return function()local O=require(script.Parent.Parent.assertDeepEqual)local H=require(script.Parent.Parent.createElement)local p=require(script.Parent.Parent.createReconciler)local g=require(script.Parent.Parent.createSpy)local t=require(script.Parent.Parent.NoopRenderer)local Q=require(script.Parent.Parent.Type)local N=require(script.Parent.Parent.Component)local l=p(t)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 p=N:extend("\077\121\067\111\109\112\111\110\101\110\116")local t=g()p.willUpdate=t.value function p.render(O)return nil end local s={a=5}local P=H(p,s)local k=nil local L="\084\101\115\116"local B=l.mountVirtualNode(P,k,L)local f={a=6;b=2}local r=H(p,f)l.updateVirtualNode(B,r);(expect(t.callCount)).to.equal(1)local I=t:captureValues("\115\101\108\102","\110\101\119\080\114\111\112\115","\110\101\119\083\116\097\116\101");(expect(Q.of(I.self))).to.equal(Q.StatefulComponentInstance)O(I.newProps,f)O(I.newState,{})end)it("\105\116 \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 p=N:extend("\077\121\067\111\109\112\111\110\101\110\116")local t local s=g()p.willUpdate=s.value function p.init(O)t=function(H)O:setState(H)end O:setState({foo=1})end function p.render(O)return nil end local P=H(p)local k=nil local L="\084\101\115\116"l.mountVirtualNode(P,k,L);(expect(s.callCount)).to.equal(0)t({foo=2});(expect(s.callCount)).to.equal(1)local B=s:captureValues("\115\101\108\102","\110\101\119\080\114\111\112\115","\110\101\119\083\116\097\116\101");(expect(Q.of(B.self))).to.equal(Q.StatefulComponentInstance)O(B.newProps,{})O(B.newState,{foo=2})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 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 willUpdateSpy = createSpy()

		MyComponent.willUpdate = willUpdateSpy.value

		function MyComponent:render()
			return nil
		end

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

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

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

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

		local values = willUpdateSpy:captureValues("self", "newProps", "newState")

		expect(Type.of(values.self)).to.equal(Type.StatefulComponentInstance)
		assertDeepEqual(values.newProps, newProps)
		assertDeepEqual(values.newState, {})
	end)

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

		local willUpdateSpy = createSpy()

		MyComponent.willUpdate = willUpdateSpy.value

		function MyComponent:init()
			setComponentState = function(state)
				self:setState(state)
			end

			self:setState({
				foo = 1
			})
		end

		function MyComponent:render()
			return nil
		end

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

		noopReconciler.mountVirtualNode(initialElement, hostParent, key)

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

		setComponentState({
			foo = 2
		})

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

		local values = willUpdateSpy:captureValues("self", "newProps", "newState")

		expect(Type.of(values.self)).to.equal(Type.StatefulComponentInstance)
		assertDeepEqual(values.newProps, {})
		assertDeepEqual(values.newState, {
			foo = 2
		})
	end)
end