local x local s local F local z local W local M local S=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 p=S.beforeEach local r=S.expect local Q=S.describe local J=S.it local B=S.jest Q("\084\101\115\116\082\101\110\100\101\114\101\114 \084\097\103 \083\117\112\112\111\114\116",function()p(function()B.resetModules()x=require("\046\046\047\114\111\098\108\111\120\047\082\111\098\108\111\120\067\111\109\112\111\110\101\110\116\080\114\111\112\115")s=x.setInitialTags F=x.updateTags z=x.removeTags W=x.getInstancesForTag M=(require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\115\104\097\114\101\100")).Tag end)J("\115\104\111\117\108\100 \115\101\116 \105\110\105\116\105\097\108 \116\097\103\115 \102\111\114 \097\110 \105\110\115\116\097\110\099\101",function()local x="\114\111\111\116\067\111\110\116\097\105\110\101\114\049"local F={{props={[M]="\102\111\111"},rootContainerInstance=x};{props={[M]="\098\097\114"},rootContainerInstance=x},{props={[M]="\102\111\111\044\098\097\114"},rootContainerInstance=x};{props={[M]="\098\097\114"},rootContainerInstance=x}}for x,F in F do s(F,"\073\110\115\116\097\110\099\101",F.props,F.rootContainerInstance)end local z=W(x,"\102\111\111");(r(#z)).toEqual(2);(r(z)).toEqual({F[1];F[3]})local S=W(x,"\098\097\114");(r(#S)).toEqual(3);(r(S)).toEqual({F[2];F[3],F[4]})end)J("\115\104\111\117\108\100 \117\112\100\097\116\101 \116\097\103\115",function()local x="\114\111\111\116\067\111\110\116\097\105\110\101\114\049"local z={{props={[M]="\102\111\111"};rootContainerInstance=x},{props={[M]="\098\097\114"};rootContainerInstance=x},{props={[M]="\102\111\111\044\098\097\114"};rootContainerInstance=x};{props={[M]="\098\097\114"};rootContainerInstance=x}}for x,F in z do s(F,"\073\110\115\116\097\110\099\101",F.props,F.rootContainerInstance)end local S={{[M]="\102\111\111\044\098\097\114"};{[M]="\098\097\122"},{[M]="\098\097\122"},{[M]="\098\097\114"}}for x,s in z do F(s,S[x],s.props)end local p=W(x,"\102\111\111");(r(#p)).toEqual(1);(r(p)).toEqual({z[1]})local Q=W(x,"\098\097\114");(r(#Q)).toEqual(2);(r(Q)).toEqual({z[4],z[1]})local J=W(x,"\098\097\122");(r(#J)).toEqual(2);(r(J)).toEqual({z[2],z[3]})end)J("\115\104\111\117\108\100 \114\101\109\111\118\101 \116\097\103\115",function()local x="\114\111\111\116\067\111\110\116\097\105\110\101\114\049"local F={{props={[M]="\102\111\111"};rootContainerInstance=x},{props={[M]="\098\097\114"};rootContainerInstance=x};{props={[M]="\102\111\111\044\098\097\114"},rootContainerInstance=x};{props={[M]="\098\097\114"};rootContainerInstance=x}}for x,F in F do s(F,"\073\110\115\116\097\110\099\101",F.props,F.rootContainerInstance)end F[1].children={[2]=F[2];[3]=F[3]}z(F[1])local S=W(x,"\102\111\111");(r(#S)).toEqual(0)local p=W(x,"\098\097\114");(r(#p)).toEqual(1);(r(p)).toEqual({F[4]})end)end)
local RobloxComponentProps
local setInitialTags
local updateTags
local removeTags
local getInstancesForTag
local Tag

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("TestRenderer Tag Support", function()
	beforeEach(function()
		jest.resetModules()
		RobloxComponentProps = require("../roblox/RobloxComponentProps")
		setInitialTags = RobloxComponentProps.setInitialTags
		updateTags = RobloxComponentProps.updateTags
		removeTags = RobloxComponentProps.removeTags
		getInstancesForTag = RobloxComponentProps.getInstancesForTag
		Tag = require("@pkg/@jsdotlua/shared").Tag
	end)

	it("should set initial tags for an instance", function()
		local rootContainer = "rootContainer1"
		local hostInstances = {
			{
				props = { [Tag] = "foo" },
				rootContainerInstance = rootContainer,
			},
			{
				props = { [Tag] = "bar" },
				rootContainerInstance = rootContainer,
			},
			{
				props = { [Tag] = "foo,bar" },
				rootContainerInstance = rootContainer,
			},
			{
				props = { [Tag] = "bar" },
				rootContainerInstance = rootContainer,
			},
		}

		for _, inst in hostInstances do
			setInitialTags(inst, "Instance", inst.props, inst.rootContainerInstance)
		end

		local fooTags = getInstancesForTag(rootContainer, "foo")
		jestExpect(#fooTags).toEqual(2)
		jestExpect(fooTags).toEqual({
			hostInstances[1],
			hostInstances[3],
		})

		local barTags = getInstancesForTag(rootContainer, "bar")
		jestExpect(#barTags).toEqual(3)
		jestExpect(barTags).toEqual({
			hostInstances[2],
			hostInstances[3],
			hostInstances[4],
		})
	end)

	it("should update tags", function()
		local rootContainer = "rootContainer1"
		local hostInstances = {
			{
				props = { [Tag] = "foo" },
				rootContainerInstance = rootContainer,
			},
			{
				props = { [Tag] = "bar" },
				rootContainerInstance = rootContainer,
			},
			{
				props = { [Tag] = "foo,bar" },
				rootContainerInstance = rootContainer,
			},
			{
				props = { [Tag] = "bar" },
				rootContainerInstance = rootContainer,
			},
		}

		for _, inst in hostInstances do
			setInitialTags(inst, "Instance", inst.props, inst.rootContainerInstance)
		end

		local newProps = {
			{ [Tag] = "foo,bar" },
			{ [Tag] = "baz" },
			{ [Tag] = "baz" },
			{ [Tag] = "bar" },
		}

		for i, inst in hostInstances do
			updateTags(inst, newProps[i], inst.props)
		end

		local fooTags = getInstancesForTag(rootContainer, "foo")
		jestExpect(#fooTags).toEqual(1)
		jestExpect(fooTags).toEqual({
			hostInstances[1],
		})

		local barTags = getInstancesForTag(rootContainer, "bar")
		jestExpect(#barTags).toEqual(2)
		jestExpect(barTags).toEqual({
			hostInstances[4],
			hostInstances[1],
		})

		local bazTags = getInstancesForTag(rootContainer, "baz")
		jestExpect(#bazTags).toEqual(2)
		jestExpect(bazTags).toEqual({
			hostInstances[2],
			hostInstances[3],
		})
	end)

	it("should remove tags", function()
		local rootContainer = "rootContainer1"
		local hostInstances = {
			{
				props = { [Tag] = "foo" },
				rootContainerInstance = rootContainer,
			},
			{
				props = { [Tag] = "bar" },
				rootContainerInstance = rootContainer,
			},
			{
				props = { [Tag] = "foo,bar" },
				rootContainerInstance = rootContainer,
			},
			{
				props = { [Tag] = "bar" },
				rootContainerInstance = rootContainer,
			},
		}

		for _, inst in hostInstances do
			setInitialTags(inst, "Instance", inst.props, inst.rootContainerInstance)
		end

		-- Children should have tags removed as well
		hostInstances[1]["children"] = {
			[2] = hostInstances[2],
			[3] = hostInstances[3],
		}

		removeTags(hostInstances[1])

		local fooTags = getInstancesForTag(rootContainer, "foo")
		jestExpect(#fooTags).toEqual(0)

		local barTags = getInstancesForTag(rootContainer, "bar")
		jestExpect(#barTags).toEqual(1)
		jestExpect(barTags).toEqual({
			hostInstances[4],
		})
	end)
end)
