Skip to content

Commit

Permalink
Use Jest for running unit tests (#242)
Browse files Browse the repository at this point in the history
This PR ports us over to Jest!

Closes #241
  • Loading branch information
vocksel authored Apr 22, 2024
1 parent 80ba872 commit 536fe99
Show file tree
Hide file tree
Showing 24 changed files with 636 additions and 668 deletions.
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
/*.rbxm*

# Luau
sourcemap.json
sourcemap*.json

# Selene
/roblox.toml

# Wally
/DevPackages
Expand Down
5 changes: 1 addition & 4 deletions dev.project.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
{
"name": "flipbook",
"tree": {
"Packages": {
"$path": "Packages"
},
"Example": {
"$path": "example"
},
"$path": "src"
"$path": "default.project.json"
}
}
29 changes: 25 additions & 4 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ tests_project := "tests.project.json"

tmpdir := `mktemp -d`
global_defs_path := tmpdir / "globalTypes.d.lua"
testez_defs_path := "testez.d.luau"
sourcemap_path := tmpdir / "sourcemap.json"

_lint-file-extensions:
Expand All @@ -28,13 +27,27 @@ _lint-file-extensions:
exit 1
fi
_get-client-settings:
#!/usr/bin/env bash
set -euxo pipefail
os={{ os_family() }}

if [[ "$os" == "macos" ]]; then
echo "/Applications/RobloxStudio.app/Contents/MacOS/ClientSettings"
elif [[ "$os" == "windows" ]]; then
robloxStudioPath=$(find "$LOCALAPPDATA/Roblox/Versions" -name "RobloxStudioBeta.exe")
dir=$(dirname $robloxStudioPath)
echo "$dir/ClientSettings"
fi

default:
@just --list

wally-install:
wally install
rojo sourcemap {{ tests_project }} -o {{ sourcemap_path }}
wally-package-types --sourcemap {{ sourcemap_path }} {{ packages_dir }}
wally-package-types --sourcemap {{ sourcemap_path }} {{ absolute_path(packages_dir) }}

init:
foreman install
Expand All @@ -52,9 +65,18 @@ build-watch:
npx -y chokidar-cli "{{ project_dir }}/**/*" --initial \
-c "just build" \

set-flags:
#!/usr/bin/env bash
set -euxo pipefail
clientSettings=$(just _get-client-settings)
mkdir -p "$clientSettings"
cp -R tests/ClientAppSettings.json "$clientSettings"

test:
just set-flags
rojo build {{ tests_project }} -o test-place.rbxl
run-in-roblox --place test-place.rbxl --script tests/init.server.lua
run-in-roblox --place test-place.rbxl --script tests/run-tests.luau

analyze:
curl -s -o {{ global_defs_path }} \
Expand All @@ -64,7 +86,6 @@ analyze:

luau-lsp analyze --sourcemap={{ sourcemap_path }} \
--defs={{ global_defs_path }} \
--defs={{ testez_defs_path }} \
--settings="./.vscode/settings.json" \
--ignore=**/_Index/** \
{{ project_dir }}
Expand Down
2 changes: 1 addition & 1 deletion selene.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
std = "roblox+testez"
std = "roblox"

[lints]
global_usage = "allow"
30 changes: 17 additions & 13 deletions src/Common/mapRanges.spec.luau
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
return function()
local mapRanges = require(script.Parent.mapRanges)

it("should return 1.5 if we remap 0.5 from a 0 -> 1 range to a 1 -> 2 range", function()
expect(mapRanges(0.5, 0, 1, 1, 2)).to.equal(1.5)
end)

it("should error if max0 is the same as min0", function()
expect(function()
mapRanges(0.5, 1, 1, 2, 2)
end).to.throw()
end)
end
local flipbook = script:FindFirstAncestor("flipbook")

local JestGlobals = require(flipbook.Packages.JestGlobals)
local mapRanges = require(script.Parent.mapRanges)

local expect = JestGlobals.expect
local test = JestGlobals.test

test("return 1.5 if we remap 0.5 from a 0 -> 1 range to a 1 -> 2 range", function()
expect(mapRanges(0.5, 0, 1, 1, 2)).toBe(1.5)
end)

test("error if max0 is the same as min0", function()
expect(function()
mapRanges(0.5, 1, 1, 2, 2)
end).toThrow()
end)
171 changes: 87 additions & 84 deletions src/Common/useDescendants.spec.luau
Original file line number Diff line number Diff line change
@@ -1,107 +1,110 @@
local flipbook = script:FindFirstAncestor("flipbook")

return function()
local React = require(flipbook.Packages.React)
local ReactRoblox = require(flipbook.Packages.ReactRoblox)
local newFolder = require(flipbook.Testing.newFolder)
local useDescendants = require(script.Parent.useDescendants)

local container = Instance.new("ScreenGui")
local root = ReactRoblox.createRoot(container)

afterEach(function()
ReactRoblox.act(function()
root:unmount()
end)
local JestGlobals = require(flipbook.Packages.JestGlobals)
local React = require(flipbook.Packages.React)
local ReactRoblox = require(flipbook.Packages.ReactRoblox)
local newFolder = require(flipbook.Testing.newFolder)
local useDescendants = require(script.Parent.useDescendants)

local afterEach = JestGlobals.afterEach
local expect = JestGlobals.expect
local test = JestGlobals.test

local container = Instance.new("ScreenGui")
local root = ReactRoblox.createRoot(container)

afterEach(function()
ReactRoblox.act(function()
root:unmount()
end)

it("should return an initial list of descendants that match the predicate", function()
local tree = newFolder({
Match = Instance.new("Part"),
Foo = Instance.new("Part"),
})

local descendants
local function HookTester()
descendants = useDescendants(tree, function(descendant)
return descendant.Name == "Match"
end)

return nil
end

ReactRoblox.act(function()
root:render(React.createElement(HookTester))
end)

test("return an initial list of descendants that match the predicate", function()
local tree = newFolder({
Match = Instance.new("Part"),
Foo = Instance.new("Part"),
})

local descendants
local function HookTester()
descendants = useDescendants(tree, function(descendant)
return descendant.Name == "Match"
end)

expect(descendants).to.be.ok()
expect(#descendants).to.equal(1)
expect(descendants[1]).to.equal(tree:FindFirstChild("Match"))
end)

it("should respond to changes in descendants that match the predicate", function()
local tree = newFolder({
Match = Instance.new("Part"),
Foo = Instance.new("Part"),
})
return nil
end

local descendants
local function HookTester()
descendants = useDescendants(tree, function(descendant)
return descendant.Name == "Match"
end)

return nil
end
ReactRoblox.act(function()
root:render(React.createElement(HookTester))
end)

ReactRoblox.act(function()
root:render(React.createElement(HookTester))
expect(descendants).toBeDefined()
expect(#descendants).toBe(1)
expect(descendants[1]).toBe(tree:FindFirstChild("Match"))
end)

test("respond to changes in descendants that match the predicate", function()
local tree = newFolder({
Match = Instance.new("Part"),
Foo = Instance.new("Part"),
})

local descendants
local function HookTester()
descendants = useDescendants(tree, function(descendant)
return descendant.Name == "Match"
end)

expect(descendants).to.be.ok()
expect(#descendants).to.equal(1)
return nil
end

local folder = newFolder({
Match = Instance.new("Part"),
})
ReactRoblox.act(function()
root:render(React.createElement(HookTester))
end)

ReactRoblox.act(function()
folder.Parent = tree
end)
expect(descendants).toBeDefined()
expect(#descendants).toBe(1)

expect(#descendants).to.equal(2)
end)
local folder = newFolder({
Match = Instance.new("Part"),
})

it("should force an update when a matching descendant's name changes", function()
local descendants
ReactRoblox.act(function()
folder.Parent = tree
end)

local tree = newFolder({
Match = Instance.new("Part"),
})
expect(#descendants).toBe(2)
end)

local function HookTester()
descendants = useDescendants(tree, function(descendant)
return descendant:IsA("Part")
end)
test("force an update when a matching descendant's name changes", function()
local descendants

return nil
end
local tree = newFolder({
Match = Instance.new("Part"),
})

ReactRoblox.act(function()
root:render(React.createElement(HookTester))
local function HookTester()
descendants = useDescendants(tree, function(descendant)
return descendant:IsA("Part")
end)

expect(descendants).to.be.ok()
expect(#descendants).to.equal(1)
return nil
end

local prev = descendants
local match = tree:FindFirstChild("Match")
ReactRoblox.act(function()
root:render(React.createElement(HookTester))
end)

ReactRoblox.act(function()
match.Name = "Changed"
end)
expect(descendants).toBeDefined()
expect(#descendants).toBe(1)

expect(descendants).never.to.equal(prev)
expect(descendants[1]).to.equal(match)
local prev = descendants
local match = tree:FindFirstChild("Match")

ReactRoblox.act(function()
match.Name = "Changed"
end)
end

expect(descendants).never.toBe(prev)
expect(descendants[1]).toBe(match)
end)
Loading

0 comments on commit 536fe99

Please sign in to comment.