local I local B local Q local X=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\106\101\115\116-\103\108\111\098\097\108\115")local r=X.expect local u=X.beforeEach local i=X.it local O=X.jest u(function()O.resetModules()O.useFakeTimers()I=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\101\097\099\116")B=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\101\097\099\116-\110\111\111\112-\114\101\110\100\101\114\101\114")Q=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\115\099\104\101\100\117\108\101\114")end)local function C(B)Q.unstable_yieldValue(B.text)return I.createElement("\115\112\097\110",{prop=B.text})end i("\114\101\103\114\101\115\115\105\111\110\058 \115\101\116\083\116\097\116\101 \099\097\108\108\098\097\099\107 \040\050\110\100 \097\114\103\041 \115\104\111\117\108\100 \111\110\108\121 \102\105\114\101 \111\110\099\101\044 \101\118\101\110 \097\102\116\101\114 \097 \114\101\098\097\115\101",function()local X local u=I.Component:extend("\065\112\112")function u.init(I)I:setState({step=0})end function u.render(B)X=B return I.createElement(C,{text=B.state.step})end local i=B.createRoot()B.act(function()i.render(I.createElement(u))end);(r(Q)).toHaveYielded({0})B.act(function()X:setState({step=1},function()return Q.unstable_yieldValue("\067\097\108\108\098\097\099\107 \049")end)B.flushSync(function()X:setState({step=2},function()return Q.unstable_yieldValue("\067\097\108\108\098\097\099\107 \050")end)end)end);(r(Q)).toHaveYielded({2;"\067\097\108\108\098\097\099\107 \050";2,"\067\097\108\108\098\097\099\107 \049"})end)
-- ROBLOX upstream: https://github.com/facebook/react/blob/d7dce572c7453737a685e791e7afcbc7e2b2fe16/packages/react-reconciler/src/__tests__/ReactClassSetStateCallback-test.js
--[[*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @emails react-core
 * @jest-environment node
]]

--[[ eslint-disable no-func-assign ]]
local React

local ReactNoop
local Scheduler

local JestGlobals = require("@pkg/@jsdotlua/jest-globals")
local jestExpect = JestGlobals.expect
local beforeEach = JestGlobals.beforeEach
local it = JestGlobals.it
local jest = JestGlobals.jest

beforeEach(function()
	jest.resetModules()
	jest.useFakeTimers()

	React = require("@pkg/@jsdotlua/react")
	ReactNoop = require("@pkg/@jsdotlua/react-noop-renderer")
	Scheduler = require("@pkg/@jsdotlua/scheduler")
end)

local function Text(props)
	Scheduler.unstable_yieldValue(props.text)
	return React.createElement("span", {
		prop = props.text,
	})
end

it(
	"regression: setState callback (2nd arg) should only fire once, even after a rebase",
	function()
		local app
		local App = React.Component:extend("App")
		function App:init()
			self:setState({ step = 0 })
		end
		function App:render()
			app = self
			return React.createElement(Text, { text = self.state.step })
		end

		local root = ReactNoop.createRoot()
		ReactNoop.act(function()
			root.render(React.createElement(App))
		end)
		jestExpect(Scheduler).toHaveYielded({ 0 })

		ReactNoop.act(function()
			app:setState({ step = 1 }, function()
				return Scheduler.unstable_yieldValue("Callback 1")
			end)

			ReactNoop.flushSync(function()
				app:setState({ step = 2 }, function()
					return Scheduler.unstable_yieldValue("Callback 2")
				end)
			end)
		end)
		jestExpect(Scheduler).toHaveYielded({ 2, "Callback 2", 2, "Callback 1" })
	end
)
