local d local i local F=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 k=F.jest local b=F.expect local a=F.describe local M=F.beforeEach local B=F.it a("\082\101\097\099\116\073\110\099\114\101\109\101\110\116\097\108\085\112\100\097\116\101\115\077\105\110\105\109\097\108\105\115\109",function()M(function()k.resetModules()d=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\101\097\099\116")i=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")end)B("\115\104\111\117\108\100 \114\101\110\100\101\114 \097 \115\105\109\112\108\101 \099\111\109\112\111\110\101\110\116",function()local function F()return d.createElement("\100\105\118",nil,"\072\101\108\108\111 \087\111\114\108\100")end local function k()return d.createElement(F)end i.render(d.createElement(k))local a=i.flushWithHostCounters();(b(a)).toEqual({hostDiffCounter=0,hostUpdateCounter=0})i.render(d.createElement(k));(b(i.flushWithHostCounters())).toEqual({hostDiffCounter=1,hostUpdateCounter=1})end)B("\115\104\111\117\108\100 \110\111\116 \100\105\102\102 \114\101\102\101\114\101\110\116\105\097\108\108\121 \101\113\117\097\108 \104\111\115\116 \101\108\101\109\101\110\116\115",function()local function F(i)return d.createElement("\115\112\097\110",nil,"\104\101\108\108\111",d.createElement("\098"),i.name)end local k=d.createElement("\100\105\118",nil,d.createElement(F,{name="\119\111\114\108\100"}))local function a()return k end local function M()return d.createElement(a)end i.render(d.createElement(M));(b(i.flushWithHostCounters())).toEqual({hostDiffCounter=0;hostUpdateCounter=0})i.render(d.createElement(M));(b(i.flushWithHostCounters())).toEqual({hostDiffCounter=0;hostUpdateCounter=0})end)B("\115\104\111\117\108\100 \110\111\116 \100\105\102\102 \112\097\114\101\110\116\115 \111\102 \115\101\116\083\116\097\116\101 \116\097\114\103\101\116\115",function()local F local function k(i)return d.createElement("\115\112\097\110",nil,"\104\101\108\108\111",d.createElement("\098"),i.name)end local a=d.Component:extend("\067\104\105\108\100")function a.init(d)d.state={name="\066\097\116\109\097\110"}end function a.render(i)F=i return d.createElement("\100\105\118",nil,d.createElement(k,{name=i.state.name}))end local function M()return d.createElement("\115\101\099\116\105\111\110",nil,d.createElement("\100\105\118",nil,d.createElement(k,{name="\119\111\114\108\100"}),d.createElement(a),d.createElement("\104\114"),d.createElement(k,{name="\119\111\114\108\100"})))end i.render(d.createElement(M));(b(i.flushWithHostCounters())).toEqual({hostDiffCounter=0,hostUpdateCounter=0})F:setState({name="\082\111\098\105\110"});(b(i.flushWithHostCounters())).toEqual({hostDiffCounter=3,hostUpdateCounter=4})i.render(d.createElement(M));(b(i.flushWithHostCounters())).toEqual({hostDiffCounter=10;hostUpdateCounter=10})end)end)
-- Upstream: https://github.com/facebook/react/blob/d13f5b9538e48f74f7c571ef3cde652ca887cca0/packages/react-reconciler/src/__tests__/ReactIncrementalUpdatesMinimalism-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
 --]]
--!strict
local React
local ReactNoop
local JestGlobals = require("@pkg/@jsdotlua/jest-globals")
local jest = JestGlobals.jest
local jestExpect = JestGlobals.expect
local describe = JestGlobals.describe
local beforeEach = JestGlobals.beforeEach
local it = JestGlobals.it

describe("ReactIncrementalUpdatesMinimalism", function()
	beforeEach(function()
		jest.resetModules()
		React = require("@pkg/@jsdotlua/react")
		ReactNoop = require("@pkg/@jsdotlua/react-noop-renderer")
	end)
	it("should render a simple component", function()
		local function Child()
			return React.createElement("div", nil, "Hello World")
		end
		local function Parent()
			return React.createElement(Child)
		end

		ReactNoop.render(React.createElement(Parent))
		local x = ReactNoop.flushWithHostCounters()
		jestExpect(x).toEqual({
			hostDiffCounter = 0,
			hostUpdateCounter = 0,
		})
		ReactNoop.render(React.createElement(Parent))
		jestExpect(ReactNoop.flushWithHostCounters()).toEqual({
			hostDiffCounter = 1,
			hostUpdateCounter = 1,
		})
	end)
	it("should not diff referentially equal host elements", function()
		local function Leaf(props)
			return React.createElement(
				"span",
				nil,
				"hello",
				React.createElement("b"),
				props.name
			)
		end

		local constEl = React.createElement(
			"div",
			nil,
			React.createElement(Leaf, {
				name = "world",
			})
		)

		local function Child()
			return constEl
		end
		local function Parent()
			return React.createElement(Child)
		end

		ReactNoop.render(React.createElement(Parent))
		jestExpect(ReactNoop.flushWithHostCounters()).toEqual({
			hostDiffCounter = 0,
			hostUpdateCounter = 0,
		})
		ReactNoop.render(React.createElement(Parent))
		jestExpect(ReactNoop.flushWithHostCounters()).toEqual({
			hostDiffCounter = 0,
			hostUpdateCounter = 0,
		})
	end)
	it("should not diff parents of setState targets", function()
		local childInst

		local function Leaf(props)
			return React.createElement(
				"span",
				nil,
				"hello",
				React.createElement("b"),
				props.name
			)
		end

		local Child = React.Component:extend("Child")
		function Child:init()
			self.state = { name = "Batman" }
		end
		function Child:render()
			childInst = self
			return React.createElement(
				"div",
				nil,
				React.createElement(Leaf, { name = self.state.name })
			)
		end

		local function Parent()
			return React.createElement(
				"section",
				nil,
				React.createElement(
					"div",
					nil,
					React.createElement(Leaf, {
						name = "world",
					}),
					React.createElement(Child),
					React.createElement("hr"),
					React.createElement(Leaf, {
						name = "world",
					})
				)
			)
		end

		ReactNoop.render(React.createElement(Parent))
		jestExpect(ReactNoop.flushWithHostCounters()).toEqual({
			hostDiffCounter = 0,
			hostUpdateCounter = 0,
		})
		childInst:setState({
			name = "Robin",
		})
		jestExpect(ReactNoop.flushWithHostCounters()).toEqual({
			-- Child > div
			-- Child > Leaf > span
			-- Child > Leaf > span > b
			hostDiffCounter = 3,
			-- Child > div
			-- Child > Leaf > span
			-- Child > Leaf > span > b
			-- Child > Leaf > span > #text
			hostUpdateCounter = 4,
		})
		ReactNoop.render(React.createElement(Parent))
		jestExpect(ReactNoop.flushWithHostCounters()).toEqual({
			-- Parent > section
			-- Parent > section > div
			-- Parent > section > div > Leaf > span
			-- Parent > section > div > Leaf > span > b
			-- Parent > section > div > Child > div
			-- Parent > section > div > Child > div > Leaf > span
			-- Parent > section > div > Child > div > Leaf > span > b
			-- Parent > section > div > hr
			-- Parent > section > div > Leaf > span
			-- Parent > section > div > Leaf > span > b
			hostDiffCounter = 10,
			hostUpdateCounter = 10,
		})
	end)
end)
