diff options
Diffstat (limited to 'tests/test_browser.py')
-rw-r--r-- | tests/test_browser.py | 519 |
1 files changed, 318 insertions, 201 deletions
diff --git a/tests/test_browser.py b/tests/test_browser.py index 3b9d6ebb..3bceeda8 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -1,5 +1,5 @@ import BaseHTTPServer, multiprocessing, os, shutil, subprocess, unittest, zlib, webbrowser, time, shlex -from runner import BrowserCore, path_from_root +from runner import BrowserCore, path_from_root, nonfastcomp from tools.shared import * # User can specify an environment variable EMSCRIPTEN_BROWSER to force the browser test suite to @@ -120,8 +120,6 @@ If manually bisecting: ''' def test_emscripten_log(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('fastcomp uses asm, where call stacks are sometimes less clear') - src = os.path.join(self.get_dir(), 'src.cpp') open(src, 'w').write(self.with_report_result(open(path_from_root('tests', 'emscripten_log', 'emscripten_log.cpp')).read())) @@ -143,187 +141,193 @@ If manually bisecting: os.chdir(cwd) def test_split(self): - # test HTML generation. - self.reftest(path_from_root('tests', 'htmltest.png')) - output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '--split', '100', '--pre-js', 'reftest.js']).communicate() - assert os.path.exists(os.path.join(self.get_dir(), 'something.js')), 'must be main js file' - assert os.path.exists(os.path.join(self.get_dir(), 'something_functions.js')), 'must be functions js file' - assert os.path.exists(os.path.join(self.get_dir(), 'something.include.html')), 'must be js include file' - - open(os.path.join(self.get_dir(), 'something.html'), 'w').write(''' - - <!doctype html> - <html lang="en-us"> - <head> - <meta charset="utf-8"> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - <title>Emscripten-Generated Code</title> - <style> - .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } - canvas.emscripten { border: 1px solid black; } - textarea.emscripten { font-family: monospace; width: 80%; } - div.emscripten { text-align: center; } - </style> - </head> - <body> - <hr/> - <div class="emscripten" id="status">Downloading...</div> - <div class="emscripten"> - <progress value="0" max="100" id="progress" hidden=1></progress> - </div> - <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> - <hr/> - <div class="emscripten"><input type="button" value="fullscreen" onclick="Module.requestFullScreen()"></div> - <hr/> - <textarea class="emscripten" id="output" rows="8"></textarea> - <hr> - <script type='text/javascript'> - // connect to canvas - var Module = { - preRun: [], - postRun: [], - print: (function() { - var element = document.getElementById('output'); - element.value = ''; // clear browser cache - return function(text) { - // These replacements are necessary if you render to raw HTML - //text = text.replace(/&/g, "&"); - //text = text.replace(/</g, "<"); - //text = text.replace(/>/g, ">"); - //text = text.replace('\\n', '<br>', 'g'); - element.value += text + "\\n"; - element.scrollTop = element.scrollHeight; // focus on bottom - }; - })(), - printErr: function(text) { - if (0) { // XXX disabled for safety typeof dump == 'function') { - dump(text + '\\n'); // fast, straight to the real console - } else { - console.log(text); - } - }, - canvas: document.getElementById('canvas'), - setStatus: function(text) { - if (Module.setStatus.interval) clearInterval(Module.setStatus.interval); - var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); - var statusElement = document.getElementById('status'); - var progressElement = document.getElementById('progress'); - if (m) { - text = m[1]; - progressElement.value = parseInt(m[2])*100; - progressElement.max = parseInt(m[4])*100; - progressElement.hidden = false; - } else { - progressElement.value = null; - progressElement.max = null; - progressElement.hidden = true; + def nfc(): + # test HTML generation. + self.reftest(path_from_root('tests', 'htmltest.png')) + output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '--split', '100', '--pre-js', 'reftest.js']).communicate() + assert os.path.exists(os.path.join(self.get_dir(), 'something.js')), 'must be main js file' + assert os.path.exists(os.path.join(self.get_dir(), 'something_functions.js')), 'must be functions js file' + assert os.path.exists(os.path.join(self.get_dir(), 'something.include.html')), 'must be js include file' + + open(os.path.join(self.get_dir(), 'something.html'), 'w').write(''' + + <!doctype html> + <html lang="en-us"> + <head> + <meta charset="utf-8"> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <title>Emscripten-Generated Code</title> + <style> + .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } + canvas.emscripten { border: 1px solid black; } + textarea.emscripten { font-family: monospace; width: 80%; } + div.emscripten { text-align: center; } + </style> + </head> + <body> + <hr/> + <div class="emscripten" id="status">Downloading...</div> + <div class="emscripten"> + <progress value="0" max="100" id="progress" hidden=1></progress> + </div> + <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> + <hr/> + <div class="emscripten"><input type="button" value="fullscreen" onclick="Module.requestFullScreen()"></div> + <hr/> + <textarea class="emscripten" id="output" rows="8"></textarea> + <hr> + <script type='text/javascript'> + // connect to canvas + var Module = { + preRun: [], + postRun: [], + print: (function() { + var element = document.getElementById('output'); + element.value = ''; // clear browser cache + return function(text) { + // These replacements are necessary if you render to raw HTML + //text = text.replace(/&/g, "&"); + //text = text.replace(/</g, "<"); + //text = text.replace(/>/g, ">"); + //text = text.replace('\\n', '<br>', 'g'); + element.value += text + "\\n"; + element.scrollTop = element.scrollHeight; // focus on bottom + }; + })(), + printErr: function(text) { + if (0) { // XXX disabled for safety typeof dump == 'function') { + dump(text + '\\n'); // fast, straight to the real console + } else { + console.log(text); + } + }, + canvas: document.getElementById('canvas'), + setStatus: function(text) { + if (Module.setStatus.interval) clearInterval(Module.setStatus.interval); + var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); + var statusElement = document.getElementById('status'); + var progressElement = document.getElementById('progress'); + if (m) { + text = m[1]; + progressElement.value = parseInt(m[2])*100; + progressElement.max = parseInt(m[4])*100; + progressElement.hidden = false; + } else { + progressElement.value = null; + progressElement.max = null; + progressElement.hidden = true; + } + statusElement.innerHTML = text; + }, + totalDependencies: 0, + monitorRunDependencies: function(left) { + this.totalDependencies = Math.max(this.totalDependencies, left); + Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); } - statusElement.innerHTML = text; - }, - totalDependencies: 0, - monitorRunDependencies: function(left) { - this.totalDependencies = Math.max(this.totalDependencies, left); - Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); - } - }; - Module.setStatus('Downloading...'); - </script>''' + open(os.path.join(self.get_dir(), 'something.include.html')).read() + ''' - </body> - </html> - ''') + }; + Module.setStatus('Downloading...'); + </script>''' + open(os.path.join(self.get_dir(), 'something.include.html')).read() + ''' + </body> + </html> + ''') + + self.run_browser('something.html', 'You should see "hello, world!" and a colored cube.', '/report_result?0') - self.run_browser('something.html', 'You should see "hello, world!" and a colored cube.', '/report_result?0') + nonfastcomp(nfc) def test_split_in_source_filenames(self): - self.reftest(path_from_root('tests', 'htmltest.png')) - output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '-g', '--split', '100', '--pre-js', 'reftest.js']).communicate() - assert os.path.exists(os.path.join(self.get_dir(), 'something.js')), 'must be main js file' - assert os.path.exists(os.path.join(self.get_dir(), 'something', 'hello_world_sdl.cpp.js')), 'must be functions js file' - assert os.path.exists(os.path.join(self.get_dir(), 'something.include.html')), 'must be js include file' - - open(os.path.join(self.get_dir(), 'something.html'), 'w').write(''' - - <!doctype html> - <html lang="en-us"> - <head> - <meta charset="utf-8"> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - <title>Emscripten-Generated Code</title> - <style> - .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } - canvas.emscripten { border: 1px solid black; } - textarea.emscripten { font-family: monospace; width: 80%; } - div.emscripten { text-align: center; } - </style> - </head> - <body> - <hr/> - <div class="emscripten" id="status">Downloading...</div> - <div class="emscripten"> - <progress value="0" max="100" id="progress" hidden=1></progress> - </div> - <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> - <hr/> - <div class="emscripten"><input type="button" value="fullscreen" onclick="Module.requestFullScreen()"></div> - <hr/> - <textarea class="emscripten" id="output" rows="8"></textarea> - <hr> - <script type='text/javascript'> - // connect to canvas - var Module = { - preRun: [], - postRun: [], - print: (function() { - var element = document.getElementById('output'); - element.value = ''; // clear browser cache - return function(text) { - // These replacements are necessary if you render to raw HTML - //text = text.replace(/&/g, "&"); - //text = text.replace(/</g, "<"); - //text = text.replace(/>/g, ">"); - //text = text.replace('\\n', '<br>', 'g'); - element.value += text + "\\n"; - element.scrollTop = element.scrollHeight; // focus on bottom - }; - })(), - printErr: function(text) { - if (0) { // XXX disabled for safety typeof dump == 'function') { - dump(text + '\\n'); // fast, straight to the real console - } else { - console.log(text); - } - }, - canvas: document.getElementById('canvas'), - setStatus: function(text) { - if (Module.setStatus.interval) clearInterval(Module.setStatus.interval); - var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); - var statusElement = document.getElementById('status'); - var progressElement = document.getElementById('progress'); - if (m) { - text = m[1]; - progressElement.value = parseInt(m[2])*100; - progressElement.max = parseInt(m[4])*100; - progressElement.hidden = false; - } else { - progressElement.value = null; - progressElement.max = null; - progressElement.hidden = true; + def nfc(): + self.reftest(path_from_root('tests', 'htmltest.png')) + output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_sdl.cpp'), '-o', 'something.js', '-g', '--split', '100', '--pre-js', 'reftest.js']).communicate() + assert os.path.exists(os.path.join(self.get_dir(), 'something.js')), 'must be main js file' + assert os.path.exists(os.path.join(self.get_dir(), 'something', 'hello_world_sdl.cpp.js')), 'must be functions js file' + assert os.path.exists(os.path.join(self.get_dir(), 'something.include.html')), 'must be js include file' + + open(os.path.join(self.get_dir(), 'something.html'), 'w').write(''' + + <!doctype html> + <html lang="en-us"> + <head> + <meta charset="utf-8"> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <title>Emscripten-Generated Code</title> + <style> + .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; } + canvas.emscripten { border: 1px solid black; } + textarea.emscripten { font-family: monospace; width: 80%; } + div.emscripten { text-align: center; } + </style> + </head> + <body> + <hr/> + <div class="emscripten" id="status">Downloading...</div> + <div class="emscripten"> + <progress value="0" max="100" id="progress" hidden=1></progress> + </div> + <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> + <hr/> + <div class="emscripten"><input type="button" value="fullscreen" onclick="Module.requestFullScreen()"></div> + <hr/> + <textarea class="emscripten" id="output" rows="8"></textarea> + <hr> + <script type='text/javascript'> + // connect to canvas + var Module = { + preRun: [], + postRun: [], + print: (function() { + var element = document.getElementById('output'); + element.value = ''; // clear browser cache + return function(text) { + // These replacements are necessary if you render to raw HTML + //text = text.replace(/&/g, "&"); + //text = text.replace(/</g, "<"); + //text = text.replace(/>/g, ">"); + //text = text.replace('\\n', '<br>', 'g'); + element.value += text + "\\n"; + element.scrollTop = element.scrollHeight; // focus on bottom + }; + })(), + printErr: function(text) { + if (0) { // XXX disabled for safety typeof dump == 'function') { + dump(text + '\\n'); // fast, straight to the real console + } else { + console.log(text); + } + }, + canvas: document.getElementById('canvas'), + setStatus: function(text) { + if (Module.setStatus.interval) clearInterval(Module.setStatus.interval); + var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); + var statusElement = document.getElementById('status'); + var progressElement = document.getElementById('progress'); + if (m) { + text = m[1]; + progressElement.value = parseInt(m[2])*100; + progressElement.max = parseInt(m[4])*100; + progressElement.hidden = false; + } else { + progressElement.value = null; + progressElement.max = null; + progressElement.hidden = true; + } + statusElement.innerHTML = text; + }, + totalDependencies: 0, + monitorRunDependencies: function(left) { + this.totalDependencies = Math.max(this.totalDependencies, left); + Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); } - statusElement.innerHTML = text; - }, - totalDependencies: 0, - monitorRunDependencies: function(left) { - this.totalDependencies = Math.max(this.totalDependencies, left); - Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); - } - }; - Module.setStatus('Downloading...'); - </script>''' + open(os.path.join(self.get_dir(), 'something.include.html')).read() + ''' - </body> - </html> - ''') + }; + Module.setStatus('Downloading...'); + </script>''' + open(os.path.join(self.get_dir(), 'something.include.html')).read() + ''' + </body> + </html> + ''') - self.run_browser('something.html', 'You should see "hello, world!" and a colored cube.', '/report_result?0') + self.run_browser('something.html', 'You should see "hello, world!" and a colored cube.', '/report_result?0') + + nonfastcomp(nfc) def test_compression(self): open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(self.with_report_result(r''' @@ -580,6 +584,45 @@ If manually bisecting: shutil.rmtree(os.path.join(self.get_dir(), 'subdirr')) self.run_browser('page.html', 'You should see two cool numbers', '/report_result?1') + def test_custom_file_package_url(self): + # a few files inside a directory + self.clear() + os.makedirs(os.path.join(self.get_dir(), 'subdirr')); + os.makedirs(os.path.join(self.get_dir(), 'cdn')); + open(os.path.join(self.get_dir(), 'subdirr', 'data1.txt'), 'w').write('''1214141516171819''') + # change the file package base dir to look in a "cdn". note that normally you would add this in your own custom html file etc., and not by + # modifying the existing shell in this manner + open(self.in_dir('shell.html'), 'w').write(open(path_from_root('src', 'shell.html')).read().replace('var Module = {', 'var Module = { filePackagePrefixURL: "cdn/", ')) + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(self.with_report_result(r''' + #include <stdio.h> + #include <string.h> + #include <emscripten.h> + int main() { + char buf[17]; + + FILE *f = fopen("subdirr/data1.txt", "r"); + fread(buf, 1, 16, f); + buf[16] = 0; + fclose(f); + printf("|%s|\n", buf); + int result = !strcmp("1214141516171819", buf); + + REPORT_RESULT(); + return 0; + } + ''')) + + def test(): + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '--shell-file', 'shell.html', '--preload-file', 'subdirr/data1.txt', '-o', 'test.html']).communicate() + shutil.move('test.data', os.path.join('cdn', 'test.data')) + self.run_browser('test.html', '', '/report_result?1') + + test() + + # TODO: CORS, test using a full url for filePackagePrefixURL + #open(self.in_dir('shell.html'), 'w').write(open(path_from_root('src', 'shell.html')).read().replace('var Module = {', 'var Module = { filePackagePrefixURL: "http:/localhost:8888/cdn/", ')) + #test() + def test_compressed_file(self): open(os.path.join(self.get_dir(), 'datafile.txt'), 'w').write('compress this please' + (2000*'.')) open(os.path.join(self.get_dir(), 'datafile2.txt'), 'w').write('moar' + (100*'!')) @@ -617,6 +660,9 @@ If manually bisecting: shutil.move(os.path.join(self.get_dir(), 'datafile.txt'), 'datafile.txt.renamedsoitcannotbefound'); self.run_browser('page.html', '', '/report_result?1') + def test_sdl_swsurface(self): + self.btest('sdl_swsurface.c', expected='1') + def test_sdl_image(self): # load an image file, get pixel data. Also O2 coverage for --preload-file, and memory-init shutil.copyfile(path_from_root('tests', 'screenshot.jpg'), os.path.join(self.get_dir(), 'screenshot.jpg')) @@ -682,7 +728,13 @@ If manually bisecting: self.btest('sdl_stb_image_data.c', reference='screenshot.jpg', args=['-s', 'STB_IMAGE=1', '--preload-file', 'screenshot.not']) def test_sdl_canvas(self): + self.clear() self.btest('sdl_canvas.c', expected='1', args=['-s', 'LEGACY_GL_EMULATION=1']) + # some extra coverage + self.clear() + self.btest('sdl_canvas.c', expected='1', args=['-s', 'LEGACY_GL_EMULATION=1', '-s', '-O0', '-s', 'SAFE_HEAP=1']) + self.clear() + self.btest('sdl_canvas.c', expected='1', args=['-s', 'LEGACY_GL_EMULATION=1', '-s', '-O2', '-s', 'SAFE_HEAP=1']) def test_sdl_canvas_proxy(self): def post(): @@ -695,8 +747,11 @@ function assert(x, y) { if (!x) throw 'assertion failed ' + y } var windowClose = window.close; window.close = function() { - doReftest(); - setTimeout(windowClose, 1000); + // wait for rafs to arrive and the screen to update before reftesting + setTimeout(function() { + doReftest(); + setTimeout(windowClose, 1000); + }, 1000); }; </script> </body>''' % open('reftest.js').read()) @@ -707,7 +762,7 @@ window.close = function() { self.btest('sdl_canvas_proxy.c', reference='sdl_canvas_proxy.png', args=['--proxy-to-worker', '--preload-file', 'data.txt'], manual_reference=True, post_build=post) def test_sdl_canvas_alpha(self): - self.btest('sdl_canvas_alpha.c', reference='sdl_canvas_alpha.png', reference_slack=1) + self.btest('sdl_canvas_alpha.c', reference='sdl_canvas_alpha.png', reference_slack=9) def test_sdl_key(self): open(os.path.join(self.get_dir(), 'pre.js'), 'w').write(''' @@ -737,7 +792,7 @@ window.close = function() { ''') open(os.path.join(self.get_dir(), 'sdl_key.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_key.c')).read())) - Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_key.c'), '-o', 'page.html', '--pre-js', 'pre.js', '-s', '''EXPORTED_FUNCTIONS=['_main', '_one']''']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_key.c'), '-o', 'page.html', '--pre-js', 'pre.js', '-s', '''EXPORTED_FUNCTIONS=['_main', '_one']''', '-s', 'NO_EXIT_RUNTIME=1']).communicate() self.run_browser('page.html', '', '/report_result?223092870') def test_sdl_key_proxy(self): @@ -784,7 +839,7 @@ keydown(100);keyup(100); // trigger the end </body>''') open('test.html', 'w').write(html) - self.btest('sdl_key_proxy.c', '223092870', args=['--proxy-to-worker', '--pre-js', 'pre.js', '-s', '''EXPORTED_FUNCTIONS=['_main', '_one']'''], manual_reference=True, post_build=post) + self.btest('sdl_key_proxy.c', '223092870', args=['--proxy-to-worker', '--pre-js', 'pre.js', '-s', '''EXPORTED_FUNCTIONS=['_main', '_one']''', '-s', 'NO_EXIT_RUNTIME=1'], manual_reference=True, post_build=post) def test_sdl_text(self): open(os.path.join(self.get_dir(), 'pre.js'), 'w').write(''' @@ -1110,8 +1165,6 @@ keydown(100);keyup(100); // trigger the end self.run_browser('page.html', '', '/report_result?1') def test_sdl_audio_beeps(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo c++ exceptions in fastcomp') - open(os.path.join(self.get_dir(), 'sdl_audio_beep.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio_beep.cpp')).read())) # use closure to check for a possible bug with closure minifying away newer Audio() attributes @@ -1410,14 +1463,23 @@ keydown(100);keyup(100); // trigger the end self.btest('emscripten_api_browser.cpp', '1', args=['-s', '''EXPORTED_FUNCTIONS=['_main', '_third']''']) def test_emscripten_api2(self): - open('script1.js', 'w').write(''' - Module._set(456); - ''') + def setup(): + open('script1.js', 'w').write(''' + Module._set(456); + ''') + open('file1.txt', 'w').write('first'); + open('file2.txt', 'w').write('second'); - open('file1.txt', 'w').write('first'); - open('file2.txt', 'w').write('second'); + setup() Popen([PYTHON, FILE_PACKAGER, 'test.data', '--preload', 'file1.txt', 'file2.txt'], stdout=open('script2.js', 'w')).communicate() + self.btest('emscripten_api_browser2.cpp', '1', args=['-s', '''EXPORTED_FUNCTIONS=['_main', '_set']''']) + # check using file packager to another dir + self.clear() + setup() + os.mkdir('sub') + Popen([PYTHON, FILE_PACKAGER, 'sub/test.data', '--preload', 'file1.txt', 'file2.txt'], stdout=open('script2.js', 'w')).communicate() + shutil.copyfile(os.path.join('sub', 'test.data'), 'test.data') self.btest('emscripten_api_browser2.cpp', '1', args=['-s', '''EXPORTED_FUNCTIONS=['_main', '_set']''']) def test_emscripten_api_infloop(self): @@ -1433,11 +1495,6 @@ keydown(100);keyup(100); // trigger the end def test_sdl_resize(self): self.btest('sdl_resize.c', '1') - def test_gc(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('flaky in fastcomp and also non-fastcomp -O1, timing issues') - - self.btest('browser_gc.cpp', '1') - def test_glshaderinfo(self): self.btest('glshaderinfo.cpp', '1') @@ -1481,7 +1538,7 @@ keydown(100);keyup(100); // trigger the end self.btest('gles2_conformance.cpp', args=['-s', 'GL_ASSERTIONS=1'], expected=['1']) def test_matrix_identity(self): - self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'], args=['-s', 'LEGACY_GL_EMULATION=1']) + self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840', '1588195328'], args=['-s', 'LEGACY_GL_EMULATION=1']) def test_cubegeom_pre(self): self.btest('cubegeom_pre.c', reference='cubegeom_pre.png', args=['-s', 'LEGACY_GL_EMULATION=1']) @@ -1495,6 +1552,21 @@ keydown(100);keyup(100); // trigger the end def test_cubegeom(self): self.btest('cubegeom.c', reference='cubegeom.png', args=['-O2', '-g', '-s', 'LEGACY_GL_EMULATION=1']) + def test_cubegeom_proc(self): + open('side.c', 'w').write(r''' + +extern void* SDL_GL_GetProcAddress(const char *); + +void *glBindBuffer = 0; // same name as the gl function, to check that the collision does not break us + +void *getBindBuffer() { + if (!glBindBuffer) glBindBuffer = SDL_GL_GetProcAddress("glBindBuffer"); + return glBindBuffer; +} +''') + for opts in [0, 1]: + self.btest('cubegeom_proc.c', reference='cubegeom.png', args=['-O' + str(opts), 'side.c', '-s', 'LEGACY_GL_EMULATION=1']) + def test_cubegeom_glew(self): self.btest('cubegeom_glew.c', reference='cubegeom.png', args=['-O2', '--closure', '1', '-s', 'LEGACY_GL_EMULATION=1']) @@ -1543,6 +1615,9 @@ keydown(100);keyup(100); // trigger the end def test_cube_explosion(self): self.btest('cube_explosion.c', reference='cube_explosion.png', args=['-s', 'LEGACY_GL_EMULATION=1']) + def test_glgettexenv(self): + self.btest('glgettexenv.c', args=['-s', 'LEGACY_GL_EMULATION=1'], expected=['1']) + def test_sdl_canvas_blank(self): self.btest('sdl_canvas_blank.c', reference='sdl_canvas_blank.png') @@ -1599,6 +1674,10 @@ keydown(100);keyup(100); // trigger the end shutil.copyfile(path_from_root('tests', 'screenshot.dds'), os.path.join(self.get_dir(), 'screenshot.dds')) self.btest('s3tc.c', reference='s3tc.png', args=['--preload-file', 'screenshot.dds', '-s', 'LEGACY_GL_EMULATION=1']) + def test_s3tc_ffp_only(self): + shutil.copyfile(path_from_root('tests', 'screenshot.dds'), os.path.join(self.get_dir(), 'screenshot.dds')) + self.btest('s3tc.c', reference='s3tc.png', args=['--preload-file', 'screenshot.dds', '-s', 'LEGACY_GL_EMULATION=1', '-s', 'GL_FFP_ONLY=1']) + def test_s3tc_crunch(self): shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds') shutil.copyfile(path_from_root('tests', 'bloom.dds'), 'bloom.dds') @@ -1622,7 +1701,7 @@ keydown(100);keyup(100); // trigger the end self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'asset_a.js', '--pre-js', 'asset_b.js', '-s', 'LEGACY_GL_EMULATION=1']) def test_aniso(self): - if SPIDERMONKEY_ENGINE in JS_ENGINES and os.environ.get('EMCC_FAST_COMPILER') != '1': + if SPIDERMONKEY_ENGINE in JS_ENGINES: # asm.js-ification check Popen([PYTHON, EMCC, path_from_root('tests', 'aniso.c'), '-O2', '-g2', '-s', 'LEGACY_GL_EMULATION=1']).communicate() Settings.ASM_JS = 1 @@ -1686,10 +1765,10 @@ keydown(100);keyup(100); // trigger the end self.btest('http.cpp', expected='0', args=['-I' + path_from_root('tests')]) def test_module(self): - if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp') - - Popen([PYTHON, EMCC, path_from_root('tests', 'browser_module.cpp'), '-o', 'module.js', '-O2', '-s', 'SIDE_MODULE=1', '-s', 'DLOPEN_SUPPORT=1', '-s', 'EXPORTED_FUNCTIONS=["_one", "_two"]']).communicate() - self.btest('browser_main.cpp', args=['-O2', '-s', 'MAIN_MODULE=1', '-s', 'DLOPEN_SUPPORT=1'], expected='8') + def nfc(): + Popen([PYTHON, EMCC, path_from_root('tests', 'browser_module.cpp'), '-o', 'module.js', '-O2', '-s', 'SIDE_MODULE=1', '-s', 'DLOPEN_SUPPORT=1', '-s', 'EXPORTED_FUNCTIONS=["_one", "_two"]']).communicate() + self.btest('browser_main.cpp', args=['-O2', '-s', 'MAIN_MODULE=1', '-s', 'DLOPEN_SUPPORT=1'], expected='8') + nonfastcomp(nfc) def test_mmap_file(self): open(self.in_dir('data.dat'), 'w').write('data from the file ' + ('.' * 9000)) @@ -1768,3 +1847,41 @@ Module["preRun"].push(function () { self.btest('doublestart.c', args=['--pre-js', 'pre.js', '-o', 'test.html'], expected='1') + def test_html5(self): + self.btest(path_from_root('tests', 'test_html5.c'), expected='0') + + def test_html5_fullscreen(self): + self.btest(path_from_root('tests', 'test_html5_fullscreen.c'), expected='0') + + def test_codemods(self): + for opt_level in [0, 2]: + print 'opt level', opt_level + opts = '-O' + str(opt_level) + # sanity checks, building with and without precise float semantics generates different results + self.btest(path_from_root('tests', 'codemods.cpp'), expected='2', args=[opts]) + self.btest(path_from_root('tests', 'codemods.cpp'), expected='1', args=[opts, '-s', 'PRECISE_F32=1']) + self.btest(path_from_root('tests', 'codemods.cpp'), expected='1', args=[opts, '-s', 'PRECISE_F32=2']) # empty polyfill, but browser has support, so semantics are like float + + # now use a shell to remove the browser's fround support + open(self.in_dir('shell.html'), 'w').write(open(path_from_root('src', 'shell.html')).read().replace('var Module = {', ''' + Math.fround = null; + var Module = { + ''')) + self.btest(path_from_root('tests', 'codemods.cpp'), expected='2', args=[opts, '--shell-file', 'shell.html']) + self.btest(path_from_root('tests', 'codemods.cpp'), expected='1', args=[opts, '--shell-file', 'shell.html', '-s', 'PRECISE_F32=1']) + self.btest(path_from_root('tests', 'codemods.cpp'), expected='2', args=[opts, '--shell-file', 'shell.html', '-s', 'PRECISE_F32=2']) # empty polyfill, no browser support, so semantics are like double + + # finally, remove fround, patch up fround as the code executes (after polyfilling etc.), to verify that we got rid of it entirely on the client side + fixer = 'python fix.py' + open('fix.py', 'w').write(r''' +import sys +filename = sys.argv[1] +js = open(filename).read() +replaced = js.replace("var Math_fround = Math.fround;", "var Math_fround = Math.fround = function(x) { return 0; }") +assert js != replaced +open(filename, 'w').write(replaced) + ''') + self.btest(path_from_root('tests', 'codemods.cpp'), expected='2', args=[opts, '--shell-file', 'shell.html', '--js-transform', fixer]) # no fround anyhow + self.btest(path_from_root('tests', 'codemods.cpp'), expected='121378', args=[opts, '--shell-file', 'shell.html', '--js-transform', fixer, '-s', 'PRECISE_F32=1']) # proper polyfill was enstated, then it was replaced by the fix so 0 is returned all the time, hence a different result here + self.btest(path_from_root('tests', 'codemods.cpp'), expected='2', args=[opts, '--shell-file', 'shell.html', '--js-transform', fixer, '-s', 'PRECISE_F32=2']) # we should remove the calls to the polyfill ENTIRELY here, on the clientside, so we should NOT see any calls to fround here, and result should be like double + |