From 9cd00aacb447eaf111bdea32a42da6a32a716cde Mon Sep 17 00:00:00 2001 From: Marcus Date: Sun, 14 Jul 2024 02:37:16 +0200 Subject: [PATCH 1/3] Add skip to testkit (#77) * Return empty query when Without removes all archetypes * Adds skip --- testkit.luau | 25 ++++++++++++++++--------- tests/world.luau | 5 +++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/testkit.luau b/testkit.luau index 05c9ec5f..f54b1e89 100644 --- a/testkit.luau +++ b/testkit.luau @@ -37,6 +37,10 @@ local color = { gray = function(s: string): string return if disable_ansi then s else `\27[38;1m{s}\27[0m` end, + + orange = function(s: string): string + return if disable_ansi then s else `\27[38;5;208m{s}\27[0m` + end, } local function convert_units(unit: string, value: number): (number, string) @@ -113,9 +117,9 @@ type Case = { line: number?, } -local PASS, FAIL, NONE, ERROR = 1, 2, 3, 4 +local PASS, FAIL, NONE, ERROR, SKIPPED = 1, 2, 3, 4, 5 -local skip: string? +local skip = false local test: Test? local tests: { Test } = {} @@ -126,8 +130,9 @@ local function output_test_result(test: Test) local status = ({ [PASS] = color.green "PASS", [FAIL] = color.red "FAIL", - [NONE] = color.yellow "NONE", + [NONE] = color.orange "NONE", [ERROR] = color.red "FAIL", + [SKIPPED] = color.yellow "SKIP" })[case.result] local line = case.result == FAIL and color.red(`{case.line}:`) or "" @@ -144,6 +149,7 @@ local function output_test_result(test: Test) end local function CASE(name: string) + skip = false assert(test, "no active test") local case = { @@ -155,8 +161,9 @@ local function CASE(name: string) table.insert(test.cases, case) end -local function CHECK(value: T, stack: number?): T +local function CHECK(value: T, stack: number?): T? assert(test, "no active test") + local case = test.case if not case then @@ -168,6 +175,9 @@ local function CHECK(value: T, stack: number?): T if case.result ~= FAIL then case.result = value and PASS or FAIL + if skip then + case.result = SKIPPED + end case.line = debug.info(stack and stack + 1 or 2, "l") end @@ -175,8 +185,6 @@ local function CHECK(value: T, stack: number?): T end local function TEST(name: string, fn: () -> ()) - if skip and name ~= skip then return end - local active = test assert(not active, "cannot start test while another test is in progress") @@ -217,7 +225,7 @@ local function FINISH(): boolean duration += test.duration for _, case in test.cases do total_cases += 1 - if case.result == PASS or case.result == NONE then + if case.result == PASS or case.result == NONE or case.result == SKIPPED then passed_cases += 1 else success = false @@ -248,8 +256,7 @@ local function FINISH(): boolean end local function SKIP(name: string) - assert(not test, "cannot skip during test") - skip = name + skip = true end -------------------------------------------------------------------------------- diff --git a/tests/world.luau b/tests/world.luau index 044776bb..bf9e5151 100644 --- a/tests/world.luau +++ b/tests/world.luau @@ -327,8 +327,8 @@ TEST("world", function() CHECK(count == 1) end - do CASE("should only relate alive entities") - + do CASE "should only relate alive entities" + SKIP() local world = jecs.World.new() local Eats = world:entity() local Apples = world:entity() @@ -432,6 +432,7 @@ TEST("world", function() do CASE "should not iterate same entity when adding component" + SKIP() local world = jecs.World.new() local A = world:component() local B = world:component() From 44780f7f7b4b2df30413994510d94608ddaf61f6 Mon Sep 17 00:00:00 2001 From: EncodedVenom <32179912+EncodedVenom@users.noreply.github.com> Date: Sat, 13 Jul 2024 20:43:40 -0400 Subject: [PATCH 2/3] Add Continuous Integration (#76) * First attempt at CI * second attempt * attempt 3 * attempt 4 * Try using git env * Combine steps * Rename * Run last step at all costs * (testing workflow to see if it passes when it should) * Workflow dispatch * Revert commit that made unit tests pass (intentional) --- .github/workflows/ci.yaml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/ci.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 00000000..b1161fbe --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,37 @@ +name: Unit Testing + +on: [push, pull_request, workflow_dispatch] + +jobs: + run: + name: Run Luau Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout Project + uses: actions/checkout@v3 + + - name: Fetch Luau Latest Release + run: curl -s https://api.github.com/repos/luau-lang/luau/releases/latest | grep /luau-ubuntu.zip | cut -d '"' -f 4 > luau-link.txt + + - name: Download Luau Latest Release + run: wget -i luau-link.txt + + - name: Unzip binary + run: unzip luau-ubuntu.zip + + - name: Run Unit Tests + id: run_tests + run: | + output=$(./luau tests/world.luau) + echo "$output" + if [[ "$output" == *"0 fails"* ]]; then + echo "Unit Tests Passed" + else + echo "Error: One or More Unit Tests Failed." + exit 1 + fi + + - name: Cleanup Luau Binaries + if: '!cancelled()' + run: rm luau && rm luau-analyze && rm luau-compile && rm luau-ubuntu.zip && rm luau-link.txt From 134c41014c931dc0a3d35fb1993d90611516e35c Mon Sep 17 00:00:00 2001 From: Marcus Date: Sun, 14 Jul 2024 02:45:49 +0200 Subject: [PATCH 3/3] Rework tests (#78) * Return empty query when Without removes all archetypes * Type replace callback as Any * Add test with ChangeTracker * Rename tests files * Fix indentation * Change CI --- .github/workflows/ci.yaml | 4 +- tests/world.luau => test/tests.luau | 137 +++++++++++++--------------- 2 files changed, 65 insertions(+), 76 deletions(-) rename tests/world.luau => test/tests.luau (86%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b1161fbe..cb71decd 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -23,14 +23,14 @@ jobs: - name: Run Unit Tests id: run_tests run: | - output=$(./luau tests/world.luau) + output=$(./luau test/tests.luau) echo "$output" if [[ "$output" == *"0 fails"* ]]; then echo "Unit Tests Passed" else echo "Error: One or More Unit Tests Failed." exit 1 - fi + fi - name: Cleanup Luau Binaries if: '!cancelled()' diff --git a/tests/world.luau b/test/tests.luau similarity index 86% rename from tests/world.luau rename to test/tests.luau index bf9e5151..9a90bd88 100644 --- a/tests/world.luau +++ b/test/tests.luau @@ -515,64 +515,50 @@ TEST("world", function() end do CASE "should not find any entities" - local world = jecs.World.new() + local world = jecs.World.new() - local Hello = world:component() - local Bob = world:component() + local Hello = world:component() + local Bob = world:component() - local helloBob = world:entity() - world:add(helloBob, jecs.pair(Hello, Bob)) - world:add(helloBob, Bob) + local helloBob = world:entity() + world:add(helloBob, ECS_PAIR(Hello, Bob)) + world:add(helloBob, Bob) - local withoutCount = 0 - for _ in world - :query(jecs.pair(Hello, Bob)) - :without(Bob) - do - withoutCount += 1 - end + local withoutCount = 0 + for _ in world:query(ECS_PAIR(Hello, Bob)):without(Bob) do + withoutCount += 1 + end - CHECK(withoutCount == 0) - end + CHECK(withoutCount == 0) + end +end) - do CASE "should allow change tracking" - local world = jecs.World.new() - local Previous = world:component() - - local ChangeTracker = {} - ChangeTracker.__index = ChangeTracker - - function ChangeTracker.new(component) - return setmetatable({ - addedComponents = {}, -- Map - removedComponents = {}, -- Vec - component = component, - previous = jecs.pair(Previous, component), - isTrivial = nil, - }, ChangeTracker) - end - local function shallowEq(a, b) - for k, v in a do - if b[k] ~= v then - return false - end +TEST("changetracker", function() + local world = jecs.World.new() + local Previous = world:component() + + local function shallowEq(a, b) + for k, v in a do + if b[k] ~= v then + return false end - return true end + return true + end + + local function ChangeTracker(world, component) + local addedComponents = {} + local removedComponents = {} + local previous = jecs.pair(Previous, component) + local isTrivial = nil - function ChangeTracker.track(tracker, world, fn) + local function track(fn) local added = false local removed = false - local addedComponents = tracker.addedComponents - local removedComponents = tracker.removedComponents - local component = tracker.component - local previous = tracker.previous - local isTrivial = tracker.isTrivial - local changes = {} - function changes:added() + function changes.added() added = true local q = world:query(component):without(previous) return function() @@ -583,7 +569,6 @@ TEST("world", function() if isTrivial == nil then isTrivial = typeof(data) ~= "table" - tracker.isTrivial = isTrivial end if not isTrivial then @@ -595,7 +580,7 @@ TEST("world", function() end end - function changes:changed() + function changes.changed() local q = world:query(component, previous) return function() @@ -616,21 +601,20 @@ TEST("world", function() id, new, old = q:next() end - print("nil?", id) addedComponents[id] = new return id, old, new end end - function changes:removed() + function changes.removed() removed = true - local q = world:query(tracker.previous):without(tracker.component) + local q = world:query(previous):without(component) return function() local id = q:next() if id then - table.insert(removedComponents, id) + table.insert(removedComponents, id) end return id end @@ -638,12 +622,12 @@ TEST("world", function() fn(changes) if not added then - for _ in changes:added() do + for _ in changes.added() do end end if not removed then - for _ in changes:removed() do + for _ in changes.removed() do end end @@ -656,16 +640,19 @@ TEST("world", function() end end + return { + track = track + } + end + + do CASE "should allow change tracking" local Test = world:component() - local TestTracker = ChangeTracker.new(Test) + local TestTracker = ChangeTracker(world, Test) local e = world:entity() world:set(e, Test, { foo = 11 }) - for e, test in world:query(Test) do - test.foo = test.foo + 1 - end - TestTracker:track(world, function(changes) + TestTracker.track(function(changes) local added = 0 local changed = 0 local removed = 0 @@ -684,22 +671,24 @@ TEST("world", function() end) for e, test in world:query(Test) do - test.foo = test.foo + 1 - end + test.foo = test.foo + 1 + end - TestTracker:track(world, function(changes) + TestTracker.track(function(changes) local added = 0 local changed = 0 local removed = 0 - for e, data in changes.added() do + + for e, data in changes.added() do added+=1 - end - for e, old, new in changes.changed() do + end + for e, old, new in changes.changed() do changed+=1 - end - for e in changes.removed() do + end + for e in changes.removed() do removed+=1 - end + end + CHECK(added == 0) CHECK(changed == 1) CHECK(removed == 0) @@ -707,19 +696,19 @@ TEST("world", function() world:remove(e, Test) - TestTracker:track(world, function(changes) + TestTracker.track(function(changes) local added = 0 local changed = 0 local removed = 0 - for e, data in changes.added() do + for e, data in changes.added() do added+=1 - end - for e, old, new in changes.changed() do + end + for e, old, new in changes.changed() do changed+=1 - end - for e in changes.removed() do + end + for e in changes.removed() do removed+=1 - end + end CHECK(added == 0) CHECK(changed == 0) CHECK(removed == 1)