local x local s 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 z=F.beforeEach local W=F.expect local M=F.describe local S=F.it local p=F.jest M("\082\101\097\099\116\084\101\115\116\082\101\110\100\101\114\101\114",function()z(function()p.resetModules()x=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\101\097\099\116")s=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\101\097\099\116-\116\101\115\116-\114\101\110\100\101\114\101\114")end)S("\114\101\110\100\101\114\115 \097 \099\111\109\112\111\110\101\110\116 \119\105\116\104 \082\101\097\099\116\046\067\104\097\110\103\101\044 \082\101\097\099\116\046\069\118\101\110\116\044 \082\101\097\099\116\046\084\097\103 \112\114\111\112\115",function()local F=function() end local z=function() end local function M()return x.createElement("\097",{role="\108\105\110\107",[x.Change.Text]=F,[x.Event.Activated]=z,[x.Tag]="\099\111\109\112\111\110\101\110\116\065"})end local S=s.create(x.createElement(M));(W(S.toJSON())).toEqual({type="\097";props={role="\108\105\110\107",[x.Change.Text]=F,[x.Event.Activated]=z,[x.Tag]="\099\111\109\112\111\110\101\110\116\065"},children=nil})end)S("\067\097\110 \100\114\105\118\101 \099\104\097\110\103\101 \097\110\100 \101\118\101\110\116 \115\105\103\110\097\108\115 \102\114\111\109 \097 \114\101\102",function()local F=x.createRef()local z=p.fn()local M=p.fn()local S=x.Component:extend("\082\111\111\116\067\111\109\112\111\110\101\110\116")function S.render(s)return x.createElement("\070\114\097\109\101",{},{B=x.createElement("\070\114\097\109\101",{ref=s.props.childRef,[x.Change.Text]=s.props.textCallback,[x.Event.Activated]=s.props.clickCallback})})end local r=s.create(x.createElement(S,{childRef=F,textCallback=z;clickCallback=M}),{createNodeMock=function(x)return x end})F.current.props[x.Change.Text]("\067\104\097\110\103\101\100 \084\101\120\116");(W(z)).toHaveBeenCalledWith("\067\104\097\110\103\101\100 \084\101\120\116")F.current.props[x.Event.Activated]()F.current.props[x.Event.Activated]();(W(M)).toHaveBeenCalledTimes(2)r.unmount();(W(F.current)).never.toBeDefined()end)S("\067\111\108\108\101\099\116\115 \116\097\103\103\101\100 \105\110\115\116\097\110\099\101\115",function()local F=s.create(x.createElement("\100\105\118",{Name="\065",[x.Tag]="\102\111\111",key="\065"},{B=x.createElement("\100\105\118",{[x.Tag]="\102\111\111"});C=x.createElement("\100\105\118",{[x.Tag]="\098\097\114\044\102\111\111"});D=x.createElement("\100\105\118",{[x.Tag]="\098\097\114\044\102\111\111"},{E=x.createElement("\100\105\118",{[x.Tag]="\098\097\114"})})}))local z=F.getInstancesForTag("\098\097\114");(W(#z)).toEqual(3)local M=F.getInstancesForTag("\102\111\111");(W(#M)).toEqual(4)local S=F.getInstancesForTag("\098\097\122");(W(#S)).toEqual(0)F.update(x.createElement("\100\105\118",{Name="\065";[x.Tag]="\102\111\111";key="\065"},{B=x.createElement("\100\105\118",{[x.Tag]="\098\097\114\044\098\097\122"}),C=x.createElement("\100\105\118",{[x.Tag]="\098\097\122"})}))M=F.getInstancesForTag("\102\111\111");(W(#M)).toEqual(1)z=F.getInstancesForTag("\098\097\114");(W(#z)).toEqual(1)S=F.getInstancesForTag("\098\097\122");(W(#S)).toEqual(2)F.unmount()M=F.getInstancesForTag("\102\111\111");(W(#M)).toEqual(0)z=F.getInstancesForTag("\098\097\114");(W(#z)).toEqual(0)S=F.getInstancesForTag("\098\097\122");(W(#S)).toEqual(0)end)end)
-- Upstream: https://github.com/facebook/react/blob/16654436039dd8f16a63928e71081c7745872e8f/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.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 ReactTestRenderer

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

describe("ReactTestRenderer", function()
	beforeEach(function()
		jest.resetModules()

		React = require("@pkg/@jsdotlua/react")
		ReactTestRenderer = require("@pkg/@jsdotlua/react-test-renderer")
	end)
	it("renders a component with React.Change, React.Event, React.Tag props", function()
		local onTextChangedCallback = function() end

		local onActivated = function() end

		local function Link()
			return React.createElement("a", {
				role = "link",
				[React.Change.Text] = onTextChangedCallback,
				[React.Event.Activated] = onActivated,
				[React.Tag] = "componentA",
			})
		end

		local renderer = ReactTestRenderer.create(React.createElement(Link))

		jestExpect(renderer.toJSON()).toEqual({
			type = "a",
			props = {
				role = "link",
				[React.Change.Text] = onTextChangedCallback,
				[React.Event.Activated] = onActivated,
				[React.Tag] = "componentA",
			},
			children = nil,
		})
	end)

	it("Can drive change and event signals from a ref", function()
		local ref = React.createRef()
		local textCallback = jest.fn()
		local clickCallback = jest.fn()

		local RootComponent = React.Component:extend("RootComponent")

		function RootComponent:render()
			return React.createElement("Frame", {}, {
				B = React.createElement("Frame", {
					ref = self.props.childRef,
					[React.Change.Text] = self.props.textCallback,
					[React.Event.Activated] = self.props.clickCallback,
				}),
			})
		end

		local renderer = ReactTestRenderer.create(
			React.createElement(RootComponent, {
				childRef = ref,
				textCallback = textCallback,
				clickCallback = clickCallback,
			}),
			{
				createNodeMock = function(element)
					return element
				end,
			}
		)

		ref.current.props[React.Change.Text]("Changed Text")
		jestExpect(textCallback).toHaveBeenCalledWith("Changed Text")

		ref.current.props[React.Event.Activated]()
		ref.current.props[React.Event.Activated]()
		jestExpect(clickCallback).toHaveBeenCalledTimes(2)

		renderer.unmount()
		jestExpect(ref.current).never.toBeDefined()
	end)

	it("Collects tagged instances", function()
		local renderer = ReactTestRenderer.create(React.createElement("div", {
			Name = "A",
			[React.Tag] = "foo",
			key = "A",
		}, {
			B = React.createElement("div", {
				[React.Tag] = "foo",
			}),
			C = React.createElement("div", {
				[React.Tag] = "bar,foo",
			}),
			D = React.createElement("div", {
				[React.Tag] = "bar,foo",
			}, {
				E = React.createElement("div", {
					[React.Tag] = "bar",
				}),
			}),
		}))

		local barInstances = renderer.getInstancesForTag("bar")
		jestExpect(#barInstances).toEqual(3)

		local fooInstances = renderer.getInstancesForTag("foo")
		jestExpect(#fooInstances).toEqual(4)

		local bazInstances = renderer.getInstancesForTag("baz")
		jestExpect(#bazInstances).toEqual(0)

		-- Should update tags when components update
		renderer.update(React.createElement("div", {
			Name = "A",
			[React.Tag] = "foo",
			key = "A",
		}, {
			B = React.createElement("div", {
				[React.Tag] = "bar,baz",
			}),
			C = React.createElement("div", {
				[React.Tag] = "baz",
			}),
		}))

		fooInstances = renderer.getInstancesForTag("foo")
		jestExpect(#fooInstances).toEqual(1)

		barInstances = renderer.getInstancesForTag("bar")
		jestExpect(#barInstances).toEqual(1)

		bazInstances = renderer.getInstancesForTag("baz")
		jestExpect(#bazInstances).toEqual(2)

		-- Should remove tags when unmounting
		renderer.unmount()
		fooInstances = renderer.getInstancesForTag("foo")
		jestExpect(#fooInstances).toEqual(0)

		barInstances = renderer.getInstancesForTag("bar")
		jestExpect(#barInstances).toEqual(0)

		bazInstances = renderer.getInstancesForTag("baz")
		jestExpect(#bazInstances).toEqual(0)
	end)
end)
