diff --git a/feature_tests/js/api/OptionInputStruct.d.ts b/feature_tests/js/api/OptionInputStruct.d.ts index 04c9d834d..5e7bf96f1 100644 --- a/feature_tests/js/api/OptionInputStruct.d.ts +++ b/feature_tests/js/api/OptionInputStruct.d.ts @@ -3,9 +3,9 @@ import type { OptionEnum } from "./OptionEnum" import type { pointer, codepoint } from "./diplomat-runtime.d.ts"; type OptionInputStruct_Obj = { - a: number | null; - b: codepoint | null; - c: OptionEnum | null; + a?: number | null; + b?: codepoint | null; + c?: OptionEnum | null; }; export class OptionInputStruct { diff --git a/feature_tests/js/test/.gitignore b/feature_tests/js/test/.gitignore new file mode 100644 index 000000000..9044a0c52 --- /dev/null +++ b/feature_tests/js/test/.gitignore @@ -0,0 +1 @@ +*.mjs \ No newline at end of file diff --git a/feature_tests/js/test/attrs-ts.mjs b/feature_tests/js/test/attrs-ts.mjs deleted file mode 100644 index 8634d331c..000000000 --- a/feature_tests/js/test/attrs-ts.mjs +++ /dev/null @@ -1,10 +0,0 @@ -import test from "ava"; -import { RenamedMyIterable } from "diplomat-wasm-js-feature-tests"; -test("Verify Iterables and Iterators", t => { - let iterable = RenamedMyIterable.new_([10, 20, 30, 40, 50]); - let start = 10; - for (let i of iterable) { - t.is(i, start); - start += 10; - } -}); diff --git a/feature_tests/js/test/attrs.mjs b/feature_tests/js/test/attrs.mjs deleted file mode 100644 index d8c5bf726..000000000 --- a/feature_tests/js/test/attrs.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import test from "ava"; - -import { RenamedMyIterable } from "diplomat-wasm-js-feature-tests"; - -test("Verify Iterables and Iterators", t => { - let iterable = RenamedMyIterable.new_([10, 20, 30, 40, 50]); - - let start = 10; - for (let i of iterable) { - t.is(i, start); - start += 10; - } -}); \ No newline at end of file diff --git a/feature_tests/js/test/lifetimes-ts.mjs b/feature_tests/js/test/lifetimes-ts.mjs deleted file mode 100644 index bef12bab4..000000000 --- a/feature_tests/js/test/lifetimes-ts.mjs +++ /dev/null @@ -1,10 +0,0 @@ -import test from 'ava'; -import { Foo } from "diplomat-wasm-js-feature-tests"; -test("Foo", (t) => { - let f = Foo.new_("This is a test string."); - t.not(f.ffiValue, null); - let returning = f.asReturning(); - t.is(returning.bytes.toString(), "This is a test string."); - let b = f.bar.foo.asReturning().bytes; - t.is(b.toString(), "This is a test string."); -}); diff --git a/feature_tests/js/test/lifetimes.mjs b/feature_tests/js/test/lifetimes.mjs deleted file mode 100644 index 7e7e74d2a..000000000 --- a/feature_tests/js/test/lifetimes.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import test from 'ava'; -import { Foo } from "diplomat-wasm-js-feature-tests"; - -test("Foo", (t) => { - let f = Foo.new_("This is a test string."); - t.not(f.ffiValue, null); - - let returning = f.asReturning(); - t.is(returning.bytes.toString(), "This is a test string."); - - let b = f.bar.foo.asReturning().bytes; - t.is(b.toString(), "This is a test string."); -}); \ No newline at end of file diff --git a/feature_tests/js/test/option-ts.mjs b/feature_tests/js/test/option-ts.mjs deleted file mode 100644 index 31c874604..000000000 --- a/feature_tests/js/test/option-ts.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import test from 'ava'; -import { OptionOpaque } from "diplomat-wasm-js-feature-tests"; -test("Verify option methods", t => { - const o = OptionOpaque.new_(5); - o.assertInteger(5); - const on = OptionOpaque.newNone(); - t.assert(on === null); - const s = OptionOpaque.newStruct(); - s.a.assertInteger(101); - s.b.assertChar('餐'.codePointAt(0)); - t.is(s.c, 904); - s.d.assertInteger(926535); - const sn = OptionOpaque.newStructNones(); - t.assert(!sn.a); - t.assert(!sn.b); - t.is(sn.c, 908); - t.assert(!sn.d); -}); diff --git a/feature_tests/js/test/option-ts.mts b/feature_tests/js/test/option-ts.mts index 6f61ec93b..73c531e06 100644 --- a/feature_tests/js/test/option-ts.mts +++ b/feature_tests/js/test/option-ts.mts @@ -1,20 +1,20 @@ import test from 'ava'; -import { OptionOpaque } from "diplomat-wasm-js-feature-tests"; +import { OptionOpaque, OptionEnum, OptionInputStruct } from "diplomat-wasm-js-feature-tests"; test("Verify option methods", t => { const o = OptionOpaque.new_(5); - o!.assertInteger(5); + o.assertInteger(5); const on = OptionOpaque.newNone(); - t.assert(on === null); + t.assert(!on); const s = OptionOpaque.newStruct(); - s.a!.assertInteger(101); - s.b!.assertChar('餐'.codePointAt(0)); - t.is(s.c!, 904); - s.d!.assertInteger(926535); + s.a.assertInteger(101); + s.b.assertChar('餐'.codePointAt(0)); + t.is(s.c, 904); + s.d.assertInteger(926535); const sn = OptionOpaque.newStructNones(); t.assert(!sn.a); @@ -22,3 +22,24 @@ test("Verify option methods", t => { t.is(sn.c, 908); t.assert(!sn.d); }); + +test("DiplomatOption tests", t => { + let maybeU8 = OptionOpaque.acceptsOptionU8(null); + t.assert(maybeU8 === null); + maybeU8 = OptionOpaque.acceptsOptionU8(47); + t.is(maybeU8, 47); + + let maybeStruct = OptionOpaque.acceptsOptionInputStruct(null); + t.assert(maybeStruct === null); + maybeStruct = OptionOpaque.acceptsOptionInputStruct(new OptionInputStruct({a: 7, c: OptionEnum.Bar})); + t.is(maybeStruct.a, 7); + t.assert(maybeStruct.b === null); + t.is(maybeStruct.c.value, OptionEnum.Bar.value); + + + let struct = OptionOpaque.returnsOptionInputStruct(); + t.is(struct.a, 6); + t.assert(struct.b === null); + t.is(struct.c.value, OptionEnum.Bar.value); + +}); \ No newline at end of file diff --git a/feature_tests/js/test/option.mjs b/feature_tests/js/test/option.mjs deleted file mode 100644 index 829536add..000000000 --- a/feature_tests/js/test/option.mjs +++ /dev/null @@ -1,45 +0,0 @@ -import test from 'ava'; - -import { OptionOpaque, OptionInputStruct, OptionEnum } from "diplomat-wasm-js-feature-tests"; - -test("Verify option methods", t => { - const o = OptionOpaque.new_(5); - o.assertInteger(5); - - const on = OptionOpaque.newNone(); - t.assert(!on); - - const s = OptionOpaque.newStruct(); - - s.a.assertInteger(101); - s.b.assertChar('餐'.codePointAt(0)); - t.is(s.c, 904); - s.d.assertInteger(926535); - - const sn = OptionOpaque.newStructNones(); - t.assert(!sn.a); - t.assert(!sn.b); - t.is(sn.c, 908); - t.assert(!sn.d); -}); - -test("DiplomatOption tests", t => { - let maybeU8 = OptionOpaque.acceptsOptionU8(null); - t.assert(maybeU8 === null); - maybeU8 = OptionOpaque.acceptsOptionU8(47); - t.is(maybeU8, 47); - - let maybeStruct = OptionOpaque.acceptsOptionInputStruct(null); - t.assert(maybeStruct === null); - maybeStruct = OptionOpaque.acceptsOptionInputStruct(new OptionInputStruct({a: 7, c: OptionEnum.Bar})); - t.is(maybeStruct.a, 7); - t.assert(maybeStruct.b === null); - t.is(maybeStruct.c.value, OptionEnum.Bar.value); - - - let struct = OptionOpaque.returnsOptionInputStruct(); - t.is(struct.a, 6); - t.assert(struct.b === null); - t.is(struct.c.value, OptionEnum.Bar.value); - -}); diff --git a/feature_tests/js/test/result-ts.mjs b/feature_tests/js/test/result-ts.mjs deleted file mode 100644 index f45dd3027..000000000 --- a/feature_tests/js/test/result-ts.mjs +++ /dev/null @@ -1,24 +0,0 @@ -import test from 'ava'; -import { ErrorEnum, MyStruct, ResultOpaque } from 'diplomat-wasm-js-feature-tests'; -test('Verify result methods', t => { - const s = ResultOpaque.new_(5); - s.assertInteger(5); - const error1 = t.throws(() => ResultOpaque.newFailingFoo()); - t.is(error1.message, 'ErrorEnum: Foo'); - t.is(error1.cause, ErrorEnum.Foo); - const error2 = t.throws(() => ResultOpaque.newFailingBar()); - t.is(error2.message, 'ErrorEnum: Bar'); - t.is(error2.cause, ErrorEnum.Bar); - t.is(ResultOpaque.newFailingUnit(), null); - const error3 = t.throws(() => ResultOpaque.newFailingStruct(109)); - t.is(error3.message, 'ErrorStruct: [object Object]'); - t.is(error3.cause.i, 109); - const error4 = t.throws(() => ResultOpaque.newInErr(559)); - t.is(error4.message, 'ResultOpaque: [object Object]'); - error4.cause.assertInteger(559); - const error5 = t.throws(() => ResultOpaque.newInEnumErr(881)); - t.is(error5.message, 'ResultOpaque: [object Object]'); - error5.cause.assertInteger(881); - const error6 = t.throws(() => MyStruct.failsZstResult()); - t.is(error6.message, "MyZst"); -}); diff --git a/feature_tests/js/test/result.mjs b/feature_tests/js/test/result.mjs deleted file mode 100644 index bc5cd4c39..000000000 --- a/feature_tests/js/test/result.mjs +++ /dev/null @@ -1,33 +0,0 @@ -import test from 'ava'; - -import { ErrorEnum, ResultOpaque, MyStruct } from "diplomat-wasm-js-feature-tests" - -test("Verify result methods", t => { - const s = ResultOpaque.new_(5); - s.assertInteger(5); - - const error1 = t.throws(() => ResultOpaque.newFailingFoo()); - t.is(error1.message, "ErrorEnum: Foo"); - t.is(error1.cause, ErrorEnum.Foo); - - const error2 = t.throws(() => ResultOpaque.newFailingBar()); - t.is(error2.message, "ErrorEnum: Bar"); - t.is(error2.cause, ErrorEnum.Bar); - - t.is(ResultOpaque.newFailingUnit(), null); - - const error3 = t.throws(() => ResultOpaque.newFailingStruct(109)); - t.is(error3.message, "ErrorStruct: [object Object]") - t.is(error3.cause.i, 109); - - const error4 = t.throws(() => ResultOpaque.newInErr(559)); - t.is(error4.message, "ResultOpaque: [object Object]"); - error4.cause.assertInteger(559); - - const error5 = t.throws(() => ResultOpaque.newInEnumErr(881)); - t.is(error5.message, "ResultOpaque: [object Object]"); - error5.cause.assertInteger(881); - - const error6 = t.throws(() => MyStruct.failsZstResult()); - t.is(error6.message, "MyZst"); -}); diff --git a/feature_tests/js/test/slices-ts.mjs b/feature_tests/js/test/slices-ts.mjs deleted file mode 100644 index a675bda02..000000000 --- a/feature_tests/js/test/slices-ts.mjs +++ /dev/null @@ -1,19 +0,0 @@ -import test from "ava"; -import { MyString, Float64Vec } from "diplomat-wasm-js-feature-tests"; -test("MyString functionality", (t) => { - let str = MyString.new_("This is a test value."); - t.is(str.str, "This is a test value."); -}); -test("String List", (t) => { - let str = MyString.newFromFirst(["This", "is", "a", "test."]); - t.is(str.str, "This"); -}); -test("MyString borrow", (t) => { - let str = MyString.new_("This is a test."); - t.is(str.borrow(), "This is a test."); -}); -test("Float64Vec", (t) => { - let input = [1, 2, 3, 4, 5]; - let data = Float64Vec.newIsize(input); - t.deepEqual(data.borrow(), input); -}); diff --git a/feature_tests/js/test/slices-ts.mts b/feature_tests/js/test/slices-ts.mts index bad6434f8..4b22a8e58 100644 --- a/feature_tests/js/test/slices-ts.mts +++ b/feature_tests/js/test/slices-ts.mts @@ -1,6 +1,5 @@ import test from "ava"; import { MyString, Float64Vec } from "diplomat-wasm-js-feature-tests"; -import wasm from "../api/diplomat-wasm.mjs"; test("MyString functionality", (t) => { let str = MyString.new_("This is a test value."); diff --git a/feature_tests/js/test/slices.mjs b/feature_tests/js/test/slices.mjs deleted file mode 100644 index 4b22a8e58..000000000 --- a/feature_tests/js/test/slices.mjs +++ /dev/null @@ -1,23 +0,0 @@ -import test from "ava"; -import { MyString, Float64Vec } from "diplomat-wasm-js-feature-tests"; - -test("MyString functionality", (t) => { - let str = MyString.new_("This is a test value."); - t.is(str.str, "This is a test value."); -}); - -test("String List", (t) => { - let str = MyString.newFromFirst(["This", "is", "a", "test."]); - t.is(str.str, "This"); -}); - -test("MyString borrow", (t) => { - let str = MyString.new_("This is a test."); - t.is(str.borrow(), "This is a test."); -}); - -test("Float64Vec", (t) => { - let input = [1, 2, 3, 4, 5]; - let data = Float64Vec.newIsize(input); - t.deepEqual(data.borrow(), input); -}); diff --git a/feature_tests/js/test/struct-ts.mjs b/feature_tests/js/test/struct-ts.mjs deleted file mode 100644 index ff9a237bc..000000000 --- a/feature_tests/js/test/struct-ts.mjs +++ /dev/null @@ -1,33 +0,0 @@ -import test from 'ava'; -import { MyEnum, MyStruct, CyclicStructB } from "diplomat-wasm-js-feature-tests"; -test("Verify invariants of struct", t => { - const s = MyStruct.new_(); - t.is(s.a, 17); - t.is(s.b, true); - t.is(s.c, 209); - t.is(s.d, 1234n); - t.is(s.e, 5991); - t.is(s.f, '餐'.codePointAt(0)); - t.is(s.g, MyEnum.B); - t.is(s.intoA(), 17); -}); -test("Test struct creation", t => { - const s = new MyStruct({ - a: 17, - b: true, - c: 209, - d: 1234n, - e: 5991, - f: '餐'.codePointAt(0), - g: MyEnum.B - }); - t.is(s.intoA(), 17); -}); -test("Function Returning Nested Struct of One Field", t => { - const a = CyclicStructB.getA(); - t.is(a.cyclicOut(), "0"); -}); -test("Function De-Referencing Nested Struct of One Primitive", t => { - const a = CyclicStructB.getAOption(); - t.is(a.cyclicOut(), "0"); -}); diff --git a/feature_tests/js/test/struct-ts.mts b/feature_tests/js/test/struct-ts.mts index 2a0efc56c..878edb061 100644 --- a/feature_tests/js/test/struct-ts.mts +++ b/feature_tests/js/test/struct-ts.mts @@ -1,5 +1,5 @@ import test from 'ava'; -import { MyEnum, MyStruct, CyclicStructB } from "diplomat-wasm-js-feature-tests"; +import { MyEnum, MyStruct, CyclicStructB, ScalarPairWithPadding, BigStructWithStuff } from "diplomat-wasm-js-feature-tests"; test("Verify invariants of struct", t => { const s = MyStruct.new_(); @@ -26,7 +26,28 @@ test("Test struct creation", t => { t.is(s.intoA(), 17); }); -test("Function Returning Nested Struct of One Field", t => { +test("Test struct layout: scalar pair layout", t => { + const s = new ScalarPairWithPadding({ + first: 122, + second: 414 + }); + s.assertValue(); + t.is(true, true); // Ava doesn't like tests without assertions +}); + +test("Test struct layout: complex struct with multiple padding types and contained scalar pair", t => { + const s = new BigStructWithStuff({ + first: 101, + second: 505, + third: 9345, + fourth: new ScalarPairWithPadding({first: 122, second: 414}), + fifth: 99 + }); + s.assertValue(853); + t.is(true, true); // Ava doesn't like tests without assertions +}); + +test("Function Returning Nested Struct of One Primitive", t => { const a = CyclicStructB.getA(); t.is(a.cyclicOut(), "0"); }); diff --git a/feature_tests/js/test/struct.mjs b/feature_tests/js/test/struct.mjs deleted file mode 100644 index 31041f43f..000000000 --- a/feature_tests/js/test/struct.mjs +++ /dev/null @@ -1,58 +0,0 @@ -import test from 'ava'; -import { MyEnum, MyStruct, ScalarPairWithPadding, BigStructWithStuff, CyclicStructB } from "diplomat-wasm-js-feature-tests"; - -test("Verify invariants of struct", t => { - const s = MyStruct.new_("hello"); - t.is(s.a, 17); - t.is(s.b, true); - t.is(s.c, 209); - t.is(s.d, 1234n); - t.is(s.e, 5991); - t.is(s.f, '餐'.codePointAt(0)); - t.is(s.g, MyEnum.B); - t.is(s.intoA(), 17); -}); - -test("Test struct creation", t => { - const s = new MyStruct({ - a: 17, - b: true, - c: 209, - d: 1234n, - e: 5991, - f: '餐'.codePointAt(0), - g: MyEnum.B - }); - t.is(s.intoA(), 17); -}); - -test("Test struct layout: scalar pair layout", t => { - const s = new ScalarPairWithPadding({ - first: 122, - second: 414 - }); - s.assertValue(); - t.is(true, true); // Ava doesn't like tests without assertions -}); - -test("Test struct layout: complex struct with multiple padding types and contained scalar pair", t => { - const s = new BigStructWithStuff({ - first: 101, - second: 505, - third: 9345, - fourth: new ScalarPairWithPadding({first: 122, second: 414}), - fifth: 99 - }); - s.assertValue(853); - t.is(true, true); // Ava doesn't like tests without assertions -}); - -test("Function Returning Nested Struct of One Primitive", t => { - const a = CyclicStructB.getA(); - t.is(a.cyclicOut(), "0"); -}); - -test("Function De-Referencing Nested Struct of One Primitive", t => { - const a = CyclicStructB.getAOption(); - t.is(a.cyclicOut(), "0"); -}); \ No newline at end of file diff --git a/tool/templates/js/struct.js.jinja b/tool/templates/js/struct.js.jinja index b79a77af7..7bf313d53 100644 --- a/tool/templates/js/struct.js.jinja +++ b/tool/templates/js/struct.js.jinja @@ -6,7 +6,7 @@ {%- if typescript && !is_out -%} type {{type_name}}_Obj = { {%- for field in fields %} - {{field.field_name}}: {{field.js_type_name}}; + {{field.field_name}} {%- if let Type::DiplomatOption(o) = field.field_type %}?{% endif %}: {{field.js_type_name}}; {%- endfor %} };