Skip to content

Commit

Permalink
LUAFDN-565: Add tests to devtools (and fixes to make them pass) (#300)
Browse files Browse the repository at this point in the history
Added the storeOwners tests.

In the process, discovered and resolved issues in devtools:

* Using a table instead of polyfill's Set object caused Array.from to return an empty array, leading to owners info being lost.
* Expecting getIndexOfElementID to always return a number caused nil errors.
* Using act would cause reconciler configs to clash
* lastIndexOf was misimplemented
* Erroneous early-requires of React in other test code break devtools initialization
  • Loading branch information
RoFlection Bot committed Aug 18, 2022
1 parent 56ddda9 commit 7c78801
Show file tree
Hide file tree
Showing 20 changed files with 924 additions and 361 deletions.
1 change: 1 addition & 0 deletions .styluaignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.snap.lua
1 change: 1 addition & 0 deletions bin/spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ local RobloxJest = require(RotrieverWorkspace.React.Dev.RobloxJest)
-- ROBLOX deviation: upstream mocks both of these via
-- scripts/setupHostConfigs.js, but this testing entry-point is the closest
-- equivalent we have
_G.__ROACT_17_MOCK_SCHEDULER__ = true
RobloxJest.mock(RotrieverWorkspace.Scheduler.Scheduler, function()
return require(RotrieverWorkspace.Scheduler.Scheduler.unstable_mock)
end)
Expand Down
79 changes: 79 additions & 0 deletions bin/testing.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash
set -e

<<comment
Got tired of the long commands throughout the dev/test workflow.
This script simplifies it :)
Passing no args will simply run the unit tests
Passing --analyze or -a will run static type analysis
Passing --snapshot or -s will (re)generate the Jest snapshots
Passing --profile or -p will generate & open a flamegraph of a benchmark that you supply
Example usages:
bin/testing.sh
bin/testing.sh -a
bin/testing.sh --snapshot
bin/testing.sh -p bin/run-wide-tree-benchmark.lua
comment

# Parse the args
PARAMS=""
while (( "$#" )); do
case "$1" in
-s|--snapshot)
SNAPSHOT=0
shift
;;
-a|--analyze)
ANALYZE=0
shift
;;
-p|--profile)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
PROFILE=$2
shift 2
else
echo "Error: Argument for $1 is missing, please specify a lua file to run (ie: bin/run-sierpinski-triangle-benchmark.lua)" >&2
exit 1
fi
;;
-*|--*=)
echo "Error: Unsupported flag $1" >&2
exit 1
;;
*) # Preserve positional arguments
PARAMS="$PARAMS $1"
shift
;;
esac
done
# Set positional arguments in their proper place
eval set -- "$PARAMS"

# Perform requested action

if [[ $SNAPSHOT ]]; then
echo "Generating snapshots..."
roblox-cli run --load.model tests.project.json --run bin/spec.lua --fastFlags.overrides EnableLoadModule=true --fastFlags.allOnLuau --lua.globals=__DEV__=true --lua.globals=__COMPAT_WARNINGS__=true --lua.globals=UPDATESNAPSHOT="all" --load.asRobloxScript --fs.readwrite="$(pwd)"
exit 0
fi

if [[ $ANALYZE ]]; then
echo "Analyzing..."
robloxdev-cli analyze tests.project.json
exit 0
fi

if [[ $PROFILE ]]; then
echo "Generating profiled benchmark '$PROFILE'..."
robloxdev-cli run --load.model tests.project.json --run $PROFILE --headlessRenderer 1 --fastFlags.overrides "EnableDelayedTaskMethods=true" "FIntScriptProfilerFrequency=1000000" "DebugScriptProfilerEnabled=true" "EnableLoadModule=true" --fastFlags.allOnLuau
python ../game-engine/Client/Luau/tools/perfgraph.py profile.out > $PROFILE-profile.svg
rm profile.out
start $PROFILE-profile.svg
echo "Flamegraph opened successfully in default svg viewer application"
exit 0
fi

echo "Running tests..."
roblox-cli run --load.model tests.project.json --run bin/spec.lua --fastFlags.overrides EnableLoadModule=true --fastFlags.allOnLuau --lua.globals=__DEV__=true --lua.globals=__COMPAT_WARNINGS__=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
-- Jest Roblox Snapshot v1, http://roblox.github.io/jest-roblox/snapshot-testing

local exports = {}

exports[ [=[Store owners list should drill through interleaved intermediate components: 1: mount 1]=] ] = [=[
"[root]
▾ <Root>
▾ <Intermediate key=\"intermediate\">
<Leaf key=\"leaf\">
▾ <Wrapper key=\"wrapper\">
<Leaf>
<Leaf key=\"leaf\">"
]=]

exports[ [=[Store owners list should drill through interleaved intermediate components: 2: components owned by <Root> 1]=] ] = [=[
" ▾ <Root>
▾ <Intermediate key=\"intermediate\">
<Leaf>
<Leaf key=\"leaf\">"
]=]

exports[ [=[Store owners list should drill through interleaved intermediate components: 3: components owned by <Intermediate> 1]=] ] = [=[
" ▾ <Intermediate key=\"intermediate\">
<Leaf key=\"leaf\">
▾ <Wrapper key=\"wrapper\">"
]=]

exports[ [=[Store owners list should drill through intermediate components: 1: mount 1]=] ] = [=[
"[root]
▾ <Root>
▾ <Intermediate>
▾ <Wrapper>
<Leaf>"
]=]

exports[ [=[Store owners list should drill through intermediate components: 2: components owned by <Root> 1]=] ] = [=[
" ▾ <Root>
▾ <Intermediate>
<Leaf>"
]=]

exports[ [=[Store owners list should drill through intermediate components: 3: components owned by <Intermediate> 1]=] ] = [=[
" ▾ <Intermediate>
▾ <Wrapper>"
]=]

exports[ [=[Store owners list should show the proper owners list order and contents after insertions and deletions: 1: mount 1]=] ] = [=[
"[root]
▾ <Root>
▾ <Intermediate key=\"1\">
▾ <Wrapper>
<Leaf>"
]=]

exports[ [=[Store owners list should show the proper owners list order and contents after insertions and deletions: 2: components owned by <Root> 1]=] ] = [=[
" ▾ <Root>
▾ <Intermediate key=\"1\">
<Leaf>"
]=]

exports[ [=[Store owners list should show the proper owners list order and contents after insertions and deletions: 3: update to add direct 1]=] ] = [=[
"[root]
▾ <Root>
<Leaf key=\"1\">
▾ <Intermediate key=\"2\">
▾ <Wrapper>
<Leaf>"
]=]

exports[ [=[Store owners list should show the proper owners list order and contents after insertions and deletions: 4: components owned by <Root> 1]=] ] = [=[
" ▾ <Root>
<Leaf key=\"1\">
▾ <Intermediate key=\"2\">
<Leaf>"
]=]

exports[ [=[Store owners list should show the proper owners list order and contents after insertions and deletions: 5: update to remove indirect 1]=] ] = [=[
"[root]
▾ <Root>
<Leaf key=\"1\">"
]=]

exports[ [=[Store owners list should show the proper owners list order and contents after insertions and deletions: 6: components owned by <Root> 1]=] ] = [=[
" ▾ <Root>
<Leaf key=\"1\">"
]=]

exports[ [=[Store owners list should show the proper owners list order and contents after insertions and deletions: 7: update to remove both 1]=] ] = [=[
"[root]
<Root>"
]=]

exports[ [=[Store owners list should show the proper owners list order and contents after insertions and deletions: 8: components owned by <Root> 1]=] ] = [=[
" <Root>"]=]

exports[ [=[Store owners list should show the proper owners list ordering after reordered children: 1: mount (ascending) 1]=] ] = [=[
"[root]
▾ <Root>
<Leaf key=\"A\">
<Leaf key=\"B\">
<Leaf key=\"C\">"
]=]

exports[ [=[Store owners list should show the proper owners list ordering after reordered children: 2: components owned by <Root> 1]=] ] = [=[
" ▾ <Root>
<Leaf key=\"A\">
<Leaf key=\"B\">
<Leaf key=\"C\">"
]=]

exports[ [=[Store owners list should show the proper owners list ordering after reordered children: 3: update (descending) 1]=] ] = [=[
"[root]
▾ <Root>
<Leaf key=\"C\">
<Leaf key=\"B\">
<Leaf key=\"A\">"
]=]

exports[ [=[Store owners list should show the proper owners list ordering after reordered children: 4: components owned by <Root> 1]=] ] = [=[
" ▾ <Root>
<Leaf key=\"C\">
<Leaf key=\"B\">
<Leaf key=\"A\">"
]=]

return exports
9 changes: 5 additions & 4 deletions modules/react-devtools-shared/src/__tests__/console.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ return function()
registerRenderer = function(...) end,
}

-- ROBLOX deviation: require these as relative paths
local React = require(Packages.React)
-- ROBLOX deviation: use ReactRoblox instead of ReactDOM
local ReactRoblox = require(Packages.ReactRoblox)
local React
local ReactRoblox
local utils = require(script.Parent.utils)

describe("console", function()
Expand Down Expand Up @@ -79,6 +77,9 @@ return function()
Console.registerRenderer(internals)
end

React = require(Packages.React)
ReactRoblox = require(Packages.ReactRoblox)

act = utils.act
end)

Expand Down
Loading

0 comments on commit 7c78801

Please sign in to comment.