diff --git a/makefile b/makefile index 6f17df2..11f5a0f 100644 --- a/makefile +++ b/makefile @@ -37,6 +37,7 @@ build-go: ## build from current commit using just go wasm: ## build wasm binary @echo Build wasm binary @go generate ./wasm/wasm.go + @tar -czf ./wasm/kuneiform_wasm.tar.gz -C ./wasm/ kuneiform.wasm release: ## release @# need configure github token @@ -45,3 +46,7 @@ release: ## release test: ## run tests @go test -v ./kfparser/ -count=1 + @make test-wasm + +test-wasm: ## run wasm tests + @GOOS=js GOARCH=wasm go test -v -exec="$$(go env GOROOT)/misc/wasm/go_js_wasm_exec" ./wasm/ -count=1 \ No newline at end of file diff --git a/wasm/.gitignore b/wasm/.gitignore index 917660a..f455cfc 100644 --- a/wasm/.gitignore +++ b/wasm/.gitignore @@ -1 +1,2 @@ -*.wasm \ No newline at end of file +*.wasm +*.tar.gz \ No newline at end of file diff --git a/wasm/testdata/all_features.golden b/wasm/testdata/all_features.golden new file mode 100644 index 0000000..0d44f44 --- /dev/null +++ b/wasm/testdata/all_features.golden @@ -0,0 +1,57 @@ +{ + "owner": "", + "name": "td1", + "tables": [ + { + "name": "tt1", + "columns": [ + { + "name": "tc1", + "type": "int" + } + ] + } + ], + "actions": [ + { + "name": "act1", + "inputs": [ + "$var1" + ], + "public": false, + "mutability": "update", + "auxiliaries": null, + "statements": [ + "select * from tt1 where tc1 = $var1;" + ] + }, + { + "name": "init", + "inputs": null, + "public": false, + "mutability": "update", + "auxiliaries": null, + "statements": [ + "act1(1);", + "$v=ext1.call(@caller);", + "insert into tt1 values ($v);" + ] + } + ], + "extensions": [ + { + "name": "a_ext", + "config": [ + { + "argument": "addr", + "value": "'0x0000'" + }, + { + "argument": "seed", + "value": "3" + } + ], + "alias": "ext1" + } + ] +} \ No newline at end of file diff --git a/wasm/testdata/all_features.kf b/wasm/testdata/all_features.kf new file mode 100644 index 0000000..9a7fcac --- /dev/null +++ b/wasm/testdata/all_features.kf @@ -0,0 +1,14 @@ +database td1; +use a_ext{addr: '0x0000', seed: 3} as ext1; + +table tt1 { tc1 int } + +action act1($var1) private { + select * from tt1 where tc1 = $var1; +} + +init() { + act1(1); + $v = ext1.call(@caller); + insert into tt1 values ($v); +} \ No newline at end of file diff --git a/wasm/wasm_test.go b/wasm/wasm_test.go new file mode 100644 index 0000000..4b93daa --- /dev/null +++ b/wasm/wasm_test.go @@ -0,0 +1,75 @@ +//go:build js && wasm + +package main + +import ( + "flag" + "io" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var ( + update = flag.Bool("update", false, "update the golden files of this test") +) + +var testDataDir = "testdata" + +func goldenValue(t *testing.T, goldenFile string, actual string, update bool) string { + t.Helper() + goldenPath := filepath.Join(".", testDataDir, goldenFile+".golden") + + f, err := os.OpenFile(goldenPath, os.O_RDWR|os.O_CREATE, 0666) + defer f.Close() + + if update { + _, err := f.WriteString(actual) + if err != nil { + t.Fatalf("Error writing to file %s: %s", goldenPath, err) + } + + return actual + } + + content, err := io.ReadAll(f) + if err != nil { + t.Fatalf("Error opening file %s: %s", goldenPath, err) + } + return string(content) +} + +func TestParse(t *testing.T) { + // refer: https://github.com/golang/go/wiki/WebAssembly#executing-webassembly-with-nodejs + + // TODO: refactor, this method should also works for ../kfparser/parser_test.go + // testdata directory should be shared between wasm and kfparser tests + tests := []struct { + name string + target string + }{ + { + name: "all_features", + target: "all_features", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + kfPath := filepath.Join(".", testDataDir, tt.target+".kf") + + kfDef, err := os.ReadFile(kfPath) + require.NoError(t, err) + + got, err := parse(string(kfDef)) + require.NoError(t, err) + + want := goldenValue(t, tt.target, got, *update) + + assert.Equal(t, want, got) + }) + } +}