local e local k local p local f local S=game:GetService("\067\111\108\108\101\099\116\105\111\110\083\101\114\118\105\099\101")local A=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 M=A.expect local O=A.jest local X=require("\046\047\119\097\105\116\070\111\114\069\118\101\110\116\115")local o=A.beforeEach local L=A.afterEach local r=A.it local q=A.describe o(function()O.resetModules()e=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\101\097\099\116")k=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\101\097\099\116-\114\111\098\108\111\120")p=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")f=(require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\114\101\097\099\116")).Tag end)q("\097\100\100\105\110\103 \116\097\103\115",function()local A,q local K,h local a,F o(function()local e,p=O.fn()local f,M=O.fn()a=(S:GetInstanceAddedSignal("\116\097\103\049")):Connect(p)F=(S:GetInstanceAddedSignal("\116\097\103\050")):Connect(M)K=e h=f q=Instance.new("\070\111\108\100\101\114")q.Parent=game:GetService("\087\111\114\107\115\112\097\099\101")A=k.createRoot(q)end)L(function()a:Disconnect()F:Disconnect()A:unmount()q:Destroy()end)r("\115\104\111\117\108\100 \097\100\100 \097 \115\105\110\103\108\101 \116\097\103",function()local k=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k,[f]="\116\097\103\049"}))p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledWith(k.current);(M(S:GetTagged("\116\097\103\049"))).toEqual({k.current})end)r("\115\104\111\117\108\100 \097\100\100 \115\101\118\101\114\097\108 \116\097\103\115",function()local k=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]="\116\097\103\049 \116\097\103\050"}))p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledWith(k.current);(M(h)).toHaveBeenCalledWith(k.current);(M(S:GetTagged("\116\097\103\049"))).toEqual({k.current});(M(S:GetTagged("\116\097\103\050"))).toEqual({k.current})end)r("\115\104\111\117\108\100 \097\100\100 \116\097\103\115 \116\111 \115\101\118\101\114\097\108 \099\104\105\108\100\114\101\110",function()local k,O=e.createRef(),e.createRef()A:render(e.createElement("\070\114\097\109\101",nil,e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k,[f]="\116\097\103\049"}),e.createElement("\084\101\120\116\066\111\120",{ref=O,[f]="\116\097\103\049"})))p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledWith(k.current);(M(K)).toHaveBeenCalledWith(O.current)local o=S:GetTagged("\116\097\103\049");(M(o)).toHaveLength(2);(M(o)).toContain(k.current);(M(o)).toContain(O.current)end)r("\115\104\111\117\108\100 \097\100\100 \110\111 \116\097\103\115 \119\104\101\110 \103\105\118\101\110 \097\110 \101\109\112\116\121 \115\116\114\105\110\103",function()local k=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]=""}))p.unstable_flushAllWithoutAsserting()X();(M(S:GetTags(k.current))).toEqual({})end)r("\115\104\111\117\108\100 \110\111\116 \099\104\097\110\103\101 \116\097\103\115 \116\104\097\116 \097\114\101 \114\101-\111\114\100\101\114\101\100",function()local k=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]="\116\097\103\049 \116\097\103\050"}))p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledTimes(1);(M(h)).toHaveBeenCalledTimes(1)A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]="\116\097\103\050 \116\097\103\049"}))p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledTimes(1);(M(h)).toHaveBeenCalledTimes(1)end)end)q("\114\101\109\111\118\105\110\103 \116\097\103\115",function()local A,q local K,h local a,F o(function()local e,p=O.fn()local f,M=O.fn()a=(S:GetInstanceRemovedSignal("\116\097\103\049")):Connect(p)F=(S:GetInstanceRemovedSignal("\116\097\103\050")):Connect(M)K=e h=f q=Instance.new("\070\111\108\100\101\114")q.Parent=game:GetService("\087\111\114\107\115\112\097\099\101")A=k.createRoot(q)end)L(function()a:Disconnect()F:Disconnect()A:unmount()q:Destroy()end)r("\115\104\111\117\108\100 \114\101\109\111\118\101 \097 \116\097\103 \119\104\101\110 \117\112\100\097\116\101\100",function()local k=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]="\116\097\103\049"}))p.unstable_flushAllWithoutAsserting()X();(M(S:GetTagged("\116\097\103\049"))).toEqual({k.current})A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k}))p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledWith(k.current);(M(S:GetTagged("\116\097\103\049"))).toEqual({})end)r("\115\104\111\117\108\100 \114\101\109\111\118\101 \111\110\101 \116\097\103 \105\110 \097 \108\105\115\116 \119\104\101\110 \117\112\100\097\116\101\100",function()local k=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]="\116\097\103\049 \116\097\103\050"}))p.unstable_flushAllWithoutAsserting()X();(M(S:GetTagged("\116\097\103\049"))).toEqual({k.current});(M(S:GetTagged("\116\097\103\050"))).toEqual({k.current})A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]="\116\097\103\050"}))p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledWith(k.current);(M(h)).never.toHaveBeenCalled();(M(S:GetTagged("\116\097\103\049"))).toEqual({});(M(S:GetTagged("\116\097\103\050"))).toEqual({k.current})end)r("\115\104\111\117\108\100 \114\101\109\111\118\101 \115\101\118\101\114\097\108 \116\097\103\115 \119\104\101\110 \117\112\100\097\116\101\100",function()local k=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k,[f]="\116\097\103\049 \116\097\103\050"}))p.unstable_flushAllWithoutAsserting()X();(M(S:GetTagged("\116\097\103\049"))).toEqual({k.current});(M(S:GetTagged("\116\097\103\050"))).toEqual({k.current})A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k}))p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledWith(k.current);(M(h)).toHaveBeenCalledWith(k.current);(M(S:GetTagged("\116\097\103\049"))).toEqual({});(M(S:GetTagged("\116\097\103\050"))).toEqual({})end)r("\115\104\111\117\108\100 \114\101\109\111\118\101 \116\097\103\115 \111\110 \117\110\109\111\117\110\116",function()local k=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]="\116\097\103\049 \116\097\103\050"}))p.unstable_flushAllWithoutAsserting()X();(M(S:GetTagged("\116\097\103\049"))).toEqual({k.current});(M(S:GetTagged("\116\097\103\050"))).toEqual({k.current})A:render(nil)p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledTimes(1);(M(h)).toHaveBeenCalledTimes(1);(M(S:GetTagged("\116\097\103\049"))).toEqual({});(M(S:GetTagged("\116\097\103\050"))).toEqual({})end)r("\115\104\111\117\108\100 \114\101\109\111\118\101 \116\097\103\115 \119\104\101\110 \112\114\111\118\105\100\101\100 \097\110 \101\109\112\116\121 \116\097\103 \115\116\114\105\110\103",function()local k=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]="\116\097\103\049 \116\097\103\050"}))p.unstable_flushAllWithoutAsserting()X();(M(S:GetTagged("\116\097\103\049"))).toEqual({k.current});(M(S:GetTagged("\116\097\103\050"))).toEqual({k.current})A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{ref=k;[f]=""}))p.unstable_flushAllWithoutAsserting()X();(M(K)).toHaveBeenCalledTimes(1);(M(h)).toHaveBeenCalledTimes(1);(M(S:GetTagged("\116\097\103\049"))).toEqual({});(M(S:GetTagged("\116\097\103\050"))).toEqual({})end)end)r("\115\104\111\117\108\100 \119\097\114\110 \119\104\101\110 \097\115\115\105\103\110\105\110\103 \116\097\103\115 \119\105\116\104 \097\110 \105\110\099\111\114\114\101\099\116 \116\121\112\101",function()local S=Instance.new("\070\111\108\100\101\114")S.Parent=game:GetService("\087\111\114\107\115\112\097\099\101")local A=k.createRoot(S)local O=e.createRef()A:render(e.createElement("\084\101\120\116\076\097\098\101\108",{key="\077\121 \076\097\098\101\108";ref=O,[f]=42}));(M(function()p.unstable_flushAllWithoutAsserting()X()end)).toErrorDev("\087\097\114\110\105\110\103\058 \084\121\112\101 \112\114\111\118\105\100\101\100 \102\111\114 \082\101\097\099\116\082\111\098\108\111\120\046\084\097\103 \105\115 \105\110\118\097\108\105\100 - \116\097\103\115 \115\104\111\117\108\100 \098\101 \115\112\101\099\105\102\105\101\100 \097\115 \097 \115\105\110\103\108\101 \115\116\114\105\110\103\044 \119\105\116\104 \105\110\100\105\118\105\100\117\097\108 \116\097\103\115 \100\101\108\105\109\105\116\101\100 \098\121 \115\112\097\099\101\115\046 \073\110\115\116\101\097\100 \114\101\099\101\105\118\101\100\058\n\052\050")end)r("\115\104\111\117\108\100 \119\097\114\110 \119\104\101\110 \097\115\115\105\103\110\105\110\103 \116\097\103\115 \116\111 \117\110\114\111\111\116\101\100 \105\110\115\116\097\110\099\101\115",function()local A=Instance.new("\070\111\108\100\101\114")local O=k.createRoot(A)local o=e.createRef()O:render(e.createElement("\084\101\120\116\076\097\098\101\108",{key="\077\121 \076\097\098\101\108",ref=o;[f]="\116\097\103\049"}));(M(function()p.unstable_flushAllWithoutAsserting()X()end)).toWarnDev("\087\097\114\110\105\110\103\058 \084\097\103\115 \097\112\112\108\105\101\100 \116\111 \111\114\112\104\097\110\101\100 \084\101\120\116\076\097\098\101\108 \"\077\121 \076\097\098\101\108\" \099\097\110\110\111\116 \098\101 \097\099\099\101\115\115\101\100 \118\105\097 \067\111\108\108\101\099\116\105\111\110\083\101\114\118\105\099\101\058\071\101\116\084\097\103\103\101\100\046 \073\102 \121\111\117\'\114\101 \114\101\108\121\105\110\103 \111\110 \116\097\103 \098\101\104\097\118\105\111\114 \105\110 \097 \117\110\105\116 \116\101\115\116\044 \099\111\110\115\105\100\101\114 \109\111\117\110\116\105\110\103 \121\111\117\114 \116\101\115\116 \114\111\111\116 \105\110\116\111 \116\104\101 \068\097\116\097\077\111\100\101\108\046");(M(S:GetTags(o.current))).toEqual({"\116\097\103\049"});(M(S:GetTagged("\116\097\103\049"))).toEqual({})end)
--!strict
--[[
	* 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 React
local ReactRoblox
local Scheduler
local Tag

local CollectionService = game:GetService("CollectionService")

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

beforeEach(function()
	jest.resetModules()
	React = require("@pkg/@jsdotlua/react")
	ReactRoblox = require("@pkg/@jsdotlua/react-roblox")
	Scheduler = require("@pkg/@jsdotlua/scheduler")
	Tag = require("@pkg/@jsdotlua/react").Tag
end)

describe("adding tags", function()
	local root, parent
	local tag1AddedMock, tag2AddedMock
	local tag1AddedConnection, tag2AddedConnection
	beforeEach(function()
		local tag1Mock, tag1Fn = jest.fn()
		local tag2Mock, tag2Fn = jest.fn()
		tag1AddedConnection = CollectionService:GetInstanceAddedSignal("tag1")
			:Connect(tag1Fn)
		tag2AddedConnection = CollectionService:GetInstanceAddedSignal("tag2")
			:Connect(tag2Fn)

		tag1AddedMock = tag1Mock
		tag2AddedMock = tag2Mock

		parent = Instance.new("Folder")
		parent.Parent = game:GetService("Workspace")
		root = ReactRoblox.createRoot(parent)
	end)

	afterEach(function()
		tag1AddedConnection:Disconnect()
		tag2AddedConnection:Disconnect()

		root:unmount()
		parent:Destroy()
	end)

	it("should add a single tag", function()
		local ref = React.createRef()
		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag1",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1AddedMock).toHaveBeenCalledWith(ref.current)
		jestExpect(CollectionService:GetTagged("tag1")).toEqual({ ref.current })
	end)

	it("should add several tags", function()
		local ref = React.createRef()
		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag1 tag2",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1AddedMock).toHaveBeenCalledWith(ref.current)
		jestExpect(tag2AddedMock).toHaveBeenCalledWith(ref.current)
		jestExpect(CollectionService:GetTagged("tag1")).toEqual({ ref.current })
		jestExpect(CollectionService:GetTagged("tag2")).toEqual({ ref.current })
	end)

	it("should add tags to several children", function()
		local textLabelRef, textBoxRef = React.createRef(), React.createRef()
		root:render(React.createElement(
			"Frame",
			nil,
			React.createElement("TextLabel", {
				ref = textLabelRef,
				[Tag] = "tag1",
			}),
			React.createElement("TextBox", {
				ref = textBoxRef,
				[Tag] = "tag1",
			})
		))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1AddedMock).toHaveBeenCalledWith(textLabelRef.current)
		jestExpect(tag1AddedMock).toHaveBeenCalledWith(textBoxRef.current)

		-- We don't have any guarantees about order from the engine, so we
		-- just check that both instances are present
		local tags = CollectionService:GetTagged("tag1")
		jestExpect(tags).toHaveLength(2)
		jestExpect(tags).toContain(textLabelRef.current)
		jestExpect(tags).toContain(textBoxRef.current)
	end)

	it("should add no tags when given an empty string", function()
		local ref = React.createRef()
		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(CollectionService:GetTags(ref.current)).toEqual({})
	end)

	it("should not change tags that are re-ordered", function()
		local ref = React.createRef()
		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag1 tag2",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1AddedMock).toHaveBeenCalledTimes(1)
		jestExpect(tag2AddedMock).toHaveBeenCalledTimes(1)

		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag2 tag1",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1AddedMock).toHaveBeenCalledTimes(1)
		jestExpect(tag2AddedMock).toHaveBeenCalledTimes(1)
	end)
end)

describe("removing tags", function()
	local root, parent
	local tag1RemovedMock, tag2RemovedMock
	local tag1RemovedConnection, tag2RemovedConnection

	beforeEach(function()
		local tag1Mock, tag1Fn = jest.fn()
		local tag2Mock, tag2Fn = jest.fn()
		tag1RemovedConnection = CollectionService:GetInstanceRemovedSignal("tag1")
			:Connect(tag1Fn)
		tag2RemovedConnection = CollectionService:GetInstanceRemovedSignal("tag2")
			:Connect(tag2Fn)

		tag1RemovedMock = tag1Mock
		tag2RemovedMock = tag2Mock

		parent = Instance.new("Folder")
		parent.Parent = game:GetService("Workspace")
		root = ReactRoblox.createRoot(parent)
	end)

	afterEach(function()
		tag1RemovedConnection:Disconnect()
		tag2RemovedConnection:Disconnect()

		root:unmount()
		parent:Destroy()
	end)

	it("should remove a tag when updated", function()
		local ref = React.createRef()
		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag1",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(CollectionService:GetTagged("tag1")).toEqual({ ref.current })
		root:render(React.createElement("TextLabel", {
			ref = ref,
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1RemovedMock).toHaveBeenCalledWith(ref.current)
		jestExpect(CollectionService:GetTagged("tag1")).toEqual({})
	end)

	it("should remove one tag in a list when updated", function()
		local ref = React.createRef()
		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag1 tag2",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(CollectionService:GetTagged("tag1")).toEqual({ ref.current })
		jestExpect(CollectionService:GetTagged("tag2")).toEqual({ ref.current })

		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag2",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1RemovedMock).toHaveBeenCalledWith(ref.current)
		jestExpect(tag2RemovedMock).never.toHaveBeenCalled()
		jestExpect(CollectionService:GetTagged("tag1")).toEqual({})
		jestExpect(CollectionService:GetTagged("tag2")).toEqual({ ref.current })
	end)

	it("should remove several tags when updated", function()
		local ref = React.createRef()
		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag1 tag2",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(CollectionService:GetTagged("tag1")).toEqual({ ref.current })
		jestExpect(CollectionService:GetTagged("tag2")).toEqual({ ref.current })

		root:render(React.createElement("TextLabel", {
			ref = ref,
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1RemovedMock).toHaveBeenCalledWith(ref.current)
		jestExpect(tag2RemovedMock).toHaveBeenCalledWith(ref.current)
		jestExpect(CollectionService:GetTagged("tag1")).toEqual({})
		jestExpect(CollectionService:GetTagged("tag2")).toEqual({})
	end)

	it("should remove tags on unmount", function()
		local ref = React.createRef()
		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag1 tag2",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(CollectionService:GetTagged("tag1")).toEqual({ ref.current })
		jestExpect(CollectionService:GetTagged("tag2")).toEqual({ ref.current })

		root:render(nil)
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1RemovedMock).toHaveBeenCalledTimes(1)
		jestExpect(tag2RemovedMock).toHaveBeenCalledTimes(1)
		jestExpect(CollectionService:GetTagged("tag1")).toEqual({})
		jestExpect(CollectionService:GetTagged("tag2")).toEqual({})
	end)

	it("should remove tags when provided an empty tag string", function()
		local ref = React.createRef()
		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "tag1 tag2",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(CollectionService:GetTagged("tag1")).toEqual({ ref.current })
		jestExpect(CollectionService:GetTagged("tag2")).toEqual({ ref.current })

		root:render(React.createElement("TextLabel", {
			ref = ref,
			[Tag] = "",
		}))
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()

		jestExpect(tag1RemovedMock).toHaveBeenCalledTimes(1)
		jestExpect(tag2RemovedMock).toHaveBeenCalledTimes(1)
		jestExpect(CollectionService:GetTagged("tag1")).toEqual({})
		jestExpect(CollectionService:GetTagged("tag2")).toEqual({})
	end)
end)

it("should warn when assigning tags with an incorrect type", function()
	local parent = Instance.new("Folder")
	parent.Parent = game:GetService("Workspace")
	local root = ReactRoblox.createRoot(parent)
	local ref = React.createRef()
	root:render(React.createElement("TextLabel", {
		key = "My Label",
		ref = ref,
		[Tag] = 42,
	}))
	jestExpect(function()
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()
	end).toErrorDev(
		"Warning: Type provided for ReactRoblox.Tag is invalid - tags "
			.. "should be specified as a single string, with "
			.. "individual tags delimited by spaces. Instead received:"
			.. "\n42"
	)
end)

it("should warn when assigning tags to unrooted instances", function()
	local parent = Instance.new("Folder")
	local orphanedRoot = ReactRoblox.createRoot(parent)
	local ref = React.createRef()
	orphanedRoot:render(React.createElement("TextLabel", {
		key = "My Label",
		ref = ref,
		[Tag] = "tag1",
	}))
	jestExpect(function()
		Scheduler.unstable_flushAllWithoutAsserting()
		waitForEvents()
	end).toWarnDev(
		'Warning: Tags applied to orphaned TextLabel "My Label" cannot'
			.. " be accessed via CollectionService:GetTagged. If you're relying"
			.. " on tag behavior in a unit test, consider mounting your test"
			.. " root into the DataModel."
	)

	-- Despite the warning, the tag should belong to the instance's set of
	-- tags retrieved via `GetTags`
	jestExpect(CollectionService:GetTags(ref.current)).toEqual({ "tag1" })
	-- However, we expect `GetTagged` for the tag itself to be empty; it
	-- only gets populated when the orphaned root is added to the DataModel
	jestExpect(CollectionService:GetTagged("tag1")).toEqual({})
end)
