Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f73d217
wip delegates parsing
ArcadeMode Jan 29, 2026
2f9bdd9
action/func 0-3 with primitive types can render CS
ArcadeMode Jan 30, 2026
82689b4
simple delegate working + ts+e2e test
ArcadeMode Jan 30, 2026
d6b1978
neater delegate ts signature names and spacing
ArcadeMode Jan 30, 2026
640afd7
extend e2e suites with primities in action and func
ArcadeMode Jan 30, 2026
37ff63a
wip delegates with TSExport parameters
ArcadeMode Jan 30, 2026
37e4df5
dynamic ts symbol name templates
ArcadeMode Jan 30, 2026
5bf00cd
refactor ts symbolname templates to refer to interop type infos
ArcadeMode Jan 31, 2026
52301e0
update builder to provide inner type infos to ts symbol templates
ArcadeMode Jan 31, 2026
1836a11
separate template info from rendering
ArcadeMode Jan 31, 2026
8d31849
wip outline impl using new symbol renderer
ArcadeMode Jan 31, 2026
cc53161
renderer separation completed, wip delegates with proxy types and non…
ArcadeMode Jan 31, 2026
68a2187
render delegate parameter proxy wrapping
ArcadeMode Jan 31, 2026
1893352
add partially succeeding tests for delegate return types
ArcadeMode Jan 31, 2026
afc9087
delegate wrapper for upcasting to interop types on CS side
ArcadeMode Jan 31, 2026
67d9943
delegate return types
ArcadeMode Jan 31, 2026
63db7fa
render delegates with options for symboltype for param & return
ArcadeMode Feb 1, 2026
42ac7ce
initializer e2e behavior for properties
ArcadeMode Feb 1, 2026
a2372a1
fix delegates in assembly exports + covering tests
ArcadeMode Feb 1, 2026
563587c
render CS type conversion for delegate return types
ArcadeMode Feb 1, 2026
3a1c9f2
fix namespaces in e2e
ArcadeMode Feb 1, 2026
5fbff77
move dupe return type conversion rendering to class, render all conve…
ArcadeMode Feb 1, 2026
069e42f
add task return method class to e2e to validate compilation
ArcadeMode Feb 1, 2026
9fc405e
polish
ArcadeMode Feb 1, 2026
2d9c1df
add failing test for func property
ArcadeMode Feb 1, 2026
fc96c14
WIP: try implement rendering expressions with delegate approach
ArcadeMode Feb 2, 2026
759f7c0
delegate based rendering works and tested
ArcadeMode Feb 2, 2026
ff08bff
wip prep for dynamic jsobject mapper tailored to actually used jsobje…
ArcadeMode Feb 3, 2026
712b753
wip jsobject dynamic gen
ArcadeMode Feb 3, 2026
dd57610
render jsimport, add first crude test for extension class dev
ArcadeMode Feb 3, 2026
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
2 changes: 1 addition & 1 deletion TypeShim.E2E/TypeShim.E2E.Wasm/ArrayPropertiesClass.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Runtime.InteropServices.JavaScript;

namespace TypeShim.Sample;
namespace TypeShim.E2E.Wasm;

[TSExport]
public class ArrayPropertiesClass
Expand Down
71 changes: 71 additions & 0 deletions TypeShim.E2E/TypeShim.E2E.Wasm/DelegatesTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.Runtime.InteropServices.JavaScript;

namespace TypeShim.E2E.Wasm;

[TSExport]
public class DelegatesTest
{
public void InvokeVoidAction(Action action)
{
action();
}

public void InvokeStringAction(Action<string> action)
{
action("Hello");
}

public void InvokeInt32Action(Action<int> action)
{
action(42);
}

public void InvokeBoolAction(Action<bool> action)
{
action(true);
}

public void InvokeBool2Action(Action<bool, bool> action)
{
action(true, false);
}

public void InvokeBool3Action(Action<bool, bool, bool> action)
{
action(true, false, true);
}

public string InvokeStringFunc(Func<string> func)
{
return func();
}

public int InvokeInt32Func(Func<int> func)
{
return func();
}

public bool InvokeBoolFunc(Func<bool> func)
{
return func();
}

public bool InvokeBool2Func(Func<bool, bool> func)
{
return func(true);
}

public void InvokeExportedClassAction(Action<ExportedClass> action)
{
action(new ExportedClass { Id = 100 });
}

public Func<ExportedClass> GetExportedClassFunc() {
return () => new ExportedClass { Id = 200 };
}

public Func<ExportedClass, ExportedClass> GetExportedClassExportedClassFunc() {
return (ExportedClass classIn) => classIn;
}
}
2 changes: 1 addition & 1 deletion TypeShim.E2E/TypeShim.E2E.Wasm/ExportedClass.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace TypeShim.Sample;
namespace TypeShim.E2E.Wasm;

[TSExport]
public class ExportedClass // for referencing an exported class
Expand Down
2 changes: 1 addition & 1 deletion TypeShim.E2E/TypeShim.E2E.Wasm/SimplePropertiesTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices.JavaScript;

namespace TypeShim.Sample;
namespace TypeShim.E2E.Wasm;

[TSExport]
public class SimplePropertiesTest
Expand Down
2 changes: 1 addition & 1 deletion TypeShim.E2E/TypeShim.E2E.Wasm/SimpleReturnMethodsClass.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Globalization;

namespace TypeShim.Sample;
namespace TypeShim.E2E.Wasm;

[TSExport]
public class SimpleReturnMethodsClass
Expand Down
2 changes: 1 addition & 1 deletion TypeShim.E2E/TypeShim.E2E.Wasm/TaskPropertiesClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Runtime.InteropServices.JavaScript;
using System.Threading.Tasks;

namespace TypeShim.Sample;
namespace TypeShim.E2E.Wasm;

[TSExport]
public class TaskPropertiesClass
Expand Down
14 changes: 14 additions & 0 deletions TypeShim.E2E/TypeShim.E2E.Wasm/TaskReturnMethodsClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Threading.Tasks;

namespace TypeShim.E2E.Wasm;

[TSExport]
public class TaskReturnMethodsClass
{
public Task VoidTaskMethod() => Task.CompletedTask;
public Task<int> Int32TaskMethod() => Task.FromResult(42);
public Task<bool> BoolTaskMethod() => Task.FromResult(true);
public Task<string> StringTaskMethod() => Task.FromResult("Hello, from .NET Task");

public Task<ExportedClass> ExportedClassTaskMethod() => Task.FromResult(new ExportedClass() { Id = 420 });
}
132 changes: 132 additions & 0 deletions TypeShim.E2E/vitest/src/delegates.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { describe, test, expect, beforeEach } from 'vitest';
import { DelegatesTest, ExportedClass } from '@typeshim/e2e-wasm-lib';

describe('Delegates Test', () => {
let exportedClass: ExportedClass;
let testObject: DelegatesTest;
beforeEach(() => {
exportedClass = new ExportedClass({ Id: 2 });
testObject = new DelegatesTest();
});

test('Invoke Void Action', async () => {
let isInvoked = false;
testObject.InvokeVoidAction(() => {
isInvoked = true;
});
expect(isInvoked).toBe(true);
});

test('Invoke String Action', async () => {
let receivedString = "";
testObject.InvokeStringAction((arg0: string) => {
receivedString = arg0;
});
expect(receivedString).toBe("Hello");
});

test('Invoke Int32 Action', async () => {
let receivedInt = 0;
testObject.InvokeInt32Action((arg0: number) => {
receivedInt = arg0;
});
expect(receivedInt).toBe(42);
});

test('Invoke Bool Action', async () => {
let receivedBool = false;
testObject.InvokeBoolAction((arg0: boolean) => {
receivedBool = arg0;
});
expect(receivedBool).toBe(true);
});

test('Invoke Bool2 Action', async () => {
let receivedBool1 = false;
let receivedBool2 = false;
testObject.InvokeBool2Action((arg0: boolean, arg1: boolean) => {
receivedBool1 = arg0;
receivedBool2 = arg1;
});
expect(receivedBool1).toBe(true);
expect(receivedBool2).toBe(false);
});

test('Invoke Bool3 Action', async () => {
let receivedBool1 = false;
let receivedBool2 = false;
let receivedBool3 = false;
testObject.InvokeBool3Action((arg0: boolean, arg1: boolean, arg2: boolean) => {
receivedBool1 = arg0;
receivedBool2 = arg1;
receivedBool3 = arg2;
});
expect(receivedBool1).toBe(true);
expect(receivedBool2).toBe(false);
expect(receivedBool3).toBe(true);
});

test('Invoke String Func', async () => {
const result = testObject.InvokeStringFunc(() => {
return "Hello World";
});
expect(result).toBe("Hello World");
});

test('Invoke Int32 Func', async () => {
const result = testObject.InvokeInt32Func(() => {
return 12345;
});
expect(result).toBe(12345);
});

test('Invoke Bool Func', async () => {
const result = testObject.InvokeBoolFunc(() => {
return true;
});
expect(result).toBe(true);
});

test('Invoke Bool2 Func', async () => {
const result = testObject.InvokeBool2Func((arg0: boolean) => {
return arg0;
});
expect(result).toBe(true);
});

test('Invoke ExportedClass Action', async () => {
let receivedInstance: ExportedClass = null as any;
testObject.InvokeExportedClassAction((arg0: ExportedClass) => {
receivedInstance = arg0;
});
expect(receivedInstance).not.toBeNull();
expect(receivedInstance).toBeInstanceOf(ExportedClass);
expect(receivedInstance.Id).toBe(100);
});

test('Get ExportedClass Func', async () => {
const fn = testObject.GetExportedClassFunc();
const exportedInstance = fn();
expect(exportedInstance).not.toBeNull();
expect(exportedInstance).toBeInstanceOf(ExportedClass);
expect(exportedInstance.Id).toBe(200);
});

test('Get ExportedClassExportedClassFunc Proxy', async () => {
const instance = new ExportedClass({ Id: 300 });
const fn = testObject.GetExportedClassExportedClassFunc();
const retVal = fn(instance);
expect(retVal).not.toBeNull();
expect(retVal).toBeInstanceOf(ExportedClass);
expect(retVal.Id).toBe(300);
});

test('Get ExportedClassExportedClassFunc Initializer', async () => {
const instance = { Id: 250 };
const fn = testObject.GetExportedClassExportedClassFunc();
const retVal = fn(instance);
expect(retVal).not.toBeNull();
expect(retVal).toBeInstanceOf(ExportedClass);
expect(retVal.Id).toBe(250);
});
});
26 changes: 26 additions & 0 deletions TypeShim.E2E/vitest/src/simple-properties.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,32 @@ describe('Simple Properties Test', () => {
expect(testObject.ExportedClassProperty).toBeInstanceOf(ExportedClass);
expect(testObject.ExportedClassProperty.Id).toBe(2);
});
test('Mutates ExportedClass property correctly', () => {
expect(testObject.ExportedClassProperty).toBeInstanceOf(ExportedClass);
expect(testObject.ExportedClassProperty.Id).toBe(2);
const newExportedClass = new ExportedClass({ Id: 99 });
testObject.ExportedClassProperty = newExportedClass;
expect(testObject.ExportedClassProperty).toBeInstanceOf(ExportedClass);
expect(testObject.ExportedClassProperty.Id).toBe(99);
// TODO: fix identity (https://github.com/ArcadeMode/TypeShim/issues/20)
// expect(testObject.ExportedClassProperty).toBe(newExportedClass);
});
test('Mutates ExportedClass property with Initializer', () => {
expect(testObject.ExportedClassProperty).toBeInstanceOf(ExportedClass);
expect(testObject.ExportedClassProperty.Id).toBe(2);
const exportedClassInitializer = { Id: 12345 };
testObject.ExportedClassProperty = exportedClassInitializer;
expect(testObject.ExportedClassProperty).toBeInstanceOf(ExportedClass);
expect(testObject.ExportedClassProperty.Id).toBe(12345);
});
test('Mutates ExportedClass property does not affect snapshot', () => {
const snapshot = SimplePropertiesTest.materialize(testObject);
expect(testObject.ExportedClassProperty).toBeInstanceOf(ExportedClass);
expect(testObject.ExportedClassProperty.Id).toBe(2);
const newExportedClass = new ExportedClass({ Id: 99 });
testObject.ExportedClassProperty = newExportedClass;
expect(snapshot.ExportedClassProperty.Id).toBe(2);
});
test('Returns JSObject property by reference', () => {
expect(testObject.JSObjectProperty).toBe(jsObject);
const obj = testObject.JSObjectProperty as any;
Expand Down
Loading
Loading