return function()local u=require(script.Parent.Parent.Store)local q=require(script.Parent)it("\115\104\111\117\108\100 \098\101 \097 \102\117\110\099\116\105\111\110",function()(expect(q)).to.be.a("\102\117\110\099\116\105\111\110")end)it("\115\104\111\117\108\100 \100\105\115\112\097\116\099\104 \116\104\117\110\107\115",function()local function l(u,q)return u end local r=u.new(l,{},{q})local P=0 local function y(u)P=P+1 end r:dispatch(y);(expect(P)).to.equal(1)end)it("\115\104\111\117\108\100 \097\108\108\111\119 \110\111\114\109\097\108 \097\099\116\105\111\110\115 \116\111 \112\097\115\115 \116\104\114\111\117\103\104",function()local l=0 local function r(u,q)l=l+1 return u end local P=u.new(r,{},{q})P:dispatch({type="\116\101\115\116"});(expect(l)).to.equal(2)end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \118\097\108\117\101 \102\114\111\109 \116\104\101 \116\104\117\110\107",function()local function l(u,q)return u end local r=u.new(l,{},{q})local P="\116\101\115\116"local function y(u)return P end local T=r:dispatch(y);(expect(T)).to.equal(P)end)it("\115\104\111\117\108\100 \114\101\112\111\114\116 \101\114\114\111\114\115 \099\097\112\116\117\114\101\100 \105\110 \116\104\117\110\107\115 \118\105\097 \116\104\101 \112\114\111\118\105\100\101\100 \101\114\114\111\114 \114\101\112\111\114\116\101\114",function()local l,r,P local y={reportReducerError=function(u,q,y)l=u r=q P=y end}local function T(u,q)return u end local z=u.new(T,{Value=1},{q},y)local B="\116\104\117\110\107 \102\097\105\108\101\100"local function N(u)error(B)end z:dispatch(N);(expect(l.Value)).to.equal(1);(expect(r)).to.equal(N);(expect(P.message)).to.equal("\067\097\117\103\104\116 \101\114\114\111\114 \105\110 \116\104\117\110\107")end)it("\115\104\111\117\108\100 \114\101\099\111\118\101\114 \097\110\100 \099\111\110\116\105\110\117\101 \116\111 \117\112\100\097\116\101 \097\102\116\101\114 \097 \116\104\117\110\107 \101\114\114\111\114\115",function()local l local r={reportReducerError=function(u,q,r)l=r end}local function P(u,q)return u end local y=u.new(P,{Value=1},{q},r)local T="\116\104\117\110\107 \102\097\105\108\101\100"local function z(u)error(T)end local B=false local function N(u)B=true end y:dispatch(z);(expect(l.message)).to.equal("\067\097\117\103\104\116 \101\114\114\111\114 \105\110 \116\104\117\110\107")y:dispatch(N);(expect(B)).to.equal(true)end)end
return function()
	local Store = require(script.Parent.Parent.Store)

	local thunkMiddleware = require(script.Parent)

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

	it("should dispatch thunks", function()
		local function reducer(state, action)
			return state
		end

		local store = Store.new(reducer, {}, { thunkMiddleware })
		local thunkCount = 0

		local function thunk(_store)
			thunkCount = thunkCount + 1
		end

		store:dispatch(thunk)

		expect(thunkCount).to.equal(1)
	end)

	it("should allow normal actions to pass through", function()
		local reducerCount = 0

		local function reducer(state, action)
			reducerCount = reducerCount + 1
			return state
		end

		local store = Store.new(reducer, {}, { thunkMiddleware })

		store:dispatch({
			type = "test",
		})

		-- Reducer will be invoked twice:
		-- Once when creating the store (@@INIT action)
		-- Once when the test action is dispatched
		expect(reducerCount).to.equal(2)
	end)

	it("should return the value from the thunk", function()
		local function reducer(state, action)
			return state
		end

		local store = Store.new(reducer, {}, { thunkMiddleware })
		local thunkValue = "test"

		local function thunk(_store)
			return thunkValue
		end

		local result = store:dispatch(thunk)

		expect(result).to.equal(thunkValue)
	end)

	it("should report errors captured in thunks via the provided error reporter", function()
		local caughtState, caughtAction, caughtErrorResult
		local errorReporter = {
			reportReducerError = function(state, action, errorResult)
				caughtState = state
				caughtAction = action
				caughtErrorResult = errorResult
			end,
		}

		local function reducer(state, action)
			return state
		end

		local store = Store.new(reducer, {
			Value = 1,
		}, { thunkMiddleware }, errorReporter)

		local innerErrorMessage = "thunk failed"
		local function thunk(_store)
			error(innerErrorMessage)
		end

		store:dispatch(thunk)

		expect(caughtState.Value).to.equal(1)
		expect(caughtAction).to.equal(thunk)
		expect(caughtErrorResult.message).to.equal("Caught error in thunk")
	end)

	it("should recover and continue to update after a thunk errors", function()
		local caughtErrorResult
		local errorReporter = {
			reportReducerError = function(_state, _action, errorResult)
				caughtErrorResult = errorResult
			end,
		}

		local function reducer(state, action)
			return state
		end

		local store = Store.new(reducer, {
			Value = 1,
		}, { thunkMiddleware }, errorReporter)

		local innerErrorMessage = "thunk failed"
		local function errorThunk(_store)
			error(innerErrorMessage)
		end
		local ranSafeThunk = false
		local function safeThunk(_store)
			ranSafeThunk = true
		end

		store:dispatch(errorThunk)
		expect(caughtErrorResult.message).to.equal("Caught error in thunk")

		store:dispatch(safeThunk)
		expect(ranSafeThunk).to.equal(true)
	end)
end
