Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions test/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ def assertIdentical(self, values, y, msg=None,
fail_message += '\n' + msg
self.fail(fail_message)

def assertFileContents(self, filename, contents):
def assertFileContents(self, filename, contents, tofile=None):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we didn't reuse assertFileContents, we could just use the builtin filecmp module. This would be simple and maybe faster than reading both files into memory, perhaps at the cost of not being able to print actual diffs. Would that be desirable?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I prefer to have the existing logic in place for nicely displaying diffs.

I don't think there is any perfermance issues since since we don't have any huge files checked in at all. They all measured in kb.

if EMTEST_VERBOSE:
print(f'Comparing results contents of file: {filename}')

Expand All @@ -1113,7 +1113,10 @@ def assertFileContents(self, filename, contents):
expected_content = read_file(filename)
message = "Run with --rebaseline to automatically update expectations"
self.assertTextDataIdentical(expected_content, contents, message,
filename, filename + '.new')
filename, tofile or (filename + '.new'))

def assertFilesMatch(self, expected, actual):
self.assertFileContents(expected, read_file(actual), tofile=actual)

def assertContained(self, values, string, additional_info='', regex=False):
if callable(string):
Expand Down
4 changes: 2 additions & 2 deletions test/test_codesize.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,13 @@ def test_minimal_runtime_code_size(self, test_name, wasm2js, compare_js_output=F
# Note that we do not compare the full wasm output since that is
# even more fragile and can change with LLVM updates.
if compare_js_output:
js_out = test_file('codesize', test_name + '.expected.js')
expected_js = test_file('codesize', test_name + '.expected.js')
terser = shared.get_npm_cmd('terser')
# N.b. this requires node in PATH, it does not run against NODE from
# Emscripten config file. If you have this line fail, make sure 'node' is
# visible in PATH.
self.run_process(terser + ['-b', 'beautify=true', 'a.js', '-o', 'pretty.js'], env=shared.env_with_node_in_path())
self.assertFileContents(js_out, read_file('pretty.js'))
self.assertFilesMatch(expected_js, 'pretty.js')

self.check_output_sizes(*outputs)

Expand Down
2 changes: 1 addition & 1 deletion test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9767,7 +9767,7 @@ def test_esm_integration(self):
err('this is a pointer:', stringToNewUTF8('hello'));
''')
self.assertContained('Hello, world! (3)', self.run_js('runner.mjs'))
self.assertFileContents(test_file('core/test_esm_integration.expected.mjs'), read_file('hello_world.mjs'))
self.assertFilesMatch(test_file('core/test_esm_integration.expected.mjs'), 'hello_world.mjs')

@no_omit_asm_module_exports('MODULARIZE is not compatible with DECLARE_ASM_MODULE_EXPORTS=0')
@no_strict_js('EXPORT_ES6 is not compatible with STRICT_JS')
Expand Down
34 changes: 16 additions & 18 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -3040,8 +3040,7 @@ def test_js_optimizer_py(self, name, passes):
# script calls)
copy_asset(f'js_optimizer/{name}.js')
self.run_process([PYTHON, path_from_root('tools/js_optimizer.py'), name + '.js'] + passes)
actual = read_file(name + '.js.jsopt.js')
self.assertFileContents(test_file('js_optimizer', name + '-output.js'), actual)
self.assertFilesMatch(test_file('js_optimizer', name + '-output.js'), name + '.js.jsopt.js')

def test_m_mm(self):
create_file('foo.c', '#include <emscripten.h>')
Expand Down Expand Up @@ -3584,8 +3583,7 @@ def test_embind_tsgen_end_to_end(self, opts, tsc_opts):
copy_asset('other/embind_tsgen_package.json', 'package.json')

self.run_tsc(['embind_tsgen.d.ts', 'main.ts', '--target', 'es2021'] + tsc_opts)
actual = read_file('embind_tsgen.d.ts')
self.assertFileContents(test_file('other/embind_tsgen_module.d.ts'), actual)
self.assertFilesMatch(test_file('other/embind_tsgen_module.d.ts'), 'embind_tsgen.d.ts')
self.assertContained('main ran\nts ran', self.run_js('main.js'))

@is_slow_test
Expand Down Expand Up @@ -3626,7 +3624,7 @@ def test_embind_tsgen_end_to_end(self, opts, tsc_opts):
def test_embind_tsgen_ignore(self, extra_args, expected_ts_file):
create_file('fail.js', 'assert(false);')
self.emcc('other/embind_tsgen.cpp', ['-lembind', '--emit-tsd', 'embind_tsgen.d.ts'] + extra_args)
self.assertFileContents(test_file(f'other/{expected_ts_file}'), read_file('embind_tsgen.d.ts'))
self.assertFilesMatch(test_file(f'other/{expected_ts_file}'), 'embind_tsgen.d.ts')

def test_embind_tsgen_remove_relaxed_simd(self):
self.emcc('other/test_relaxed_simd.cpp', ['-mrelaxed-simd', '-msse', '-lembind', '--emit-tsd', 'embind_tsgen.d.ts'])
Expand All @@ -3636,7 +3634,7 @@ def test_embind_tsgen_worker_env(self):
# Passing -sWASM_WORKERS requires the 'worker' environment
# at link time. Verify that TS binding generation still works in this case.
self.emcc('other/embind_tsgen.cpp', ['-lembind', '--emit-tsd', 'embind_tsgen.d.ts', '-sWASM_WORKERS'])
self.assertFileContents(test_file('other/embind_tsgen.d.ts'), read_file('embind_tsgen.d.ts'))
self.assertFilesMatch(test_file('other/embind_tsgen.d.ts'), 'embind_tsgen.d.ts')

def test_embind_tsgen_dylink(self):
create_file('side.h', r'''
Expand Down Expand Up @@ -3682,15 +3680,15 @@ def test_embind_tsgen_val(self):
def test_embind_tsgen_constant_only(self):
self.run_process([EMCC, test_file('other/embind_tsgen_constant_only.cpp'),
'-lembind', '--emit-tsd', 'out.d.ts'])
self.assertFileContents(test_file('other/embind_tsgen_constant_only.d.ts'), read_file('out.d.ts'))
self.assertFilesMatch(test_file('other/embind_tsgen_constant_only.d.ts'), 'out.d.ts')

def test_embind_tsgen_bigint(self):
cmd = [EMXX, test_file('other/embind_tsgen_bigint.cpp'), '-lembind', '--emit-tsd', 'embind_tsgen_bigint.d.ts']
# Check that TypeScript generation fails when code contains bigints but their support is not enabled
self.assert_fail(cmd + ['-sWASM_BIGINT=0'], "Missing primitive type to TS type for 'long long")
# Check that TypeScript generation works when bigint support is enabled
self.run_process(cmd)
self.assertFileContents(test_file('other/embind_tsgen_bigint.d.ts'), read_file('embind_tsgen_bigint.d.ts'))
self.assertFilesMatch(test_file('other/embind_tsgen_bigint.d.ts'), 'embind_tsgen_bigint.d.ts')

@parameterized({
'': [[]],
Expand All @@ -3704,14 +3702,14 @@ def test_embind_tsgen_wasm64(self, args):
'-lembind', '--emit-tsd', 'embind_tsgen_wasm64.d.ts', '-m64'] +
args +
self.get_cflags())
self.assertFileContents(test_file('other/embind_tsgen_wasm64.d.ts'), read_file('embind_tsgen_wasm64.d.ts'))
self.assertFilesMatch(test_file('other/embind_tsgen_wasm64.d.ts'), 'embind_tsgen_wasm64.d.ts')

@requires_jspi
def test_embind_tsgen_jspi(self):
self.run_process([EMXX, test_file('other/embind_tsgen_jspi.cpp'),
'-lembind', '--emit-tsd', 'embind_tsgen_jspi.d.ts', '-sJSPI', '-sSTRICT', '--no-entry'] +
self.get_cflags())
self.assertFileContents(test_file('other/embind_tsgen_jspi.d.ts'), read_file('embind_tsgen_jspi.d.ts'))
self.assertFilesMatch(test_file('other/embind_tsgen_jspi.d.ts'), 'embind_tsgen_jspi.d.ts')

@parameterized({
'': [0],
Expand All @@ -3727,7 +3725,7 @@ def test_embind_tsgen_exceptions(self, legacy):
'-lembind', '-fwasm-exceptions', '-sASSERTIONS',
'--emit-tsd', 'embind_tsgen.d.ts', '-Wno-deprecated'] +
self.get_cflags())
self.assertFileContents(test_file('other/embind_tsgen.d.ts'), read_file('embind_tsgen.d.ts'))
self.assertFilesMatch(test_file('other/embind_tsgen.d.ts'), 'embind_tsgen.d.ts')

def test_embind_jsgen_method_pointer_stability(self):
# Test that when method pointers are allocated at different addresses that
Expand All @@ -3748,7 +3746,7 @@ def test_emit_tsd(self, args, postfix):
'-sMODULARIZE', '-sEXPORTED_RUNTIME_METHODS=UTF8ArrayToString,wasmTable',
'-o', f'test_emit_tsd{postfix}.js'] + args +
self.get_cflags())
self.assertFileContents(test_file(f'other/test_emit_tsd{postfix}.d.ts'), read_file(f'test_emit_tsd{postfix}.d.ts'))
self.assertFilesMatch(test_file(f'other/test_emit_tsd{postfix}.d.ts'), f'test_emit_tsd{postfix}.d.ts')
# Test that the output compiles with a TS file that uses the definitions.
self.run_tsc([test_file(f'other/test_tsd{postfix}.ts'), '--noEmit'])

Expand All @@ -3759,7 +3757,7 @@ def test_emit_tsd_sync_compilation(self):
'-sMODULARIZE', '-sWASM_ASYNC_COMPILATION=0',
'-o', 'test_emit_tsd_sync.js'] +
self.get_cflags())
self.assertFileContents(test_file('other/test_emit_tsd_sync.d.ts'), read_file('test_emit_tsd_sync.d.ts'))
self.assertFilesMatch(test_file('other/test_emit_tsd_sync.d.ts'), 'test_emit_tsd_sync.d.ts')
# Test that the output compiles with a TS file that uses the definitions.
self.run_tsc([test_file('other/test_tsd_sync.ts'), '--noEmit'])

Expand Down Expand Up @@ -5000,9 +4998,9 @@ def is_js_symbol_map(symbols_file):
elif wasm == 1:
self.assertFalse(is_js_symbol_map('a.out.js.symbols'), 'Primary symbols file should store Wasm mappings')
if '-O2' in opts:
self.assertFileContents(test_file('other/test_symbol_map.O2.symbols'), read_file('a.out.js.symbols'))
self.assertFilesMatch(test_file('other/test_symbol_map.O2.symbols'), 'a.out.js.symbols')
else:
self.assertFileContents(test_file('other/test_symbol_map.O3.symbols'), read_file('a.out.js.symbols'))
self.assertFilesMatch(test_file('other/test_symbol_map.O3.symbols'), 'a.out.js.symbols')
elif wasm == 2:
# special case when both JS and Wasm targets are created
minified_middle_2 = get_minified_middle('a.out.wasm.js.symbols')
Expand Down Expand Up @@ -12509,19 +12507,19 @@ def test_gen_struct_info(self):
# This test will start failing whenever the struct info changes (e.g. offset or defines
# change). However it's easy to rebaseline with --rebaseline.
self.run_process([PYTHON, path_from_root('tools/gen_struct_info.py'), '-o', 'out.json'])
self.assertFileContents(path_from_root('src/struct_info_generated.json'), read_file('out.json'))
self.assertFilesMatch(path_from_root('src/struct_info_generated.json'), 'out.json')

# Same again for wasm64
self.run_process([PYTHON, path_from_root('tools/gen_struct_info.py'), '--wasm64', '-o', 'out.json'])
self.assertFileContents(path_from_root('src/struct_info_generated_wasm64.json'), read_file('out.json'))
self.assertFilesMatch(path_from_root('src/struct_info_generated_wasm64.json'), 'out.json')

@crossplatform
def test_gen_sig_info(self):
# This tests is fragile and will need updating any time a JS library
# function is added or its signature changed. However it's easy to
# rebaseline with --rebaseline.
self.run_process([PYTHON, path_from_root('tools/maint/gen_sig_info.py'), '-o', 'out.js'])
self.assertFileContents(path_from_root('src/lib/libsigs.js'), read_file('out.js'))
self.assertFilesMatch(path_from_root('src/lib/libsigs.js'), 'out.js')

def test_gen_struct_info_env(self):
# gen_struct_info.py builds C code in a very specific and low level way. We don't want
Expand Down
Loading