Skip to content
Merged
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
51 changes: 30 additions & 21 deletions test/other/embind_tsgen_main.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
// Example TS program that consumes the emscripten-generated module to to
// illustrate how the type definitions are used and test they are workings as
// expected.
import moduleFactory from './embind_tsgen.mjs';

const module = await moduleFactory();
// The imported file will either be an ES module or a CommonJS module depending
// on the test.
import moduleFactory from './embind_tsgen.js';

// Test a few variations of passing value_objects with strings.
module.setValObj({
bar: module.Bar.valueOne,
string: "ABCD",
callback: () => {}
});
// Async IIFE is required for TSC with commonjs modules. This is not needed for
// ESM output since top level await can be used.
(async function() {

module.setValObj({
bar: module.Bar.valueOne,
string: new Int8Array([65, 66, 67, 68]),
callback: () => {}
});
const module = await moduleFactory();

const valObj = module.getValObj();
// TODO: remove the cast below when better definitions are generated for value
// objects.
const valString : string = valObj.string as string;
// Test a few variations of passing value_objects with strings.
module.setValObj({
bar: module.Bar.valueOne,
string: "ABCD",
callback: () => {}
});

// Ensure nonnull pointers do no need a cast or nullptr check to use.
const obj = module.getNonnullPointer();
obj.delete();
module.setValObj({
bar: module.Bar.valueOne,
string: new Int8Array([65, 66, 67, 68]),
callback: () => {}
});

console.log('ts ran');
const valObj = module.getValObj();
// TODO: remove the cast below when better definitions are generated for value
// objects.
const valString : string = valObj.string as string;

// Ensure nonnull pointers do no need a cast or nullptr check to use.
const obj = module.getNonnullPointer();
obj.delete();

console.log('ts ran');

})();
19 changes: 11 additions & 8 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -3385,21 +3385,24 @@ def test_jspi_add_function(self):
self.do_runf('other/test_jspi_add_function.c', 'done')

@parameterized({
'': [[]],
'with_jsgen': [['-sEMBIND_AOT']]
'commonjs': [['-sMODULARIZE'], ['--module', 'commonjs', '--moduleResolution', 'node']],
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

FYI: this roughly matches how emscripten output is used in g3.

'esm': [['-sEXPORT_ES6'], ['--module', 'NodeNext', '--moduleResolution', 'nodenext']],
'esm_with_jsgen': [['-sEXPORT_ES6', '-sEMBIND_AOT'], ['--module', 'NodeNext', '--moduleResolution', 'nodenext']]
})
def test_embind_tsgen(self, opts):
def test_embind_tsgen_end_to_end(self, opts, tsc_opts):
# Check that TypeScript generation works and that the program is runs as
# expected.
self.emcc(test_file('other/embind_tsgen.cpp'),
['-o', 'embind_tsgen.mjs', '-lembind', '--emit-tsd', 'embind_tsgen.d.ts'] + opts)
['-o', 'embind_tsgen.js', '-lembind', '--emit-tsd', 'embind_tsgen.d.ts'] + opts)

# Test that the output compiles with a TS file that uses the defintions.
shutil.copyfile(test_file('other/embind_tsgen_main.ts'), 'main.ts')
# A package file with type=module is needed to enabled ES modules in TSC and
# also run the output JS file as a module in node.
shutil.copyfile(test_file('other/embind_tsgen_package.json'), 'package.json')
cmd = shared.get_npm_cmd('tsc') + ['embind_tsgen.d.ts', 'main.ts', '--module', 'NodeNext', '--moduleResolution', 'nodenext']
if '-sEXPORT_ES6' in opts:
# A package file with type=module is needed to enabled ES modules in TSC and
# also run the output JS file as a module in node.
shutil.copyfile(test_file('other/embind_tsgen_package.json'), 'package.json')

cmd = shared.get_npm_cmd('tsc') + ['embind_tsgen.d.ts', 'main.ts', '--target', 'es2021'] + tsc_opts
shared.check_call(cmd)
actual = read_file('embind_tsgen.d.ts')
self.assertFileContents(test_file('other/embind_tsgen_module.d.ts'), actual)
Expand Down
7 changes: 5 additions & 2 deletions tools/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -2491,9 +2491,12 @@ def modularize():
src += 'export default %s;\n' % settings.EXPORT_NAME
elif not settings.MINIMAL_RUNTIME:
src += '''\
if (typeof exports === 'object' && typeof module === 'object')
if (typeof exports === 'object' && typeof module === 'object') {
module.exports = %(EXPORT_NAME)s;
else if (typeof define === 'function' && define['amd'])
// This default export looks redundant, but it allows TS to import this
// commonjs style module.
module.exports.default = %(EXPORT_NAME)s;
} else if (typeof define === 'function' && define['amd'])
define([], () => %(EXPORT_NAME)s);
''' % {'EXPORT_NAME': settings.EXPORT_NAME}

Expand Down
Loading