return function()local N=require(script.Parent.Parent.Parent.assertDeepEqual)local R=require(script.Parent.Parent.createElement)local z=require(script.Parent.Parent.createReconciler)local V=require(script.Parent.Parent.createSpy)local x=require(script.Parent.Parent.NoopRenderer)local b=require(script.Parent.Parent.Type)local q=require(script.Parent.Parent.Component)local K=z(x)it("\115\104\111\117\108\100 \098\101 \105\110\118\111\107\101\100 \119\104\101\110 \117\112\100\097\116\101\100 \118\105\097 \117\112\100\097\116\101\086\105\114\116\117\097\108\078\111\100\101",function()local z=q:extend("\077\121\067\111\109\112\111\110\101\110\116")local x=V()z.didUpdate=x.value function z.render(N)return nil end local w={a=5}local U=R(z,w)local l=nil local k="\084\101\115\116"local S=K.mountVirtualNode(U,l,k);(expect(x.callCount)).to.equal(0)local B={a=6;b=2}local y=R(z,B)K.updateVirtualNode(S,y);(expect(x.callCount)).to.equal(1)local X=x:captureValues("\115\101\108\102","\111\108\100\080\114\111\112\115","\111\108\100\083\116\097\116\101");(expect(b.of(X.self))).to.equal(b.StatefulComponentInstance)N(X.oldProps,w)N(X.oldState,{})end)it("\115\104\111\117\108\100 \098\101 \105\110\118\111\107\101\100 \119\104\101\110 \117\112\100\097\116\101\100 \118\105\097 \115\101\116\083\116\097\116\101",function()local z=q:extend("\077\121\067\111\109\112\111\110\101\110\116")local x=V()z.didUpdate=x.value local w={a=4}local U function z.init(N)U=function(...)return N:setState(...)end N:setState(w)end function z.render(N) end local l=R(z)local k=nil local S="\084\101\115\116"K.mountVirtualNode(l,k,S);(expect(x.callCount)).to.equal(0)U({a=5});(expect(x.callCount)).to.equal(1)local B=x:captureValues("\115\101\108\102","\111\108\100\080\114\111\112\115","\111\108\100\083\116\097\116\101");(expect(b.of(B.self))).to.equal(b.StatefulComponentInstance)N(B.oldProps,{})N(B.oldState,w)end)end
return function()
	local assertDeepEqual = require(script.Parent.Parent.Parent.assertDeepEqual)
	local createElement = require(script.Parent.Parent.createElement)
	local createReconciler = require(script.Parent.Parent.createReconciler)
	local createSpy = require(script.Parent.Parent.createSpy)
	local NoopRenderer = require(script.Parent.Parent.NoopRenderer)
	local Type = require(script.Parent.Parent.Type)

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

	local noopReconciler = createReconciler(NoopRenderer)

	it("should be invoked when updated via updateVirtualNode", function()
		local MyComponent = Component:extend("MyComponent")

		local didUpdateSpy = createSpy()
		MyComponent.didUpdate = didUpdateSpy.value

		function MyComponent:render()
			return nil
		end

		local initialProps = {
			a = 5,
		}
		local initialElement = createElement(MyComponent, initialProps)
		local hostParent = nil
		local key = "Test"

		local virtualNode = noopReconciler.mountVirtualNode(initialElement, hostParent, key)

		expect(didUpdateSpy.callCount).to.equal(0)

		local newProps = {
			a = 6,
			b = 2,
		}
		local newElement = createElement(MyComponent, newProps)
		noopReconciler.updateVirtualNode(virtualNode, newElement)

		expect(didUpdateSpy.callCount).to.equal(1)

		local values = didUpdateSpy:captureValues("self", "oldProps", "oldState")

		expect(Type.of(values.self)).to.equal(Type.StatefulComponentInstance)
		assertDeepEqual(values.oldProps, initialProps)
		assertDeepEqual(values.oldState, {})
	end)

	it("should be invoked when updated via setState", function()
		local MyComponent = Component:extend("MyComponent")

		local didUpdateSpy = createSpy()
		MyComponent.didUpdate = didUpdateSpy.value

		local initialState = {
			a = 4,
		}

		local setState
		function MyComponent:init()
			setState = function(...)
				return self:setState(...)
			end

			self:setState(initialState)
		end

		function MyComponent:render() end

		local element = createElement(MyComponent)
		local hostParent = nil
		local key = "Test"

		noopReconciler.mountVirtualNode(element, hostParent, key)

		expect(didUpdateSpy.callCount).to.equal(0)

		setState({
			a = 5,
		})

		expect(didUpdateSpy.callCount).to.equal(1)

		local values = didUpdateSpy:captureValues("self", "oldProps", "oldState")

		expect(Type.of(values.self)).to.equal(Type.StatefulComponentInstance)
		assertDeepEqual(values.oldProps, {})
		assertDeepEqual(values.oldState, initialState)
	end)
end
