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 s=x.afterEach local F=x.beforeEach local z=x.expect local W=x.describe local M=x.it local S=x.jest local p local r local Q F(function()Q=_G.__COMPAT_WARNINGS__ _G.__COMPAT_WARNINGS__=false end)s(function()_G.__COMPAT_WARNINGS__=Q end)W("\067\111\110\099\117\114\114\101\110\116 \114\111\111\116 \040\100\101\102\097\117\108\116 \098\101\104\097\118\105\111\114\041",function()local x,W F(function()x=_G.__ROACT_17_INLINE_ACT__ W=_G.__ROACT_17_MOCK_SCHEDULER__ _G.__ROACT_17_INLINE_ACT__=true _G.__ROACT_17_MOCK_SCHEDULER__=true S.resetModules()p=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\111\097\099\116")r=require("\046\046")end)s(function()_G.__ROACT_17_INLINE_ACT__=x _G.__ROACT_17_MOCK_SCHEDULER__=W end)M("\115\104\111\117\108\100 \099\114\101\097\116\101 \097\110 \111\114\112\104\097\110\101\100 \105\110\115\116\097\110\099\101 \116\111 \109\111\117\110\116 \117\110\100\101\114 \105\102 \110\111\110\101 \105\115 \112\114\111\118\105\100\101\100",function()local x=r.createRef()local s=r.mount(r.createElement("\070\114\097\109\101",{ref=x}));(z(x.current)).never.toBeNil();(z(x.current.Parent)).never.toBeNil();(z(x.current.Parent.ClassName)).toBe("\070\111\108\100\101\114");(z(x.current.Name)).toBe("\082\101\097\099\116\082\111\111\116")r.unmount(s)end)M("\115\104\111\117\108\100 \110\097\109\101 \099\104\105\108\100\114\101\110 \117\115\105\110\103 \116\104\101 \107\101\121",function()local x=Instance.new("\070\111\108\100\101\114")local s=p.mount(p.createElement("\070\114\097\109\101"),x,"\083\097\109\101\078\097\109\101\084\114\101\101")local F=Instance.new("\070\111\108\100\101\114")local W=r.mount(r.createElement("\070\114\097\109\101"),F,"\083\097\109\101\078\097\109\101\084\114\101\101")local M=x:FindFirstChildWhichIsA("\070\114\097\109\101");(z(M)).never.toBeNil()local S=F:FindFirstChildWhichIsA("\070\114\097\109\101");(z(S)).never.toBeNil();(z(M.Name)).toEqual(S.Name);(z(S.Name)).toBe("\083\097\109\101\078\097\109\101\084\114\101\101")p.unmount(s)r.unmount(W)end)M("\107\101\101\112\115 \116\104\101 \115\097\109\101 \114\111\111\116 \110\097\109\101 \111\110 \117\112\100\097\116\101",function()local x=Instance.new("\070\111\108\100\101\114")local s=p.mount(p.createElement("\070\114\097\109\101"),x,"\083\097\109\101\078\097\109\101\084\114\101\101")local F=Instance.new("\070\111\108\100\101\114")local W=r.mount(r.createElement("\070\114\097\109\101"),F,"\083\097\109\101\078\097\109\101\084\114\101\101")local M=x:FindFirstChildWhichIsA("\070\114\097\109\101");(z(M.Name)).toBe("\083\097\109\101\078\097\109\101\084\114\101\101")local S=F:FindFirstChildWhichIsA("\070\114\097\109\101");(z(S.Name)).toBe("\083\097\109\101\078\097\109\101\084\114\101\101")p.update(s,p.createElement("\084\101\120\116\076\097\098\101\108"))r.update(W,r.createElement("\084\101\120\116\076\097\098\101\108"))M=x:FindFirstChildWhichIsA("\084\101\120\116\076\097\098\101\108");(z(M.Name)).toBe("\083\097\109\101\078\097\109\101\084\114\101\101")S=F:FindFirstChildWhichIsA("\084\101\120\116\076\097\098\101\108");(z(S.Name)).toBe("\083\097\109\101\078\097\109\101\084\114\101\101")p.unmount(s)r.unmount(W)end)M("\115\104\111\117\108\100 \110\111\116 \099\108\101\097\114 \111\117\116 \111\116\104\101\114 \099\104\105\108\100\114\101\110 \111\102 \116\104\101 \116\097\114\103\101\116",function()local x=Instance.new("\070\111\108\100\101\114")local s=Instance.new("\070\114\097\109\101")s.Name="\080\114\101\101\120\105\115\116\105\110\103\067\104\105\108\100"s.Parent=x local F=r.mount(r.createElement("\084\101\120\116\076\097\098\101\108"),x,"\082\111\097\099\116\084\114\101\101")local W=x:FindFirstChildWhichIsA("\084\101\120\116\076\097\098\101\108");(z(W.Name)).toBe("\082\111\097\099\116\084\114\101\101")local M=x:FindFirstChildWhichIsA("\070\114\097\109\101");(z(M.Name)).toBe("\080\114\101\101\120\105\115\116\105\110\103\067\104\105\108\100")r.unmount(F)end)end)W("\076\101\103\097\099\121 \114\111\111\116",function()local x F(function()x=_G.__ROACT_17_COMPAT_LEGACY_ROOT__ _G.__ROACT_17_COMPAT_LEGACY_ROOT__=true S.resetModules()p=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\111\097\099\116")r=require("\046\046")end)s(function()_G.__ROACT_17_COMPAT_LEGACY_ROOT__=x end)M("\115\104\111\117\108\100 \099\114\101\097\116\101 \097\110 \111\114\112\104\097\110\101\100 \105\110\115\116\097\110\099\101 \116\111 \109\111\117\110\116 \117\110\100\101\114 \105\102 \110\111\110\101 \105\115 \112\114\111\118\105\100\101\100",function()local x=r.createRef()local s=r.mount(r.createElement("\070\114\097\109\101",{ref=x}));(z(x.current)).never.toBeNil();(z(x.current.Parent)).never.toBeNil();(z(x.current.Parent.ClassName)).toBe("\070\111\108\100\101\114");(z(x.current.Name)).toBe("\082\101\097\099\116\076\101\103\097\099\121\082\111\111\116")r.unmount(s)end)end)
--[[
	* Copyright (c) Roblox Corporation. All rights reserved.
	* Licensed under the MIT License (the "License");
	* you may not use this file except in compliance with the License.
	* You may obtain a copy of the License at
	*
	*     https://opensource.org/licenses/MIT
	*
	* Unless required by applicable law or agreed to in writing, software
	* distributed under the License is distributed on an "AS IS" BASIS,
	* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	* See the License for the specific language governing permissions and
	* limitations under the License.
]]

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

local prevCompatWarnings
beforeEach(function()
	prevCompatWarnings = _G.__COMPAT_WARNINGS__
	-- Silence warnings; we're intersted in functionality in these tests
	_G.__COMPAT_WARNINGS__ = false
end)

afterEach(function()
	_G.__COMPAT_WARNINGS__ = prevCompatWarnings
end)

describe("Concurrent root (default behavior)", function()
	local prevInlineAct, prevMockScheduler
	beforeEach(function()
		prevInlineAct = _G.__ROACT_17_INLINE_ACT__
		prevMockScheduler = _G.__ROACT_17_MOCK_SCHEDULER__
		_G.__ROACT_17_INLINE_ACT__ = true
		_G.__ROACT_17_MOCK_SCHEDULER__ = true
		jest.resetModules()
		Roact = require("@pkg/@jsdotlua/roact")
		RoactCompat = require("..")
	end)

	afterEach(function()
		_G.__ROACT_17_INLINE_ACT__ = prevInlineAct
		_G.__ROACT_17_MOCK_SCHEDULER__ = prevMockScheduler
	end)

	it("should create an orphaned instance to mount under if none is provided", function()
		local ref = RoactCompat.createRef()
		local tree = RoactCompat.mount(RoactCompat.createElement("Frame", { ref = ref }))

		jestExpect(ref.current).never.toBeNil()
		jestExpect(ref.current.Parent).never.toBeNil()
		jestExpect(ref.current.Parent.ClassName).toBe("Folder")

		jestExpect(ref.current.Name).toBe("ReactRoot")

		RoactCompat.unmount(tree)
	end)

	it("should name children using the key", function()
		local legacyTarget = Instance.new("Folder")
		local legacyTree =
			Roact.mount(Roact.createElement("Frame"), legacyTarget, "SameNameTree")

		local compatTarget = Instance.new("Folder")
		local compatTree = RoactCompat.mount(
			RoactCompat.createElement("Frame"),
			compatTarget,
			"SameNameTree"
		)

		local legacyRootInstance = legacyTarget:FindFirstChildWhichIsA("Frame")
		jestExpect(legacyRootInstance).never.toBeNil()
		local compatRootInstance = compatTarget:FindFirstChildWhichIsA("Frame")
		jestExpect(compatRootInstance).never.toBeNil()

		jestExpect(legacyRootInstance.Name).toEqual(compatRootInstance.Name)
		jestExpect(compatRootInstance.Name).toBe("SameNameTree")

		Roact.unmount(legacyTree)
		RoactCompat.unmount(compatTree)
	end)

	it("keeps the same root name on update", function()
		local legacyTarget = Instance.new("Folder")
		local legacyTree =
			Roact.mount(Roact.createElement("Frame"), legacyTarget, "SameNameTree")

		local compatTarget = Instance.new("Folder")
		local compatTree = RoactCompat.mount(
			RoactCompat.createElement("Frame"),
			compatTarget,
			"SameNameTree"
		)

		local legacyRootInstance = legacyTarget:FindFirstChildWhichIsA("Frame")
		jestExpect(legacyRootInstance.Name).toBe("SameNameTree")
		local compatRootInstance = compatTarget:FindFirstChildWhichIsA("Frame")
		jestExpect(compatRootInstance.Name).toBe("SameNameTree")

		Roact.update(legacyTree, Roact.createElement("TextLabel"))
		RoactCompat.update(compatTree, RoactCompat.createElement("TextLabel"))

		legacyRootInstance = legacyTarget:FindFirstChildWhichIsA("TextLabel")
		jestExpect(legacyRootInstance.Name).toBe("SameNameTree")
		compatRootInstance = compatTarget:FindFirstChildWhichIsA("TextLabel")
		jestExpect(compatRootInstance.Name).toBe("SameNameTree")

		Roact.unmount(legacyTree)
		RoactCompat.unmount(compatTree)
	end)

	it("should not clear out other children of the target", function()
		local compatTarget = Instance.new("Folder")

		local preexistingChild = Instance.new("Frame")
		preexistingChild.Name = "PreexistingChild"
		preexistingChild.Parent = compatTarget

		local compatTree = RoactCompat.mount(
			RoactCompat.createElement("TextLabel"),
			compatTarget,
			"RoactTree"
		)

		local compatRootInstance = compatTarget:FindFirstChildWhichIsA("TextLabel")
		jestExpect(compatRootInstance.Name).toBe("RoactTree")

		local existingChild = compatTarget:FindFirstChildWhichIsA("Frame")
		jestExpect(existingChild.Name).toBe("PreexistingChild")

		RoactCompat.unmount(compatTree)
	end)
end)

describe("Legacy root", function()
	local previousGlobalValue
	beforeEach(function()
		previousGlobalValue = _G.__ROACT_17_COMPAT_LEGACY_ROOT__
		_G.__ROACT_17_COMPAT_LEGACY_ROOT__ = true
		jest.resetModules()
		Roact = require("@pkg/@jsdotlua/roact")
		RoactCompat = require("..")
	end)

	afterEach(function()
		_G.__ROACT_17_COMPAT_LEGACY_ROOT__ = previousGlobalValue
	end)

	it("should create an orphaned instance to mount under if none is provided", function()
		local ref = RoactCompat.createRef()
		local tree = RoactCompat.mount(RoactCompat.createElement("Frame", { ref = ref }))

		jestExpect(ref.current).never.toBeNil()
		jestExpect(ref.current.Parent).never.toBeNil()
		jestExpect(ref.current.Parent.ClassName).toBe("Folder")

		jestExpect(ref.current.Name).toBe("ReactLegacyRoot")

		RoactCompat.unmount(tree)
	end)
end)
