From c1c007e9c8796aa9f226582c3e905dfa7fd8cd3b Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Sat, 27 Jul 2024 01:14:47 -0300 Subject: [PATCH 1/6] adapt language_tests to nix --- test/language/test/ffi.gleam | 6 + test/language/test/ffi_nix.nix | 15 ++ test/language/test/importable.gleam | 49 +++++ test/language/test/language_test.gleam | 292 +++++++++++++++++++++++++ 4 files changed, 362 insertions(+) create mode 100644 test/language/test/ffi_nix.nix diff --git a/test/language/test/ffi.gleam b/test/language/test/ffi.gleam index 339c4ff1f..8276110e6 100644 --- a/test/language/test/ffi.gleam +++ b/test/language/test/ffi.gleam @@ -2,24 +2,30 @@ pub type Dynamic @external(erlang, "ffi_erlang", "print") @external(javascript, "./ffi_javascript.mjs", "print") +@external(nix, "./ffi_nix.nix", "print") pub fn print(a: String) -> Nil @external(erlang, "ffi_erlang", "append") @external(javascript, "./ffi_javascript.mjs", "append") +@external(nix, "./ffi_nix.nix", "append") pub fn append(a: String, b: String) -> String @external(erlang, "ffi_erlang", "to_string") @external(javascript, "./ffi_javascript.mjs", "toString") +@external(nix, "./ffi_nix.nix", "toString") pub fn to_string(a: anything) -> String @external(erlang, "ffi_erlang", "file_exists") @external(javascript, "./ffi_javascript.mjs", "fileExists") +@external(nix, "./ffi_nix.nix", "fileExists") pub fn file_exists(a: String) -> Bool @external(erlang, "ffi_erlang", "halt") @external(javascript, "./ffi_javascript.mjs", "halt") +@external(nix, "./ffi_nix.nix", "halt") pub fn halt(a: Int) -> Nil @external(erlang, "ffi_erlang", "to_dynamic") @external(javascript, "./ffi_javascript.mjs", "toDynamic") +@external(nix, "./ffi_nix.nix", "toDynamic") pub fn to_dynamic(a: x) -> Dynamic diff --git a/test/language/test/ffi_nix.nix b/test/language/test/ffi_nix.nix new file mode 100644 index 000000000..9a07c1554 --- /dev/null +++ b/test/language/test/ffi_nix.nix @@ -0,0 +1,15 @@ +let + print = msg: builtins.trace msg null; + append = a: b: a + b; + toString = builtins.toJSON; + fileExists = + f: + let + # ./. is relative to this file in the build directory (language/build/dev/nix/ffi_nix.nix) + # In other targets, this would be relative to 'language/', so let's go back there' + absPath = if builtins.isString f && builtins.substring 0 1 f != "/" then ./../../../../${f} else f; + in builtins.pathExists absPath; + halt = code: if code == 0 then null else builtins.abort (toString code); + toDynamic = x: x; +in +{ inherit print append toString fileExists halt toDynamic; } diff --git a/test/language/test/importable.gleam b/test/language/test/importable.gleam index f6ca012fa..219096765 100644 --- a/test/language/test/importable.gleam +++ b/test/language/test/importable.gleam @@ -16,6 +16,7 @@ pub const ints_in_bit_array = <<1, 2, 3>> pub const string_in_bit_array = <<"Gleam":utf8>> +@target(erlang) pub const data = << 0x1, 2, @@ -26,6 +27,41 @@ pub const data = << <<<<1, 2, 3>>:bits, "Gleam":utf8, 1024>>:bits, >> +@target(javascript) +pub const data = << + 0x1, + 2, + 2:size(16), + 0x4:size(32), + "Gleam":utf8, + 4.2:float, + <<<<1, 2, 3>>:bits, "Gleam":utf8, 1024>>:bits, +>> + +@target(nix) +pub const data = << + 0x1, + 2, + 2:size(16), + 0x4:size(32), + "Gleam":utf8, + <<<<1, 2, 3>>:bits, "Gleam":utf8, 1024>>:bits, +>> + +@target(erlang) +pub fn get_bit_array() { + << + 0x1, + 2, + 2:size(16), + 0x4:size(32), + "Gleam":utf8, + 4.2:float, + <<<<1, 2, 3>>:bits, "Gleam":utf8, 1024>>:bits, + >> +} + +@target(javascript) pub fn get_bit_array() { << 0x1, @@ -38,6 +74,19 @@ pub fn get_bit_array() { >> } +// TODO: impl :float on nix +@target(nix) +pub fn get_bit_array() { + << + 0x1, + 2, + 2:size(16), + 0x4:size(32), + "Gleam":utf8, + <<<<1, 2, 3>>:bits, "Gleam":utf8, 1024>>:bits, + >> +} + pub const language = "gleam" pub type Movie { diff --git a/test/language/test/language_test.gleam b/test/language/test/language_test.gleam index b188cf639..1e4fdcc80 100644 --- a/test/language/test/language_test.gleam +++ b/test/language/test/language_test.gleam @@ -242,6 +242,7 @@ fn assert_tests() -> List(Test) { ] } +@target(erlang) fn tail_call_optimisation_tests() -> List(Test) { [ "10 million recursions doesn't overflow the stack" @@ -260,6 +261,45 @@ fn tail_call_optimisation_tests() -> List(Test) { ] } +@target(javascript) +fn tail_call_optimisation_tests() -> List(Test) { + [ + "10 million recursions doesn't overflow the stack" + |> example(fn() { assert_equal(Nil, count_down(from: 10_000_000)) }), + // https://github.com/gleam-lang/gleam/issues/1214 + // https://github.com/gleam-lang/gleam/issues/1380 + "Arguments correctly reassigned" + |> example(fn() { + assert_equal([1, 2, 3], tail_recursive_accumulate_down(3, [])) + }), + // https://github.com/gleam-lang/gleam/issues/2400 + "not recursion, the function is shadowed its argument" + |> example(fn() { + assert_equal(function_shadowed_by_own_argument(fn() { 1 }), 1) + }), + ] +} + +@target(nix) +fn tail_call_optimisation_tests() -> List(Test) { + [ + // TODO: Tail call optimization + // "10 million recursions doesn't overflow the stack" + // |> example(fn() { assert_equal(Nil, count_down(from: 10_000_000)) }), + // https://github.com/gleam-lang/gleam/issues/1214 + // https://github.com/gleam-lang/gleam/issues/1380 + "Arguments correctly reassigned" + |> example(fn() { + assert_equal([1, 2, 3], tail_recursive_accumulate_down(3, [])) + }), + // https://github.com/gleam-lang/gleam/issues/2400 + "not recursion, the function is shadowed its argument" + |> example(fn() { + assert_equal(function_shadowed_by_own_argument(fn() { 1 }), 1) + }), + ] +} + fn function_shadowed_by_own_argument(function_shadowed_by_own_argument) { function_shadowed_by_own_argument() } @@ -951,6 +991,7 @@ fn equality_tests() -> List(Test) { ] } +@target(erlang) fn bit_array_tests() -> List(Test) { [ "<<\"Gleam\":utf8, \"👍\":utf8>> == <<\"Gleam\":utf8, \"👍\":utf8>>" @@ -977,6 +1018,57 @@ fn bit_array_tests() -> List(Test) { ] } +@target(javascript) +fn bit_array_tests() -> List(Test) { + [ + "<<\"Gleam\":utf8, \"👍\":utf8>> == <<\"Gleam\":utf8, \"👍\":utf8>>" + |> example(fn() { + assert_equal( + True, + <<"Gleam":utf8, "👍":utf8>> == <<"Gleam":utf8, "👍":utf8>>, + ) + }), + "<<\"Gleam\":utf8, \"👍\":utf8>> == <<\"👍\":utf8>>" + |> example(fn() { + assert_equal(False, <<"Gleam":utf8, "👍":utf8>> == <<"👍":utf8>>) + }), + "<<\"abc\":utf8>> == <<97, 98, 99>>" + |> example(fn() { assert_equal(True, <<"abc":utf8>> == <<97, 98, 99>>) }), + "<<<<1>>:bit_array, 2>> == <<1, 2>>" + |> example(fn() { assert_equal(True, <<<<1>>:bits, 2>> == <<1, 2>>) }), + "<<1>> == <<1:int>>" + |> example(fn() { assert_equal(True, <<1>> == <<1:int>>) }), + "<<63, 240, 0, 0, 0, 0, 0, 0>> == <<1.0:float>>" + |> example(fn() { + assert_equal(True, <<63, 240, 0, 0, 0, 0, 0, 0>> == <<1.0:float>>) + }), + ] +} + +// TODO: impl :float on nix +@target(nix) +fn bit_array_tests() -> List(Test) { + [ + "<<\"Gleam\":utf8, \"👍\":utf8>> == <<\"Gleam\":utf8, \"👍\":utf8>>" + |> example(fn() { + assert_equal( + True, + <<"Gleam":utf8, "👍":utf8>> == <<"Gleam":utf8, "👍":utf8>>, + ) + }), + "<<\"Gleam\":utf8, \"👍\":utf8>> == <<\"👍\":utf8>>" + |> example(fn() { + assert_equal(False, <<"Gleam":utf8, "👍":utf8>> == <<"👍":utf8>>) + }), + "<<\"abc\":utf8>> == <<97, 98, 99>>" + |> example(fn() { assert_equal(True, <<"abc":utf8>> == <<97, 98, 99>>) }), + "<<<<1>>:bit_array, 2>> == <<1, 2>>" + |> example(fn() { assert_equal(True, <<<<1>>:bits, 2>> == <<1, 2>>) }), + "<<1>> == <<1:int>>" + |> example(fn() { assert_equal(True, <<1>> == <<1:int>>) }), + ] +} + @target(erlang) fn bit_array_target_tests() -> List(Test) { [ @@ -996,6 +1088,11 @@ fn bit_array_target_tests() -> List(Test) { [] } +@target(nix) +fn bit_array_target_tests() -> List(Test) { + [] +} + fn sized_bit_array_tests() -> List(Test) { [ "<<1>> == <<257:size(8)>>" @@ -1319,6 +1416,7 @@ fn int_negation_tests() { ] } +@target(erlang) fn bit_array_match_tests() { [ "let <<1, x>> = <<1, 2>>" @@ -1414,6 +1512,190 @@ fn bit_array_match_tests() { ] } +@target(javascript) +fn bit_array_match_tests() { + [ + "let <<1, x>> = <<1, 2>>" + |> example(fn() { + assert_equal(2, { + let assert <<1, x>> = <<1, 2>> + x + }) + }), + "let <> = <<1>>" + |> example(fn() { + assert_equal(1, { + let assert <> = <<1>> + a + }) + }), + "let <> = <<1, 2, 3>>" + |> example(fn() { + assert_equal(#(258, 3), { + let assert <> = <<1, 2, 3>> + #(a, b) + }) + }), + "let <> = <<63,240,0,0,0,0,0,0,1>>" + |> example(fn() { + assert_equal(#(1.0, 1), { + let assert <> = <<63, 240, 0, 0, 0, 0, 0, 0, 1>> + #(a, b) + }) + }), + "let <> = <<1.23:float>>" + |> example(fn() { + assert_equal(1.23, { + let assert <> = <<1.23:float>> + a + }) + }), + "let <<_, rest:binary>> = <<1>>" + |> example(fn() { + assert_equal(<<>>, { + let assert <<_, rest:bytes>> = <<1>> + rest + }) + }), + "let <<_, rest:binary>> = <<1,2,3>>" + |> example(fn() { + assert_equal(<<2, 3>>, { + let assert <<_, rest:bytes>> = <<1, 2, 3>> + rest + }) + }), + "let <> = <<1,2,3>>" + |> example(fn() { + assert_equal(<<1, 2>>, { + let assert <> = <<1, 2, 3>> + x + }) + }), + "bit_array from function" + |> example(fn() { + assert_equal( + True, + << + 0x1, + 2, + 2:size(16), + 0x4:size(32), + "Gleam":utf8, + 4.2:float, + <<<<1, 2, 3>>:bits, "Gleam":utf8, 1024>>:bits, + >> == importable.get_bit_array(), + ) + }), + "bit_array module const" + |> example(fn() { + assert_equal( + True, + << + 0x1, + 2, + 2:size(16), + 0x4:size(32), + "Gleam":utf8, + 4.2:float, + <<<<1, 2, 3>>:bits, "Gleam":utf8, 1024>>:bits, + >> == importable.data, + ) + }), + "<<71, 108, 101, 97, 109>> == <<\"Gleam\":utf8>>" + |> example(fn() { + assert_equal(True, <<71, 108, 101, 97, 109>> == <<"Gleam":utf8>>) + }), + ] +} + +// TODO: impl :float on bitarrays so we can keep one test for all targets +@target(nix) +fn bit_array_match_tests() { + [ + "let <<1, x>> = <<1, 2>>" + |> example(fn() { + assert_equal(2, { + let assert <<1, x>> = <<1, 2>> + x + }) + }), + "let <> = <<1>>" + |> example(fn() { + assert_equal(1, { + let assert <> = <<1>> + a + }) + }), + "let <> = <<1, 2, 3>>" + |> example(fn() { + assert_equal(#(258, 3), { + let assert <> = <<1, 2, 3>> + #(a, b) + }) + }), + "let <> = <<1>>" + |> example(fn() { + assert_equal(1, { + let assert <> = <<1>> + b + }) + }), + "let <<_, rest:binary>> = <<1>>" + |> example(fn() { + assert_equal(<<>>, { + let assert <<_, rest:bytes>> = <<1>> + rest + }) + }), + "let <<_, rest:binary>> = <<1,2,3>>" + |> example(fn() { + assert_equal(<<2, 3>>, { + let assert <<_, rest:bytes>> = <<1, 2, 3>> + rest + }) + }), + "let <> = <<1,2,3>>" + |> example(fn() { + assert_equal(<<1, 2>>, { + let assert <> = <<1, 2, 3>> + x + }) + }), + "bit_array from function" + |> example(fn() { + assert_equal( + True, + << + 0x1, + 2, + 2:size(16), + 0x4:size(32), + "Gleam":utf8, + <<<<1, 2, 3>>:bits, "Gleam":utf8, 1024>>:bits, + >> == importable.get_bit_array(), + ) + }), + "bit_array module const" + |> example(fn() { + assert_equal( + True, + << + 0x1, + 2, + 2:size(16), + 0x4:size(32), + "Gleam":utf8, + <<<<1, 2, 3>>:bits, "Gleam":utf8, 1024>>:bits, + >> == importable.data, + ) + }), + "<<71, 108, 101, 97, 109>> == <<\"Gleam\":utf8>>" + |> example(fn() { + assert_equal(True, <<71, 108, 101, 97, 109>> == <<"Gleam":utf8>>) + }), + ] +} + fn anonymous_function_tests() { [ // https://github.com/gleam-lang/gleam/issues/1637 @@ -1505,6 +1787,16 @@ fn typescript_file_included_tests() { ] } +@target(nix) +fn typescript_file_included_tests() { + // Relative to current file + let path = "./build/dev/nix/language/ffi_typescript.ts" + [ + path + |> example(fn() { assert_equal(file_exists(path), True) }), + ] +} + type Cat { Cat(String, cuteness: Int) } From 6c1e80596034a1b258d8401e59382562dbf41a61 Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Sun, 28 Jul 2024 02:07:20 -0300 Subject: [PATCH 2/6] add nix to language test makefile --- test/language/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/language/Makefile b/test/language/Makefile index baa950281..d2ab40378 100644 --- a/test/language/Makefile +++ b/test/language/Makefile @@ -24,3 +24,8 @@ deno: bun: @echo test/languate on JavaScript with Bun cargo run --quiet -- test --target javascript --runtime bun + +.phony: nix +nix: + @echo test/language on Nix + cargo run --quiet -- test --target nix From 3b58df7184ff8dcd5603dcfe09e9ffe01640ce96 Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Sun, 28 Jul 2024 02:07:20 -0300 Subject: [PATCH 3/6] ci: test nix on language test --- .github/workflows/ci.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 15246531d..7dff1dbfc 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -557,6 +557,10 @@ jobs: run: make clean bun working-directory: ./test/language + - name: test/language Nix + run: make clean nix + working-directory: ./test/language + - name: test/compile_package0 run: make working-directory: ./test/compile_package0 From 0439a37f9e95cc40e3a2575d7589182b57f414b4 Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Sun, 28 Jul 2024 02:22:47 -0300 Subject: [PATCH 4/6] ci: install nix before test-projects --- .github/workflows/ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7dff1dbfc..0c26a5e93 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -527,6 +527,9 @@ jobs: elixir-version: "1.16.1" rebar3-version: "3" + - name: Install Nix + uses: nixbuild/nix-quick-install-action@v27 + - name: Download Glistix binary from previous job uses: actions/download-artifact@v4 with: From 92529e1fa597799fba626299286ba1d968885ed7 Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Sun, 28 Jul 2024 02:27:07 -0300 Subject: [PATCH 5/6] fix outdated comment --- test/language/test/language_test.gleam | 1 - 1 file changed, 1 deletion(-) diff --git a/test/language/test/language_test.gleam b/test/language/test/language_test.gleam index 1e4fdcc80..4615c31fc 100644 --- a/test/language/test/language_test.gleam +++ b/test/language/test/language_test.gleam @@ -1789,7 +1789,6 @@ fn typescript_file_included_tests() { @target(nix) fn typescript_file_included_tests() { - // Relative to current file let path = "./build/dev/nix/language/ffi_typescript.ts" [ path From c52ad8fa5f56c0a9d49fd2d230cd09baddd6be5f Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Sun, 28 Jul 2024 02:36:40 -0300 Subject: [PATCH 6/6] fix comment in nix ffi --- test/language/test/ffi_nix.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/language/test/ffi_nix.nix b/test/language/test/ffi_nix.nix index 9a07c1554..1abec35fb 100644 --- a/test/language/test/ffi_nix.nix +++ b/test/language/test/ffi_nix.nix @@ -6,7 +6,7 @@ let f: let # ./. is relative to this file in the build directory (language/build/dev/nix/ffi_nix.nix) - # In other targets, this would be relative to 'language/', so let's go back there' + # In other targets, this would be relative to 'language/', so let's go back there absPath = if builtins.isString f && builtins.substring 0 1 f != "/" then ./../../../../${f} else f; in builtins.pathExists absPath; halt = code: if code == 0 then null else builtins.abort (toString code);