Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Jest for running unit tests #242

Merged
merged 24 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
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
Loading