Skip to content

Commit 97ce2ee

Browse files
author
RoFlection Bot
committed
port cleanup, debug, end-to-end tests (#22), use test-id-tag (#28)
1 parent 1e8b68b commit 97ce2ee

File tree

9 files changed

+481
-7
lines changed

9 files changed

+481
-7
lines changed

rotriever.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ Scheduler = { git = "https://github.com/roblox/roact-alignment.git", package = "
1616
Shared = { git = "https://github.com/roblox/roact-alignment.git", package = "Shared" }
1717

1818
[dev_dependencies]
19-
JestGlobals = { git = "https://github.com/roblox/jest-roblox.git", rev="master" }
19+
JestGlobals = { git = "https://github.com/roblox/jest-roblox.git", rev="master" }
20+
LuauRegExp = "github.com/Roblox/luau-regexp@0.2.0"

src/__tests__/act.spec.lua

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ return function()
2828
return Promise.resolve()
2929
:andThen(function()
3030
local ref = React.createRef()
31-
render(React.createElement("Frame", { ref = ref }))
32-
ref.current:SetAttribute("data-testid", "foo")
31+
render(React.createElement("Frame", { ref = ref, [React.Tag] = "data-testid=foo" }))
3332
jestExpect(screen.findByTestId("foo"):expect()).toBe(ref.current)
3433
end)
3534
:expect()

src/__tests__/auto-cleanup-skip.spec.lua

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,22 @@ return function()
88
local document = require(Packages.DomTestingLibrary).document
99

1010
local React = require(Packages.React)
11-
local render
11+
local render, cleanup
1212
beforeAll(function()
1313
_G.RTL_SKIP_AUTO_CLEANUP = "true"
1414
local rtl = require(script.Parent.Parent)(afterEach)
1515
render = rtl.render
16+
-- ROBLOX deviation START: force cleanup
17+
cleanup = rtl.cleanup
18+
-- ROBLOX deviation END
19+
end)
20+
21+
-- ROBLOX deviation START: restore so it cleans up after this test
22+
afterAll(function()
23+
_G.RTL_SKIP_AUTO_CLEANUP = nil
24+
cleanup()
1625
end)
26+
-- ROBLOX deviation END
1727

1828
-- This one verifies that if RTL_SKIP_AUTO_CLEANUP is set
1929
-- then we DON'T auto-wire up the afterEach for folks
@@ -22,9 +32,6 @@ return function()
2232
end)
2333

2434
it("second", function()
25-
-- ROBLOX deviation START: restore so it cleans up after this test
26-
_G.RTL_SKIP_AUTO_CLEANUP = nil
27-
-- ROBLOX deviation END
2835
jestExpect(document:GetChildren()[1]:GetChildren()[1]:IsA("TextLabel")).toBe(true)
2936
jestExpect(document:GetChildren()[1]:GetChildren()[1].Text).toBe("hi")
3037
end)

src/__tests__/cleanup.spec.lua

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
-- ROBLOX upstream: https://github.com/testing-library/react-testing-library/blob/v12.1.5/src/__tests__/cleanup.js
2+
return function()
3+
local Packages = script.Parent.Parent.Parent
4+
5+
local JestGlobals = require(Packages.Dev.JestGlobals)
6+
local jestExpect = JestGlobals.expect
7+
local jest = JestGlobals.jest
8+
9+
local LuauPolyfill = require(Packages.LuauPolyfill)
10+
local console = LuauPolyfill.console
11+
local setTimeout = LuauPolyfill.setTimeout
12+
13+
local document = require(Packages.DomTestingLibrary).document
14+
local Promise = require(Packages.Promise)
15+
local getElementByName = require(script.Parent.Parent.jsHelpers.Element).getElementByName
16+
17+
local React = require(Packages.React)
18+
19+
local ParentModule = require(script.Parent.Parent)(afterEach)
20+
local render = ParentModule.render
21+
local cleanup = ParentModule.cleanup
22+
23+
it("cleans up the document", function()
24+
local spy = jest.fn()
25+
local divId = "my-div"
26+
27+
local Test = React.Component:extend("Test")
28+
29+
function Test:componentWillUnmount()
30+
jestExpect(getElementByName(document, divId)).toBeInTheDocument()
31+
spy()
32+
end
33+
34+
function Test:render()
35+
return React.createElement("Frame", { Name = divId })
36+
end
37+
38+
render(React.createElement(Test, nil))
39+
40+
cleanup()
41+
42+
jestExpect(document).toBeEmptyDOMElement()
43+
jestExpect(spy).toHaveBeenCalledTimes(1)
44+
end)
45+
46+
it("cleanup does not error when an element is not a child", function()
47+
render(React.createElement("Frame", nil), { container = Instance.new("Frame") })
48+
cleanup()
49+
end)
50+
51+
it("cleanup runs effect cleanup functions", function()
52+
local spy = jest.fn()
53+
54+
local function Test()
55+
React.useEffect(function()
56+
spy()
57+
end)
58+
return nil
59+
end
60+
61+
render(React.createElement(Test, nil))
62+
cleanup()
63+
jestExpect(spy).toHaveBeenCalledTimes(1)
64+
end)
65+
66+
describe("fake timers and missing act warnings", function()
67+
local originalConsoleError = console.error
68+
beforeEach(function()
69+
jest.resetAllMocks()
70+
-- ROBLOX deviation START: replace spyOn
71+
console.error = jest.fn(function()
72+
-- assert messages explicitly
73+
end)
74+
-- ROBLOX deviation END
75+
jest.useFakeTimers()
76+
end)
77+
78+
afterEach(function()
79+
-- ROBLOX deviation START: replace spyOn
80+
console.error = originalConsoleError
81+
-- ROBLOX deviation END
82+
jest.useRealTimers()
83+
end)
84+
85+
it("cleanup does not flush microtasks", function()
86+
local microTaskSpy = jest.fn()
87+
local function Test()
88+
local counter = 1
89+
local _, setDeferredCounter = React.useState(nil :: number?)
90+
React.useEffect(function()
91+
local cancelled = false
92+
-- ROBLOX deviation START: Lua Promise.resolve is not scheduled. Must use delay(0) for the same behavior
93+
Promise.delay(0):andThen(function()
94+
microTaskSpy()
95+
-- eslint-disable-next-line jest/no-if -- false positive
96+
if not cancelled then
97+
setDeferredCounter(counter)
98+
end
99+
end)
100+
101+
return function()
102+
cancelled = true
103+
end
104+
end, { counter })
105+
106+
return nil
107+
end
108+
render(React.createElement(Test, nil))
109+
110+
cleanup()
111+
112+
jestExpect(microTaskSpy).toHaveBeenCalledTimes(0)
113+
-- console.error is mocked
114+
-- eslint-disable-next-line no-console
115+
116+
-- ROBLOX deviation START: React.version not available, but will stick to React 17 for now
117+
jestExpect(console.error).toHaveBeenCalledTimes(
118+
-- ReactDOM.render is deprecated in React 18
119+
0
120+
)
121+
-- ROBLOX deviation END
122+
end)
123+
124+
it("cleanup does not swallow missing act warnings", function()
125+
local deferredStateUpdateSpy = jest.fn()
126+
local function Test()
127+
local counter = 1
128+
local _, setDeferredCounter = React.useState(nil :: number?)
129+
React.useEffect(function()
130+
local cancelled = false
131+
setTimeout(function()
132+
deferredStateUpdateSpy()
133+
if not cancelled then
134+
setDeferredCounter(counter)
135+
end
136+
end, 0)
137+
138+
return function()
139+
cancelled = true
140+
end
141+
end, { counter })
142+
143+
return nil
144+
end
145+
render(React.createElement(Test, nil))
146+
task.wait()
147+
148+
jest.runAllTimers()
149+
cleanup()
150+
151+
jestExpect(deferredStateUpdateSpy).toHaveBeenCalledTimes(1)
152+
-- console.error is mocked
153+
-- eslint-disable-next-line no-console
154+
-- ROBLOX deviation START: React.version not available, but will stick to React 17 for now
155+
jestExpect(console.error).toHaveBeenCalledTimes(
156+
-- ReactDOM.render is deprecated in React 18
157+
1
158+
)
159+
-- eslint-disable-next-line no-console
160+
jestExpect((console.error :: any).mock.calls[
161+
1 -- ReactDOM.render is deprecated in React 18
162+
][1]).toMatch("a test was not wrapped in act(...)")
163+
-- ROBLOX deviation END
164+
end)
165+
end)
166+
end

src/__tests__/debug.spec.lua

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
-- ROBLOX upstream: https://github.com/testing-library/react-testing-library/blob/v12.1.5/src/__tests__/debug.js
2+
return function()
3+
local Packages = script.Parent.Parent.Parent
4+
5+
local JestGlobals = require(Packages.Dev.JestGlobals)
6+
local jestExpect = JestGlobals.expect
7+
local jest = JestGlobals.jest
8+
9+
local LuauPolyfill = require(Packages.LuauPolyfill)
10+
local console = LuauPolyfill.console
11+
12+
local React = require(Packages.React)
13+
local ParentModule = require(script.Parent.Parent)(afterEach)
14+
local render = ParentModule.render
15+
local screen = ParentModule.screen
16+
17+
local originalConsoleLog = console.log
18+
beforeEach(function()
19+
-- ROBLOX deviation START: replace sypOn
20+
console.log = jest.fn(function() end)
21+
--ROBLOX deviation END
22+
end)
23+
afterEach(function()
24+
(console.log :: any):mockRestore()
25+
end)
26+
27+
-- ROBLOX deviation START: restore console log
28+
afterAll(function()
29+
console.log = originalConsoleLog
30+
end)
31+
-- ROBLOX deviation END
32+
33+
it("debug pretty prints the container", function()
34+
local function HelloWorld()
35+
return React.createElement("TextLabel", { Text = "Hello World" })
36+
end
37+
local debug_ = render(React.createElement(HelloWorld, nil)).debug
38+
debug_()
39+
jestExpect(console.log).toHaveBeenCalledTimes(1)
40+
jestExpect(console.log).toHaveBeenCalledWith(jestExpect.stringContaining("Hello World"))
41+
end)
42+
43+
it("debug pretty prints multiple containers", function()
44+
local function HelloWorld()
45+
local el1 =
46+
React.createElement("TextLabel", { [React.Tag] = "data-testid=testId", Text = "Hello World" }, nil)
47+
local el2 =
48+
React.createElement("TextLabel", { [React.Tag] = "data-testid=testId", Text = "Hello World" }, nil)
49+
50+
return React.createElement(React.Fragment, nil, el1, el2)
51+
end
52+
local debug_ = render(React.createElement(HelloWorld, nil)).debug
53+
local multipleElements = screen.getAllByTestId("testId")
54+
debug_(multipleElements)
55+
56+
jestExpect(console.log).toHaveBeenCalledTimes(2)
57+
jestExpect(console.log).toHaveBeenCalledWith(jestExpect.stringContaining("Hello World"))
58+
end)
59+
60+
it("allows same arguments as prettyDOM", function()
61+
local function HelloWorld()
62+
return React.createElement("TextLabel", { Text = "Hello World" })
63+
end
64+
local debug_, container
65+
do
66+
local ref = render(React.createElement(HelloWorld, nil))
67+
debug_, container = ref.debug, ref.container
68+
end
69+
debug_(container, 6, { highlight = false })
70+
71+
jestExpect(console.log).toHaveBeenCalledTimes(1)
72+
jestExpect((console.log :: any).mock.calls[1]).toEqual({ "Frame ..." })
73+
end)
74+
--[[
75+
eslint
76+
no-console: "off",
77+
testing-library/no-debug: "off",
78+
]]
79+
end

0 commit comments

Comments
 (0)