return function()local u=require(script.Parent)it("\115\104\111\117\108\100 \098\101 \097 \102\117\110\099\116\105\111\110",function()(expect(u)).to.be.a("\102\117\110\099\116\105\111\110")end)it("\115\104\111\117\108\100 \104\097\110\100\108\101 \097\099\116\105\111\110\115",function()local q=u({a=0;b=0},{a=function(u,q)return{a=u.a+1;b=u.b}end;b=function(u,q)return{a=u.a,b=u.b+2}end})local l=q({a=0,b=0},{type="\097"});(expect(l.a)).to.equal(1)l=q(l,{type="\098"});(expect(l.b)).to.equal(2)end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \105\110\105\116\105\097\108 \115\116\097\116\101 \105\102 \116\104\101 \115\116\097\116\101 \105\115 \110\105\108",function()local q=u({a=0;b=0},{})local l=q(nil,{});(expect(l)).to.be.ok();(expect(l.a)).to.equal(0);(expect(l.b)).to.equal(0)end)it("\115\104\111\117\108\100 \115\116\105\108\108 \114\117\110 \097\099\116\105\111\110 \104\097\110\100\108\101\114\115 \105\102 \116\104\101 \115\116\097\116\101 \105\115 \110\105\108",function()local q=0 local l=u(0,{foo=function(u,l)q=q+1 return nil end});(expect(q)).to.equal(0)local r=l(nil,{type="\102\111\111"});(expect(q)).to.equal(1);(expect(r)).to.equal(nil)r=l(r,{type="\102\111\111"});(expect(q)).to.equal(2);(expect(r)).to.equal(nil)end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \115\097\109\101 \115\116\097\116\101 \105\102 \116\104\101 \097\099\116\105\111\110 \105\115 \110\111\116 \104\097\110\100\108\101\100",function()local q={a=0,b=0}local l=u(q,{a=function(u,q)return{a=u.a+1,b=u.b}end;b=function(u,q)return{a=u.a,b=u.b+2}end})local r=l(q,{type="\099"});(expect(r)).to.equal(q)end)end
return function()
	local createReducer = require(script.Parent)

	it("should be a function", function()
		expect(createReducer).to.be.a("function")
	end)

	it("should handle actions", function()
		local reducer = createReducer({
			a = 0,
			b = 0,
		}, {
			a = function(state, action)
				return {
					a = state.a + 1,
					b = state.b,
				}
			end,
			b = function(state, action)
				return {
					a = state.a,
					b = state.b + 2,
				}
			end,
		})

		local newState = reducer({
			a = 0,
			b = 0,
		}, {
			type = "a",
		})

		expect(newState.a).to.equal(1)

		newState = reducer(newState, {
			type = "b",
		})

		expect(newState.b).to.equal(2)
	end)

	it("should return the initial state if the state is nil", function()
		local reducer = createReducer({
			a = 0,
			b = 0,
			-- We don't care about the actions here
		}, {})

		local newState = reducer(nil, {})
		expect(newState).to.be.ok()
		expect(newState.a).to.equal(0)
		expect(newState.b).to.equal(0)
	end)

	it("should still run action handlers if the state is nil", function()
		local callCount = 0

		local reducer = createReducer(0, {
			foo = function(state, action)
				callCount = callCount + 1
				return nil
			end,
		})

		expect(callCount).to.equal(0)

		local newState = reducer(nil, {
			type = "foo",
		})

		expect(callCount).to.equal(1)
		expect(newState).to.equal(nil)

		newState = reducer(newState, {
			type = "foo",
		})

		expect(callCount).to.equal(2)
		expect(newState).to.equal(nil)
	end)

	it("should return the same state if the action is not handled", function()
		local initialState = {
			a = 0,
			b = 0,
		}

		local reducer = createReducer(initialState, {
			a = function(state, action)
				return {
					a = state.a + 1,
					b = state.b,
				}
			end,
			b = function(state, action)
				return {
					a = state.a,
					b = state.b + 2,
				}
			end,
		})

		local newState = reducer(initialState, {
			type = "c",
		})

		expect(newState).to.equal(initialState)
	end)
end
