local B=(require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\108\117\097\117-\112\111\108\121\102\105\108\108")).Error local P=require("\064\112\107\103\047\064\106\115\100\111\116\108\117\097\047\106\101\115\116-\103\108\111\098\097\108\115")local Y=P.describe local z=P.it local H=P.beforeEach local q=P.expect local t=P.jest Y("\101\118\101\110\116\115",function()local P H(function()t.resetModules()local B=require("\046\046\047\101\118\101\110\116\115")P=B.new()end)z("\099\097\110 \100\105\115\112\097\116\099\104 \097\110 \101\118\101\110\116 \119\105\116\104 \110\111 \108\105\115\116\101\110\101\114\115",function()P:emit("\101\118\101\110\116",123)end)z("\104\097\110\100\108\101\115 \097 \108\105\115\116\101\110\101\114 \098\101\105\110\103 \097\116\116\097\099\104\101\100 \109\117\108\116\105\112\108\101 \116\105\109\101\115",function()local B=t.fn()P:addListener("\101\118\101\110\116",B)P:addListener("\101\118\101\110\116",B)P:emit("\101\118\101\110\116",123);(q(B)).toHaveBeenCalledTimes(1);(q(B)).toHaveBeenCalledWith(123)end)z("\110\111\116\105\102\105\101\115 \097\108\108 \097\116\116\097\099\104\101\100 \108\105\115\116\101\110\101\114\115 \111\102 \101\118\101\110\116\115",function()local B=t.fn()local Y=t.fn()local z=t.fn()P:addListener("\101\118\101\110\116",B)P:addListener("\101\118\101\110\116",Y)P:addListener("\111\116\104\101\114-\101\118\101\110\116",z)P:emit("\101\118\101\110\116",123);(q(B)).toHaveBeenCalledTimes(1);(q(B)).toHaveBeenCalledWith(123);(q(Y)).toHaveBeenCalledTimes(1);(q(Y)).toHaveBeenCalledWith(123);(q(z)).never.toHaveBeenCalled()end)z("\099\097\108\108\115 \108\097\116\101\114 \108\105\115\116\101\110\101\114\115 \098\101\102\111\114\101 \114\101-\116\104\114\111\119\105\110\103 \105\102 \097\110 \101\097\114\108\105\101\114 \111\110\101 \116\104\114\111\119\115",function()local Y=t.fn(function()error(B.new("\101\120\112\101\099\116\101\100"))end)local z=t.fn()P:addListener("\101\118\101\110\116",Y)P:addListener("\101\118\101\110\116",z);(q(function()P:emit("\101\118\101\110\116",123)end)).toThrow("\101\120\112\101\099\116\101\100");(q(Y)).toHaveBeenCalledTimes(1);(q(Y)).toHaveBeenCalledWith(123);(q(z)).toHaveBeenCalledTimes(1);(q(z)).toHaveBeenCalledWith(123)end)z("\114\101\109\111\118\101\115 \097\116\116\097\099\104\101\100 \108\105\115\116\101\110\101\114\115",function()local B=t.fn()local Y=t.fn()P:addListener("\101\118\101\110\116",B)P:addListener("\111\116\104\101\114-\101\118\101\110\116",Y)P:removeListener("\101\118\101\110\116",B)P:emit("\101\118\101\110\116",123);(q(B)).never.toHaveBeenCalled()P:emit("\111\116\104\101\114-\101\118\101\110\116",123);(q(Y)).toHaveBeenCalledTimes(1);(q(Y)).toHaveBeenCalledWith(123)end)z("\114\101\109\111\118\101\115 \097\108\108 \108\105\115\116\101\110\101\114\115",function()local B=t.fn()local Y=t.fn()local z=t.fn()P:addListener("\101\118\101\110\116",B)P:addListener("\101\118\101\110\116",Y)P:addListener("\111\116\104\101\114-\101\118\101\110\116",z)P:removeAllListeners()P:emit("\101\118\101\110\116",123)P:emit("\111\116\104\101\114-\101\118\101\110\116",123);(q(B)).never.toHaveBeenCalled();(q(Y)).never.toHaveBeenCalled();(q(z)).never.toHaveBeenCalled()end)z("\115\104\111\117\108\100 \099\097\108\108 \116\104\101 \105\110\105\116\105\097\108 \108\105\115\116\101\110\101\114\115 \101\118\101\110 \105\102 \111\116\104\101\114\115 \097\114\101 \097\100\100\101\100 \111\114 \114\101\109\111\118\101\100 \100\117\114\105\110\103 \097 \100\105\115\112\097\116\099\104",function()local B,Y local z=t.fn(function()P:removeListener("\101\118\101\110\116",B)P:addListener("\101\118\101\110\116",Y)end)B=t.fn()Y=t.fn()P:addListener("\101\118\101\110\116",z)P:addListener("\101\118\101\110\116",B)P:emit("\101\118\101\110\116",123);(q(z)).toHaveBeenCalledTimes(1);(q(z)).toHaveBeenCalledWith(123);(q(B)).toHaveBeenCalledTimes(1);(q(B)).toHaveBeenCalledWith(123);(q(Y)).never.toHaveBeenCalled()P:emit("\101\118\101\110\116",456);(q(z)).toHaveBeenCalledTimes(2);(q(z)).toHaveBeenCalledWith(456);(q(B)).toHaveBeenCalledTimes(1);(q(Y)).toHaveBeenCalledTimes(1);(q(Y)).toHaveBeenCalledWith(456)end)end)
-- ROBLOX upstream: https://github.com/facebook/react/blob/v17.0.1/packages/react-devtools-shared/src/__tests__/events-test.js
-- /**
--  * Copyright (c) Facebook, Inc. and its affiliates.
--  *
--  * This source code is licensed under the MIT license found in the
--  *
--  * LICENSE file in the root directory of this source tree.
--  * @flow
--  */

local Error = require("@pkg/@jsdotlua/luau-polyfill").Error
local JestGlobals = require("@pkg/@jsdotlua/jest-globals")
local describe = JestGlobals.describe
local it = JestGlobals.it
local beforeEach = JestGlobals.beforeEach
local jestExpect = JestGlobals.expect
local jest = JestGlobals.jest

describe("events", function()
	local dispatcher
	beforeEach(function()
		jest.resetModules()
		local EventEmitter = require("../events")
		dispatcher = EventEmitter.new()
	end)

	it("can dispatch an event with no listeners", function()
		dispatcher:emit("event", 123)
	end)

	it("handles a listener being attached multiple times", function()
		local callback = jest.fn()
		dispatcher:addListener("event", callback)
		dispatcher:addListener("event", callback)
		dispatcher:emit("event", 123)
		jestExpect(callback).toHaveBeenCalledTimes(1)
		jestExpect(callback).toHaveBeenCalledWith(123)
	end)

	it("notifies all attached listeners of events", function()
		local callback1 = jest.fn()
		local callback2 = jest.fn()
		local callback3 = jest.fn()
		dispatcher:addListener("event", callback1)
		dispatcher:addListener("event", callback2)
		dispatcher:addListener("other-event", callback3)
		dispatcher:emit("event", 123)
		jestExpect(callback1).toHaveBeenCalledTimes(1)
		jestExpect(callback1).toHaveBeenCalledWith(123)
		jestExpect(callback2).toHaveBeenCalledTimes(1)
		jestExpect(callback2).toHaveBeenCalledWith(123)
		jestExpect(callback3).never.toHaveBeenCalled()
	end)

	it("calls later listeners before re-throwing if an earlier one throws", function()
		local callbackThatThrows = jest.fn(function()
			error(Error.new("expected"))
		end)
		local callback = jest.fn()
		dispatcher:addListener("event", callbackThatThrows)
		dispatcher:addListener("event", callback)
		jestExpect(function()
			dispatcher:emit("event", 123)
		end).toThrow("expected")
		jestExpect(callbackThatThrows).toHaveBeenCalledTimes(1)
		jestExpect(callbackThatThrows).toHaveBeenCalledWith(123)
		jestExpect(callback).toHaveBeenCalledTimes(1)
		jestExpect(callback).toHaveBeenCalledWith(123)
	end)

	it("removes attached listeners", function()
		local callback1 = jest.fn()
		local callback2 = jest.fn()
		dispatcher:addListener("event", callback1)
		dispatcher:addListener("other-event", callback2)
		dispatcher:removeListener("event", callback1)
		dispatcher:emit("event", 123)
		jestExpect(callback1).never.toHaveBeenCalled()
		dispatcher:emit("other-event", 123)
		jestExpect(callback2).toHaveBeenCalledTimes(1)
		jestExpect(callback2).toHaveBeenCalledWith(123)
	end)

	it("removes all listeners", function()
		local callback1 = jest.fn()
		local callback2 = jest.fn()
		local callback3 = jest.fn()
		dispatcher:addListener("event", callback1)
		dispatcher:addListener("event", callback2)
		dispatcher:addListener("other-event", callback3)
		dispatcher:removeAllListeners()
		dispatcher:emit("event", 123)
		dispatcher:emit("other-event", 123)
		jestExpect(callback1).never.toHaveBeenCalled()
		jestExpect(callback2).never.toHaveBeenCalled()
		jestExpect(callback3).never.toHaveBeenCalled()
	end)

	it(
		"should call the initial listeners even if others are added or removed during a dispatch",
		function()
			local callback2, callback3
			local callback1 = jest.fn(function()
				dispatcher:removeListener("event", callback2)
				dispatcher:addListener("event", callback3)
			end)
			callback2 = jest.fn()
			callback3 = jest.fn()
			dispatcher:addListener("event", callback1)
			dispatcher:addListener("event", callback2)
			dispatcher:emit("event", 123)
			jestExpect(callback1).toHaveBeenCalledTimes(1)
			jestExpect(callback1).toHaveBeenCalledWith(123)
			jestExpect(callback2).toHaveBeenCalledTimes(1)
			jestExpect(callback2).toHaveBeenCalledWith(123)
			jestExpect(callback3).never.toHaveBeenCalled()
			dispatcher:emit("event", 456)
			jestExpect(callback1).toHaveBeenCalledTimes(2)
			jestExpect(callback1).toHaveBeenCalledWith(456)
			jestExpect(callback2).toHaveBeenCalledTimes(1)
			jestExpect(callback3).toHaveBeenCalledTimes(1)
			jestExpect(callback3).toHaveBeenCalledWith(456)
		end
	)
end)
