return function()local R=require(script.Parent.Parent.assertDeepEqual)local z=require(script.Parent.Parent.createElement)local J=require(script.Parent.Parent.createReconciler)local f=require(script.Parent.Parent.NoopRenderer)local Q=require(script.Parent.Parent.Component)local X=J(f)it("\115\104\111\117\108\100 \098\101 \112\114\111\118\105\100\101\100 \097\115 \097 \109\117\116\097\098\108\101 \115\101\108\102\046\095\099\111\110\116\101\120\116 \105\110 \067\111\109\112\111\110\101\110\116\058\105\110\105\116",function()local J=Q:extend("\080\114\111\118\105\100\101\114")function J.init(R)R._context.foo="\098\097\114"end function J.render(R) end local f=z(J)local O=nil local I="\080\114\111\118\105\100\101\114"local C=X.mountVirtualNode(f,O,I)local Y={foo="\098\097\114"}R(C.legacyContext,Y)end)it("\115\104\111\117\108\100 \098\101 \105\110\104\101\114\105\116\101\100 \102\114\111\109 \112\097\114\101\110\116 \115\116\097\116\101\102\117\108 \110\111\100\101\115",function()local J=Q:extend("\067\111\110\115\117\109\101\114")local f function J.init(R)f=R._context end function J.render(R) end local O=Q:extend("\080\097\114\101\110\116")function O.render(R)return z(J)end local I=z(O)local C=nil local Y="\080\097\114\101\110\116"local c={hello="\119\111\114\108\100",value=6}local U=X.mountVirtualNode(I,C,Y,nil,c);(expect(f)).never.to.equal(c);(expect(f)).never.to.equal(U.legacyContext)R(U.legacyContext,c)R(f,c)end)it("\115\104\111\117\108\100 \098\101 \105\110\104\101\114\105\116\101\100 \102\114\111\109 \112\097\114\101\110\116 \102\117\110\099\116\105\111\110 \110\111\100\101\115",function()local J=Q:extend("\067\111\110\115\117\109\101\114")local f function J.init(R)f=R._context end function J.render(R) end local function O()return z(J)end local I=z(O)local C=nil local Y="\080\097\114\101\110\116"local c={hello="\119\111\114\108\100",value=6}local U=X.mountVirtualNode(I,C,Y,nil,c);(expect(f)).never.to.equal(c);(expect(f)).never.to.equal(U.legacyContext)R(U.legacyContext,c)R(f,c)end)it("\115\104\111\117\108\100 \099\111\110\116\097\105\110 \118\097\108\117\101\115 \112\117\116 \105\110\116\111 \116\104\101 \116\114\101\101 \098\121 \112\097\114\101\110\116 \110\111\100\101\115",function()local J=Q:extend("\067\111\110\115\117\109\101\114")local f function J.init(R)f=R._context end function J.render(R) end local O=Q:extend("\080\114\111\118\105\100\101\114")function O.init(R)R._context.frob="\117\108\097\116\111\114"end function O.render(R)return z(J)end local I=z(O)local C=nil local Y="\067\111\110\115\117\109\101\114"local c={dont="\116\114\121 \105\116"}local U=X.mountVirtualNode(I,C,Y,nil,c)local A={dont="\116\114\121 \105\116"}local p={dont="\116\114\121 \105\116";frob="\117\108\097\116\111\114"};(expect(U.legacyContext)).never.to.equal(c);(expect(f)).never.to.equal(c);(expect(f)).never.to.equal(U.legacyContext)R(c,A)R(U.legacyContext,p)R(f,p)end)it("\115\104\111\117\108\100 \116\114\097\110\115\102\101\114 \099\111\110\116\101\120\116 \116\111 \099\104\105\108\100\114\101\110 \116\104\097\116 \097\114\101 \114\101\112\108\097\099\101\100",function()local J=Q:extend("\067\111\110\115\117\109\101\114\065")local f function J.init(R)R._context.A="\104\101\108\108\111"f=R._context end function J.render(R) end local O=Q:extend("\067\111\110\115\117\109\101\114\066")local I function O.init(R)R._context.B="\104\101\108\108\111"I=R._context end function O.render(R) end local C=Q:extend("\080\114\111\118\105\100\101\114")function C.init(R)R._context.frob="\117\108\097\116\111\114"end function C.render(R)local f=R.props.useConsumerB if f then return z(O)else return z(J)end end local Y=nil local c="\067\111\110\115\117\109\101\114"local U=z(C)local A=X.mountVirtualNode(U,Y,c)local p={frob="\117\108\097\116\111\114";A="\104\101\108\108\111"}R(f,p)local t={frob="\117\108\097\116\111\114",B="\104\101\108\108\111"}local g=z(C,{useConsumerB=true})X.updateVirtualNode(A,g)R(I,t)end)end
return function()
	local assertDeepEqual = require(script.Parent.Parent.assertDeepEqual)
	local createElement = require(script.Parent.Parent.createElement)
	local createReconciler = require(script.Parent.Parent.createReconciler)
	local NoopRenderer = require(script.Parent.Parent.NoopRenderer)

	local Component = require(script.Parent.Parent.Component)

	local noopReconciler = createReconciler(NoopRenderer)

	it("should be provided as a mutable self._context in Component:init", function()
		local Provider = Component:extend("Provider")

		function Provider:init()
			self._context.foo = "bar"
		end

		function Provider:render() end

		local element = createElement(Provider)
		local hostParent = nil
		local hostKey = "Provider"
		local node = noopReconciler.mountVirtualNode(element, hostParent, hostKey)

		local expectedContext = {
			foo = "bar",
		}

		assertDeepEqual(node.legacyContext, expectedContext)
	end)

	it("should be inherited from parent stateful nodes", function()
		local Consumer = Component:extend("Consumer")

		local capturedContext
		function Consumer:init()
			capturedContext = self._context
		end

		function Consumer:render() end

		local Parent = Component:extend("Parent")

		function Parent:render()
			return createElement(Consumer)
		end

		local element = createElement(Parent)
		local hostParent = nil
		local hostKey = "Parent"
		local context = {
			hello = "world",
			value = 6,
		}
		local node = noopReconciler.mountVirtualNode(element, hostParent, hostKey, nil, context)

		expect(capturedContext).never.to.equal(context)
		expect(capturedContext).never.to.equal(node.legacyContext)
		assertDeepEqual(node.legacyContext, context)
		assertDeepEqual(capturedContext, context)
	end)

	it("should be inherited from parent function nodes", function()
		local Consumer = Component:extend("Consumer")

		local capturedContext
		function Consumer:init()
			capturedContext = self._context
		end

		function Consumer:render() end

		local function Parent()
			return createElement(Consumer)
		end

		local element = createElement(Parent)
		local hostParent = nil
		local hostKey = "Parent"
		local context = {
			hello = "world",
			value = 6,
		}
		local node = noopReconciler.mountVirtualNode(element, hostParent, hostKey, nil, context)

		expect(capturedContext).never.to.equal(context)
		expect(capturedContext).never.to.equal(node.legacyContext)
		assertDeepEqual(node.legacyContext, context)
		assertDeepEqual(capturedContext, context)
	end)

	it("should contain values put into the tree by parent nodes", function()
		local Consumer = Component:extend("Consumer")

		local capturedContext
		function Consumer:init()
			capturedContext = self._context
		end

		function Consumer:render() end

		local Provider = Component:extend("Provider")

		function Provider:init()
			self._context.frob = "ulator"
		end

		function Provider:render()
			return createElement(Consumer)
		end

		local element = createElement(Provider)
		local hostParent = nil
		local hostKey = "Consumer"
		local context = {
			dont = "try it",
		}
		local node = noopReconciler.mountVirtualNode(element, hostParent, hostKey, nil, context)

		local initialContext = {
			dont = "try it",
		}

		local expectedContext = {
			dont = "try it",
			frob = "ulator",
		}

		-- Because components mutate context, we're careful with equality
		expect(node.legacyContext).never.to.equal(context)
		expect(capturedContext).never.to.equal(context)
		expect(capturedContext).never.to.equal(node.legacyContext)

		assertDeepEqual(context, initialContext)
		assertDeepEqual(node.legacyContext, expectedContext)
		assertDeepEqual(capturedContext, expectedContext)
	end)

	it("should transfer context to children that are replaced", function()
		local ConsumerA = Component:extend("ConsumerA")

		local capturedContextA
		function ConsumerA:init()
			self._context.A = "hello"

			capturedContextA = self._context
		end

		function ConsumerA:render() end

		local ConsumerB = Component:extend("ConsumerB")

		local capturedContextB
		function ConsumerB:init()
			self._context.B = "hello"

			capturedContextB = self._context
		end

		function ConsumerB:render() end

		local Provider = Component:extend("Provider")

		function Provider:init()
			self._context.frob = "ulator"
		end

		function Provider:render()
			local useConsumerB = self.props.useConsumerB

			if useConsumerB then
				return createElement(ConsumerB)
			else
				return createElement(ConsumerA)
			end
		end

		local hostParent = nil
		local hostKey = "Consumer"

		local element = createElement(Provider)
		local node = noopReconciler.mountVirtualNode(element, hostParent, hostKey)

		local expectedContextA = {
			frob = "ulator",
			A = "hello",
		}

		assertDeepEqual(capturedContextA, expectedContextA)

		local expectedContextB = {
			frob = "ulator",
			B = "hello",
		}

		local replacedElement = createElement(Provider, {
			useConsumerB = true,
		})
		noopReconciler.updateVirtualNode(node, replacedElement)

		assertDeepEqual(capturedContextB, expectedContextB)
	end)
end
