Skip to content

Commit

Permalink
[tsgen] Expand TS generation test to compile and run a TS file. (emsc…
Browse files Browse the repository at this point in the history
…ripten-core#22582)

In the new TS file we can add tests for things where just checking if
the definition file compiles is not enough. This will help catch issues
like emscripten-core#22569.
  • Loading branch information
brendandahl authored Nov 20, 2024
1 parent c7f8724 commit 76ad476
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 31 deletions.
13 changes: 11 additions & 2 deletions test/other/embind_tsgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,19 @@ struct ValArr {
EMSCRIPTEN_DECLARE_VAL_TYPE(CallbackType);

struct ValObj {
Foo foo;
Bar bar;
std::string string;
CallbackType callback;
ValObj() : callback(val::undefined()) {}
};

ValObj getValObj() {
ValObj o;
return o;
}

void setValObj(ValObj v) {}

class ClassWithConstructor {
public:
ClassWithConstructor(int, const ValArr&) {}
Expand Down Expand Up @@ -190,9 +197,11 @@ EMSCRIPTEN_BINDINGS(Test) {
.element(emscripten::index<3>());

value_object<ValObj>("ValObj")
.field("foo", &ValObj::foo)
.field("string", &ValObj::string)
.field("bar", &ValObj::bar)
.field("callback", &ValObj::callback);
function("getValObj", &getValObj);
function("setValObj", &setValObj);

register_vector<int>("IntVec");

Expand Down
14 changes: 8 additions & 6 deletions test/other/embind_tsgen.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

export type ValObj = {
foo: Foo,
bar: Bar,
callback: (message: string) => void
};

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}
Expand All @@ -108,6 +102,12 @@ export interface InterfaceWrapper extends Interface {

export type ValArr = [ number, number, number ];

export type ValObj = {
string: EmbindString,
bar: Bar,
callback: (message: string) => void
};

interface EmbindModule {
Test: {
staticFunction(_0: number): number;
Expand Down Expand Up @@ -158,6 +158,8 @@ interface EmbindModule {
smart_ptr_function(_0: ClassWithSmartPtrConstructor | null): number;
smart_ptr_function_with_params(foo: ClassWithSmartPtrConstructor | null): number;
function_with_callback_param(_0: (message: string) => void): number;
getValObj(): ValObj;
setValObj(_0: ValObj): void;
string_test(_0: EmbindString): string;
wstring_test(_0: string): string;
}
Expand Down
14 changes: 8 additions & 6 deletions test/other/embind_tsgen_ignore_1.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,6 @@ export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

export type ValObj = {
foo: Foo,
bar: Bar,
callback: (message: string) => void
};

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}
Expand All @@ -117,6 +111,12 @@ export interface InterfaceWrapper extends Interface {

export type ValArr = [ number, number, number ];

export type ValObj = {
string: EmbindString,
bar: Bar,
callback: (message: string) => void
};

interface EmbindModule {
Test: {
staticFunction(_0: number): number;
Expand Down Expand Up @@ -167,6 +167,8 @@ interface EmbindModule {
smart_ptr_function(_0: ClassWithSmartPtrConstructor | null): number;
smart_ptr_function_with_params(foo: ClassWithSmartPtrConstructor | null): number;
function_with_callback_param(_0: (message: string) => void): number;
getValObj(): ValObj;
setValObj(_0: ValObj): void;
string_test(_0: EmbindString): string;
wstring_test(_0: string): string;
}
Expand Down
14 changes: 8 additions & 6 deletions test/other/embind_tsgen_ignore_2.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,6 @@ export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

export type ValObj = {
foo: Foo,
bar: Bar,
callback: (message: string) => void
};

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}
Expand All @@ -94,6 +88,12 @@ export interface InterfaceWrapper extends Interface {

export type ValArr = [ number, number, number ];

export type ValObj = {
string: EmbindString,
bar: Bar,
callback: (message: string) => void
};

interface EmbindModule {
Test: {
staticFunction(_0: number): number;
Expand Down Expand Up @@ -144,6 +144,8 @@ interface EmbindModule {
smart_ptr_function(_0: ClassWithSmartPtrConstructor | null): number;
smart_ptr_function_with_params(foo: ClassWithSmartPtrConstructor | null): number;
function_with_callback_param(_0: (message: string) => void): number;
getValObj(): ValObj;
setValObj(_0: ValObj): void;
string_test(_0: EmbindString): string;
wstring_test(_0: string): string;
}
Expand Down
14 changes: 8 additions & 6 deletions test/other/embind_tsgen_ignore_3.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

export type ValObj = {
foo: Foo,
bar: Bar,
callback: (message: string) => void
};

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}
Expand All @@ -108,6 +102,12 @@ export interface InterfaceWrapper extends Interface {

export type ValArr = [ number, number, number ];

export type ValObj = {
string: EmbindString,
bar: Bar,
callback: (message: string) => void
};

interface EmbindModule {
Test: {
staticFunction(_0: number): number;
Expand Down Expand Up @@ -158,6 +158,8 @@ interface EmbindModule {
smart_ptr_function(_0: ClassWithSmartPtrConstructor | null): number;
smart_ptr_function_with_params(foo: ClassWithSmartPtrConstructor | null): number;
function_with_callback_param(_0: (message: string) => void): number;
getValObj(): ValObj;
setValObj(_0: ValObj): void;
string_test(_0: EmbindString): string;
wstring_test(_0: string): string;
}
Expand Down
30 changes: 30 additions & 0 deletions test/other/embind_tsgen_main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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();

// Test a few variations of passing value_objects with strings.
module.setValObj({
bar: module.Bar.valueOne,
string: "ABCD",
callback: () => {}
});

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

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');
168 changes: 168 additions & 0 deletions test/other/embind_tsgen_module.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// TypeScript bindings for emscripten-generated code. Automatically generated at compile time.
declare namespace RuntimeExports {
let HEAPF32: any;
let HEAPF64: any;
let HEAP_DATA_VIEW: any;
let HEAP8: any;
let HEAPU8: any;
let HEAP16: any;
let HEAPU16: any;
let HEAP32: any;
let HEAPU32: any;
let HEAP64: any;
let HEAPU64: any;
}
interface WasmModule {
_main(_0: number, _1: number): number;
}

type EmbindString = ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string;
export interface ClassHandle {
isAliasOf(other: ClassHandle): boolean;
delete(): void;
deleteLater(): this;
isDeleted(): boolean;
clone(): this;
}
export interface Test extends ClassHandle {
x: number;
readonly y: number;
get stringProperty(): string;
set stringProperty(value: EmbindString);
functionOne(_0: number, _1: number): number;
functionTwo(_0: number, _1: number): number;
functionFour(_0: boolean): number;
functionFive(x: number, y: number): number;
constFn(): number;
longFn(_0: number): number;
functionThree(_0: EmbindString): number;
functionSix(str: EmbindString): number;
}

export interface Obj extends ClassHandle {
}

export interface BarValue<T extends number> {
value: T;
}
export type Bar = BarValue<0>|BarValue<1>|BarValue<2>;

export interface EmptyEnumValue<T extends number> {
value: T;
}
export type EmptyEnum = never/* Empty Enumerator */;

export type ValArrIx = [ Bar, Bar, Bar, Bar ];

export interface IntVec extends ClassHandle {
push_back(_0: number): void;
resize(_0: number, _1: number): void;
size(): number;
get(_0: number): number | undefined;
set(_0: number, _1: number): boolean;
}

export interface MapIntInt extends ClassHandle {
keys(): IntVec;
get(_0: number): number | undefined;
set(_0: number, _1: number): void;
size(): number;
}

export interface Foo extends ClassHandle {
process(_0: Test): void;
}

export interface ClassWithConstructor extends ClassHandle {
fn(_0: number): number;
}

export interface ClassWithTwoConstructors extends ClassHandle {
}

export interface ClassWithSmartPtrConstructor extends ClassHandle {
fn(_0: number): number;
}

export interface BaseClass extends ClassHandle {
fn(_0: number): number;
}

export interface DerivedClass extends BaseClass {
fn2(_0: number): number;
}

export interface Interface extends ClassHandle {
invoke(_0: EmbindString): void;
}

export interface InterfaceWrapper extends Interface {
notifyOnDestruction(): void;
}

export type ValArr = [ number, number, number ];

export type ValObj = {
string: EmbindString,
bar: Bar,
callback: (message: string) => void
};

interface EmbindModule {
Test: {
staticFunction(_0: number): number;
staticFunctionWithParam(x: number): number;
staticProperty: number;
get staticStringProperty(): string;
set staticStringProperty(value: EmbindString);
};
class_returning_fn(): Test;
class_unique_ptr_returning_fn(): Test;
Obj: {};
getPointer(_0: Obj | null): Obj | null;
getNonnullPointer(): Obj;
a_class_instance: Test;
an_enum: Bar;
Bar: {valueOne: BarValue<0>, valueTwo: BarValue<1>, valueThree: BarValue<2>};
EmptyEnum: {};
enum_returning_fn(): Bar;
IntVec: {
new(): IntVec;
};
MapIntInt: {
new(): MapIntInt;
};
Foo: {};
ClassWithConstructor: {
new(_0: number, _1: ValArr): ClassWithConstructor;
};
ClassWithTwoConstructors: {
new(): ClassWithTwoConstructors;
new(_0: number): ClassWithTwoConstructors;
};
ClassWithSmartPtrConstructor: {
new(_0: number, _1: ValArr): ClassWithSmartPtrConstructor;
};
BaseClass: {};
DerivedClass: {};
Interface: {
implement(_0: any): InterfaceWrapper;
extend(_0: EmbindString, _1: any): any;
};
InterfaceWrapper: {};
a_bool: boolean;
an_int: number;
optional_test(_0?: Foo): number | undefined;
global_fn(_0: number, _1: number): number;
optional_and_nonoptional_test(_0: Foo | undefined, _1: number): number | undefined;
smart_ptr_function(_0: ClassWithSmartPtrConstructor | null): number;
smart_ptr_function_with_params(foo: ClassWithSmartPtrConstructor | null): number;
function_with_callback_param(_0: (message: string) => void): number;
getValObj(): ValObj;
setValObj(_0: ValObj): void;
string_test(_0: EmbindString): string;
wstring_test(_0: string): string;
}

export type MainModule = WasmModule & typeof RuntimeExports & EmbindModule;
export default function MainModuleFactory (options?: unknown): Promise<MainModule>;
3 changes: 3 additions & 0 deletions test/other/embind_tsgen_package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
Loading

0 comments on commit 76ad476

Please sign in to comment.