return function()local I=require(script.Parent.Store)local G=require(script.Parent.thunkMiddleware)local j=require(script.Parent.makeThunkMiddleware)it("\115\104\111\117\108\100 \100\105\115\112\097\116\099\104 \116\104\117\110\107\115",function()local function j(I,G)return I end local x=I.new(j,{},{G})local h=0 local function s(I)h=h+1 end x:dispatch(s);(expect(h)).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 j=0 local function x(I,G)j=j+1 return I end local h=I.new(x,{},{G})h:dispatch({type="\116\101\115\116"});(expect(j)).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 j(I,G)return I end local x=I.new(j,{},{G})local h="\116\101\115\116"local function s(I)return h end local H=x:dispatch(s);(expect(H)).to.equal(h)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 j,x,h local s={reportReducerError=function(I,G,s)j=I x=G h=s end}local function H(I,G)return I end local B=I.new(H,{Value=1},{G},s)local W="\116\104\117\110\107 \102\097\105\108\101\100"local function M(I)error(W)end B:dispatch(M);(expect(j.Value)).to.equal(1);(expect(x)).to.equal(M);(expect(h.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 j local x={reportReducerError=function(I,G,x)j=x end}local function h(I,G)return I end local s=I.new(h,{Value=1},{G},x)local H="\116\104\117\110\107 \102\097\105\108\101\100"local function B(I)error(H)end local W=false local function M(I)W=true end s:dispatch(B);(expect(j.message)).to.equal("\067\097\117\103\104\116 \101\114\114\111\114 \105\110 \116\104\117\110\107")s:dispatch(M);(expect(W)).to.equal(true)end)it("\115\104\111\117\108\100 \115\101\110\100 \101\120\116\114\097 \097\114\103\117\109\101\110\116 \116\111 \116\104\117\110\107\115 \119\104\101\110 \112\114\111\118\105\100\101\100",function()local function G(I,G)return I end local x={What="\077\121\069\120\116\114\097\065\114\103"}local h=I.new(G,{},{j(x)})local s=0 local H=nil local function B(I,G)s=s+1 H=G end h:dispatch(B);(expect(s)).to.equal(1);(expect(H)).to.equal(x)end)end
return function()
	local Store = require(script.Parent.Store)
	local thunkMiddleware = require(script.Parent.thunkMiddleware)
	local makeThunkMiddleware = require(script.Parent.makeThunkMiddleware)

	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)

	it("should send extra argument to thunks when provided", function()
		local function reducer(state, action)
			return state
		end

		local myExtraArg = { What = "MyExtraArg" }
		local store = Store.new(reducer, {}, { makeThunkMiddleware(myExtraArg) })
		local thunkCount = 0
		local extraArgParam = nil

		local function thunk(_store, extraArg)
			thunkCount = thunkCount + 1
			extraArgParam = extraArg
		end

		store:dispatch(thunk)

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