local O=script.Parent local Z=require(O.Flags)local p=require(O.isActive)return function()afterEach(function()Z.reset()end)describe("\101\120\105\115\116\115",function()it("\115\104\111\117\108\100 \101\114\114\111\114 \105\102 \116\104\101 \102\108\097\103 \100\111\101\115 \110\111\116 \101\120\105\115\116",function()(expect(function()p("\100\111\101\115\078\111\116\069\120\105\115\116")end)).to.throw("\070\108\097\103 \'\100\111\101\115\078\111\116\069\120\105\115\116\' \100\111\101\115\110\'\116 \101\120\105\115\116\046")end)it("\115\104\111\117\108\100 \110\111\116 \101\114\114\111\114 \105\102 \116\104\101 \102\108\097\103 \101\120\105\115\116\115",function()Z.create("\101\120\105\115\116\115");(expect(function()p("\101\120\105\115\116\115")end)).to.never.throw()end)it("\115\104\111\117\108\100 \110\111\116 \101\114\114\111\114 \105\102 \097 \100\101\102\097\117\108\116 \105\115 \112\114\111\118\105\100\101\100",function()(expect(function()p("\100\111\101\115\078\111\116\069\120\105\115\116",{},{default=true})end)).to.never.throw()end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \100\101\102\097\117\108\116 \119\104\101\110 \112\114\111\118\105\100\101\100 \105\102 \116\104\101 \102\108\097\103 \100\111\101\115 \110\111\116 \101\120\105\115\116",function()local O=p("\100\111\101\115\078\111\116\069\120\105\115\116",{},{default=true});(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \110\111\116 \101\114\114\111\114 \105\102 \096\119\097\114\110\069\120\105\115\116\115\096 \105\115 \116\114\117\101",function()(expect(function()p("\100\111\101\115\078\111\116\069\120\105\115\116",{},{warnExists=true})end)).to.never.throw()end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \102\097\108\115\101 \105\102 \096\119\097\114\110\069\120\105\115\116\115\096 \105\115 \116\114\117\101 \097\110\100 \110\111 \100\101\102\097\117\108\116 \105\115 \112\114\111\118\105\100\101\100",function()local O=p("\100\111\101\115\078\111\116\069\120\105\115\116",{},{warnExists=true});(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \100\101\102\097\117\108\116 \105\102 \096\119\097\114\110\069\120\105\115\116\115\096 \105\115 \116\114\117\101 \097\110\100 \097 \100\101\102\097\117\108\116 \105\115 \112\114\111\118\105\100\101\100",function()local O=p("\100\111\101\115\078\111\116\069\120\105\115\116",{},{warnExists=true,default=true});(expect(O)).to.equal(true)end)end)describe("\114\101\116\105\114\101\100",function()beforeEach(function()Z.create("\114\101\116\105\114\101\100",{retired=true})end)it("\115\104\111\117\108\100 \110\111\116 \101\114\114\111\114 \119\105\116\104 \100\101\102\097\117\108\116 \099\111\110\102\105\103\117\114\097\116\105\111\110",function()(expect(function()p("\114\101\116\105\114\101\100")end)).to.never.throw()end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\114\117\101 \119\105\116\104 \100\101\102\097\117\108\116 \099\111\110\102\105\103\117\114\097\116\105\111\110",function()local O=p("\114\101\116\105\114\101\100");(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \110\111\116 \101\114\114\111\114 \119\105\116\104 \096\119\097\114\110\082\101\116\105\114\101\096 \115\101\116 \116\111 \102\097\108\115\101",function()(expect(function()p("\114\101\116\105\114\101\100",{},{warnRetire=false})end)).to.never.throw()end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\114\117\101 \119\105\116\104 \096\119\097\114\110\082\101\116\105\114\101\096 \115\101\116 \116\111 \102\097\108\115\101",function()local O=p("\114\101\116\105\114\101\100",{},{warnRetire=false});(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \101\114\114\111\114 \119\105\116\104 \096\097\108\108\111\119\082\101\116\105\114\101\096 \115\101\116 \116\111 \102\097\108\115\101",function()(expect(function()p("\114\101\116\105\114\101\100",{},{allowRetire=false})end)).to.throw("\070\108\097\103 \'\114\101\116\105\114\101\100\' \105\115 \114\101\116\105\114\101\100\046")end)end)describe("\097\099\116\105\118\101",function()it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101 \102\108\097\103 \105\115 \097\099\116\105\118\101",function()Z.create("\097\099\116\105\118\101",{active=true})local O=p("\097\099\116\105\118\101");(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101 \102\108\097\103 \105\115 \110\111\116 \097\099\116\105\118\101",function()Z.create("\097\099\116\105\118\101",{active=false})local O=p("\097\099\116\105\118\101");(expect(O)).to.equal(false)end)end)describe("\114\117\108\101\083\101\116\115",function()describe("\097\099\116\105\118\101",function()it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101 \102\108\097\103 \105\115 \110\111\116 \097\099\116\105\118\101 \114\101\103\097\114\100\108\101\115\115 \111\102 \114\117\108\101 \115\101\116\115",function()Z.create("\105\110\097\099\116\105\118\101",{active=false;ruleSets={{allowedUsers={[1]=true}}}})local O=p("\105\110\097\099\116\105\118\101",{userId=1});(expect(O)).to.equal(false)end)end)describe("\117\115\101\114\115",function()it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101 \117\115\101\114 \073\068 \109\097\116\099\104\101\115 \116\104\101 \097\108\108\111\119 \108\105\115\116",function()Z.create("\117\115\101\114\115",{ruleSets={{allowedUsers={[1]=true}}}})local O=p("\117\115\101\114\115",{userId=1});(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101 \117\115\101\114 \073\068 \100\111\101\115 \110\111\116 \109\097\116\099\104 \116\104\101 \097\108\108\111\119 \108\105\115\116",function()Z.create("\117\115\101\114\115",{ruleSets={{allowedUsers={[1]=true}}}})local O=p("\117\115\101\114\115",{userId=2});(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101 \117\115\101\114 \073\068 \109\097\116\099\104\101\115 \116\104\101 \100\101\110\121 \108\105\115\116",function()Z.create("\117\115\101\114\115",{ruleSets={{forbiddenUsers={[1]=true}}}})local O=p("\117\115\101\114\115",{userId=1});(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101 \117\115\101\114 \073\068 \100\111\101\115 \110\111\116 \109\097\116\099\104 \116\104\101 \100\101\110\121 \108\105\115\116",function()Z.create("\117\115\101\114\115",{ruleSets={{forbiddenUsers={[1]=true}}}})local O=p("\117\115\101\114\115",{userId=2});(expect(O)).to.equal(true)end)end)describe("\103\114\111\117\112\115",function()it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101 \103\114\111\117\112 \109\097\116\099\104\101\115 \116\104\101 \097\108\108\111\119 \108\105\115\116",function()Z.create("\103\114\111\117\112\115",{ruleSets={{allowedGroups={group1=true}}}})local O=p("\103\114\111\117\112\115",{groups={group1=true}});(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101 \103\114\111\117\112 \100\111\101\115 \110\111\116 \109\097\116\099\104 \116\104\101 \097\108\108\111\119 \108\105\115\116",function()Z.create("\103\114\111\117\112\115",{ruleSets={{allowedGroups={group1=true}}}})local O=p("\103\114\111\117\112\115",{groups={group2=true}});(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101 \103\114\111\117\112 \109\097\116\099\104\101\115 \116\104\101 \100\101\110\121 \108\105\115\116",function()Z.create("\103\114\111\117\112\115",{ruleSets={{forbiddenGroups={group1=true}}}})local O=p("\103\114\111\117\112\115",{groups={group1=true}});(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101 \103\114\111\117\112 \100\111\101\115 \110\111\116 \109\097\116\099\104 \116\104\101 \100\101\110\121 \108\105\115\116",function()Z.create("\103\114\111\117\112\115",{ruleSets={{forbiddenGroups={group1=true}}}})local O=p("\103\114\111\117\112\115",{groups={group2=true}});(expect(O)).to.equal(true)end)end)describe("\115\121\115\116\101\109",function()it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101 \115\121\115\116\101\109 \115\116\097\116\101 \109\097\116\099\104\101\115 \116\104\101 \097\108\108\111\119 \108\105\115\116",function()Z.create("\115\121\115\116\101\109",{ruleSets={{allowedSystemStates={state1=true}}}})local O=p("\115\121\115\116\101\109",{systemStates={state1=true}});(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101 \115\121\115\116\101\109 \115\116\097\116\101 \100\111\101\115 \110\111\116 \109\097\116\099\104 \116\104\101 \097\108\108\111\119 \108\105\115\116",function()Z.create("\115\121\115\116\101\109",{ruleSets={{allowedSystemStates={state1=true}}}})local O=p("\115\121\115\116\101\109",{systemStates={state2=true}});(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101 \115\121\115\116\101\109 \115\116\097\116\101 \109\097\116\099\104\101\115 \116\104\101 \100\101\110\121 \108\105\115\116",function()Z.create("\115\121\115\116\101\109",{ruleSets={{forbiddenSystemStates={state1=true}}}})local O=p("\115\121\115\116\101\109",{systemStates={state1=true}});(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101 \115\121\115\116\101\109 \115\116\097\116\101 \100\111\101\115 \110\111\116 \109\097\116\099\104 \116\104\101 \100\101\110\121 \108\105\115\116",function()Z.create("\115\121\115\116\101\109",{ruleSets={{forbiddenSystemStates={state1=true}}}})local O=p("\115\121\115\116\101\109",{systemStates={state2=true}});(expect(O)).to.equal(true)end)end)describe("\097\098\083\101\103\109\101\110\116\115",function()it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \114\101\103\097\114\100\108\101\115\115 \111\102 \115\101\103\109\101\110\116\115 \105\102 \116\104\101\114\101 \105\115 \110\111 \117\115\101\114 \105\100",function()Z.create("\097\098\083\101\103\109\101\110\116\115",{ruleSets={{abSegments={segment1=true}}}})local O=p("\097\098\083\101\103\109\101\110\116\115");(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101\114\101 \105\115 \111\110\108\121 \111\110\101 \115\101\103\109\101\110\116 \097\110\100 \105\116 \109\097\116\099\104\101\115",function()Z.create("\097\098\083\101\103\109\101\110\116\115",{ruleSets={{abSegments={segment1=1}}}})local O=p("\097\098\083\101\103\109\101\110\116\115",{userId=1;abSegments={segment1=true}});(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101\114\101 \105\115 \111\110\108\121 \111\110\101 \115\101\103\109\101\110\116 \097\110\100 \105\116 \100\111\101\115 \110\111\116 \109\097\116\099\104",function()Z.create("\097\098\083\101\103\109\101\110\116\115",{ruleSets={{abSegments={segment1=1}}}})local O=p("\097\098\083\101\103\109\101\110\116\115",{userId=1,abSegments={segment2=true}});(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \100\101\116\101\114\109\105\110\105\115\116\105\099\097\108\108\121 \097\112\112\111\114\116\105\111\110 \117\115\101\114\115 \116\111 \115\101\103\109\101\110\116\115",function()Z.create("\097\098\083\101\103\109\101\110\116\115",{ruleSets={{abSegments={segment1=1,segment2=1}}}})local O=-259204544 local j={}local N={}local T=Random.new(O)for O=1,10000,1 do local Z=T:NextInteger(100000,1099511627776.0)local c=p("\097\098\083\101\103\109\101\110\116\115",{userId=Z;abSegments={segment1=true}})if c then j[Z]=true else N[Z]=true end end for O in j do local Z=p("\097\098\083\101\103\109\101\110\116\115",{userId=O;abSegments={segment1=true}});(expect(Z)).to.equal(true)end for O in N do local Z=p("\097\098\083\101\103\109\101\110\116\115",{userId=O;abSegments={segment2=true}});(expect(Z)).to.equal(true)end end)it("\115\104\111\117\108\100 \097\112\112\111\114\116\105\111\110 \117\115\101\114\115 \116\111 \115\101\103\109\101\110\116\115 \098\097\115\101\100 \111\110 \116\104\101 \115\101\103\109\101\110\116 \119\101\105\103\104\116\115",function()Z.create("\097\098\083\101\103\109\101\110\116\115",{ruleSets={{abSegments={segment1=1;segment2=2}}}})local O=1719500710 local j=0 local N=0 local T=Random.new(O)for O=1,10000,1 do local Z=T:NextInteger(100000,1099511627776.0)local c=p("\097\098\083\101\103\109\101\110\116\115",{userId=Z;abSegments={segment1=true}})if c then j+=1 else N+=1 end end;(expect(N)).to.be.near(j*2,500)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101\114\101 \097\114\101 \109\117\108\116\105\112\108\101 \115\101\103\109\101\110\116\115 \097\110\100 \110\111\110\101 \109\097\116\099\104",function()Z.create("\097\098\083\101\103\109\101\110\116\115",{ruleSets={{abSegments={segment1=1;segment2=1}}}})local O=p("\097\098\083\101\103\109\101\110\116\115",{userId=1,abSegments={segment3=true}});(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101\114\101 \097\114\101 \109\117\108\116\105\112\108\101 \115\101\103\109\101\110\116\115 \097\110\100 \111\110\101 \109\097\116\099\104\101\115",function()Z.create("\097\098\083\101\103\109\101\110\116\115",{ruleSets={{abSegments={segment1=1;segment2=1}}}})local O=p("\097\098\083\101\103\109\101\110\116\115",{userId=1,abSegments={segment1=true,segment2=true}});(expect(O)).to.equal(true)end)end)describe("\097\099\116\105\118\097\116\105\111\110",function()it("\115\104\111\117\108\100 \105\110\118\111\107\101 \116\104\101 \097\099\116\105\118\097\116\105\111\110 \102\117\110\099\116\105\111\110",function()local O=false Z.create("\097\099\116\105\118\097\116\105\111\110",{ruleSets={{activation=function()O=true end}}});(expect(O)).to.equal(false)p("\097\099\116\105\118\097\116\105\111\110");(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \112\097\115\115 \116\104\101 \117\115\101\114 \099\111\110\116\101\120\116 \116\111 \116\104\101 \097\099\116\105\118\097\116\105\111\110 \102\117\110\099\116\105\111\110",function()local O={}local j=false Z.create("\097\099\116\105\118\097\116\105\111\110",{ruleSets={{activation=function(Z)j=Z==O end}}});(expect(j)).to.equal(false)p("\097\099\116\105\118\097\116\105\111\110",O);(expect(j)).to.equal(true)end)it("\115\104\111\117\108\100 \112\097\115\115 \116\104\101 \099\117\114\114\101\110\116 \114\117\108\101 \115\101\116 \116\111 \116\104\101 \097\099\116\105\118\097\116\105\111\110 \102\117\110\099\116\105\111\110",function()local O=false local j j={activation=function(Z,p)O=p==j end}Z.create("\097\099\116\105\118\097\116\105\111\110",{ruleSets={j}});(expect(O)).to.equal(false)p("\097\099\116\105\118\097\116\105\111\110");(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101 \097\099\116\105\118\097\116\105\111\110 \102\117\110\099\116\105\111\110 \114\101\116\117\114\110\115 \116\114\117\101",function()Z.create("\097\099\116\105\118\097\116\105\111\110",{ruleSets={{activation=function()return true end}}})local O=p("\097\099\116\105\118\097\116\105\111\110");(expect(O)).to.equal(true)end)it("\115\104\111\117\108\100 \098\101 \102\097\108\115\101 \119\104\101\110 \116\104\101 \097\099\116\105\118\097\116\105\111\110 \102\117\110\099\116\105\111\110 \114\101\116\117\114\110\115 \102\097\108\115\101",function()Z.create("\097\099\116\105\118\097\116\105\111\110",{ruleSets={{activation=function()return false end}}})local O=p("\097\099\116\105\118\097\116\105\111\110");(expect(O)).to.equal(false)end)it("\115\104\111\117\108\100 \098\101 \116\114\117\101 \119\104\101\110 \116\104\101 \097\099\116\105\118\097\116\105\111\110 \102\117\110\099\116\105\111\110 \114\101\116\117\114\110\115 \110\105\108",function()Z.create("\097\099\116\105\118\097\116\105\111\110",{ruleSets={{activation=function()return nil end}}})local O=p("\097\099\116\105\118\097\116\105\111\110");(expect(O)).to.equal(true)end)end)end)end
local Package = script.Parent
local Flags = require(Package.Flags)
local isActive = require(Package.isActive)

return function()
	afterEach(function()
		Flags.reset()
	end)

	describe("exists", function()
		it("should error if the flag does not exist", function()
			expect(function()
				isActive("doesNotExist")
			end).to.throw("Flag 'doesNotExist' doesn't exist.")
		end)

		it("should not error if the flag exists", function()
			Flags.create("exists")
			expect(function()
				isActive("exists")
			end).to.never.throw()
		end)

		it("should not error if a default is provided", function()
			expect(function()
				isActive("doesNotExist", {}, { default = true })
			end).to.never.throw()
		end)

		it("should return the default when provided if the flag does not exist", function()
			local active = isActive("doesNotExist", {}, { default = true })
			expect(active).to.equal(true)
		end)

		it("should not error if `warnExists` is true", function()
			expect(function()
				isActive("doesNotExist", {}, { warnExists = true })
			end).to.never.throw()
		end)

		it("should return false if `warnExists` is true and no default is provided", function()
			local active = isActive("doesNotExist", {}, { warnExists = true })
			expect(active).to.equal(false)
		end)

		it("should return the default if `warnExists` is true and a default is provided", function()
			local active = isActive("doesNotExist", {}, { warnExists = true, default = true })
			expect(active).to.equal(true)
		end)
	end)

	describe("retired", function()
		beforeEach(function()
			Flags.create("retired", {
				retired = true,
			})
		end)

		it("should not error with default configuration", function()
			expect(function()
				isActive("retired")
			end).to.never.throw()
		end)

		it("should return true with default configuration", function()
			local active = isActive("retired")
			expect(active).to.equal(true)
		end)

		it("should not error with `warnRetire` set to false", function()
			expect(function()
				isActive("retired", {}, { warnRetire = false })
			end).to.never.throw()
		end)

		it("should return true with `warnRetire` set to false", function()
			local active = isActive("retired", {}, { warnRetire = false })
			expect(active).to.equal(true)
		end)

		it("should error with `allowRetire` set to false", function()
			expect(function()
				isActive("retired", {}, { allowRetire = false })
			end).to.throw("Flag 'retired' is retired.")
		end)
	end)

	describe("active", function()
		it("should be true when the flag is active", function()
			Flags.create("active", {
				active = true,
			})
			local active = isActive("active")
			expect(active).to.equal(true)
		end)

		it("should be false when the flag is not active", function()
			Flags.create("active", {
				active = false,
			})
			local active = isActive("active")
			expect(active).to.equal(false)
		end)
	end)

	describe("ruleSets", function()
		describe("active", function()
			it("should be false when the flag is not active regardless of rule sets", function()
				Flags.create("inactive", {
					active = false,
					ruleSets = {
						{
							allowedUsers = { [1] = true },
						},
					},
				})
				local active = isActive("inactive", { userId = 1 })
				expect(active).to.equal(false)
			end)
		end)

		describe("users", function()
			it("should be true when the user ID matches the allow list", function()
				Flags.create("users", {
					ruleSets = {
						{
							allowedUsers = { [1] = true },
						},
					},
				})
				local active = isActive("users", { userId = 1 })
				expect(active).to.equal(true)
			end)

			it("should be false when the user ID does not match the allow list", function()
				Flags.create("users", {
					ruleSets = {
						{
							allowedUsers = { [1] = true },
						},
					},
				})
				local active = isActive("users", { userId = 2 })
				expect(active).to.equal(false)
			end)

			it("should be false when the user ID matches the deny list", function()
				Flags.create("users", {
					ruleSets = {
						{
							forbiddenUsers = { [1] = true },
						},
					},
				})
				local active = isActive("users", { userId = 1 })
				expect(active).to.equal(false)
			end)

			it("should be true when the user ID does not match the deny list", function()
				Flags.create("users", {
					ruleSets = {
						{
							forbiddenUsers = { [1] = true },
						},
					},
				})
				local active = isActive("users", { userId = 2 })
				expect(active).to.equal(true)
			end)
		end)

		describe("groups", function()
			it("should be true when the group matches the allow list", function()
				Flags.create("groups", {
					ruleSets = {
						{
							allowedGroups = { group1 = true },
						},
					},
				})
				local active = isActive("groups", {
					groups = { group1 = true },
				})
				expect(active).to.equal(true)
			end)

			it("should be false when the group does not match the allow list", function()
				Flags.create("groups", {
					ruleSets = {
						{
							allowedGroups = { group1 = true },
						},
					},
				})
				local active = isActive("groups", {
					groups = { group2 = true },
				})
				expect(active).to.equal(false)
			end)

			it("should be false when the group matches the deny list", function()
				Flags.create("groups", {
					ruleSets = {
						{
							forbiddenGroups = { group1 = true },
						},
					},
				})
				local active = isActive("groups", {
					groups = { group1 = true },
				})
				expect(active).to.equal(false)
			end)

			it("should be true when the group does not match the deny list", function()
				Flags.create("groups", {
					ruleSets = {
						{
							forbiddenGroups = { group1 = true },
						},
					},
				})
				local active = isActive("groups", {
					groups = { group2 = true },
				})
				expect(active).to.equal(true)
			end)
		end)

		describe("system", function()
			it("should be true when the system state matches the allow list", function()
				Flags.create("system", {
					ruleSets = {
						{
							allowedSystemStates = { state1 = true },
						},
					},
				})
				local active = isActive("system", {
					systemStates = { state1 = true },
				})
				expect(active).to.equal(true)
			end)

			it("should be false when the system state does not match the allow list", function()
				Flags.create("system", {
					ruleSets = {
						{
							allowedSystemStates = { state1 = true },
						},
					},
				})
				local active = isActive("system", {
					systemStates = { state2 = true },
				})
				expect(active).to.equal(false)
			end)

			it("should be false when the system state matches the deny list", function()
				Flags.create("system", {
					ruleSets = {
						{
							forbiddenSystemStates = { state1 = true },
						},
					},
				})
				local active = isActive("system", {
					systemStates = { state1 = true },
				})
				expect(active).to.equal(false)
			end)

			it("should be true when the system state does not match the deny list", function()
				Flags.create("system", {
					ruleSets = {
						{
							forbiddenSystemStates = { state1 = true },
						},
					},
				})
				local active = isActive("system", {
					systemStates = { state2 = true },
				})
				expect(active).to.equal(true)
			end)
		end)

		describe("abSegments", function()
			it("should be true regardless of segments if there is no user id", function()
				Flags.create("abSegments", {
					ruleSets = {
						{
							abSegments = { segment1 = true },
						},
					},
				})
				local active = isActive("abSegments")
				expect(active).to.equal(true)
			end)

			it("should be true when there is only one segment and it matches", function()
				Flags.create("abSegments", {
					ruleSets = {
						{
							abSegments = { segment1 = 1 },
						},
					},
				})
				local active = isActive("abSegments", {
					userId = 1,
					abSegments = { segment1 = true },
				})
				expect(active).to.equal(true)
			end)

			it("should be false when there is only one segment and it does not match", function()
				Flags.create("abSegments", {
					ruleSets = {
						{
							abSegments = { segment1 = 1 },
						},
					},
				})
				local active = isActive("abSegments", {
					userId = 1,
					abSegments = { segment2 = true },
				})
				expect(active).to.equal(false)
			end)

			it("should deterministically apportion users to segments", function()
				Flags.create("abSegments", {
					ruleSets = {
						{
							abSegments = { segment1 = 1, segment2 = 1 },
						},
					},
				})

				-- A randomly generated seed for fuzz testing
				-- local RANGE = 2 ^ 31 - 1
				-- local seed = math.random(-RANGE, RANGE)
				-- print("Determinism fuzz seed:", seed)

				-- A pre-determined seed to ensure determinism
				local seed = -259204544

				local segment1Set = {}
				local segment2Set = {}
				local random = Random.new(seed)

				for _ = 1, 10000 do
					local userId = random:NextInteger(100000, 2 ^ 40)
					local active = isActive("abSegments", {
						userId = userId,
						abSegments = { segment1 = true },
					})
					if active then
						segment1Set[userId] = true
					else
						segment2Set[userId] = true
					end
				end

				for userId in segment1Set do
					local active = isActive("abSegments", {
						userId = userId,
						abSegments = { segment1 = true },
					})
					expect(active).to.equal(true)
				end

				for userId in segment2Set do
					local active = isActive("abSegments", {
						userId = userId,
						abSegments = { segment2 = true },
					})
					expect(active).to.equal(true)
				end
			end)

			it("should apportion users to segments based on the segment weights", function()
				Flags.create("abSegments", {
					ruleSets = {
						{
							abSegments = { segment1 = 1, segment2 = 2 },
						},
					},
				})

				-- A randomly generated seed for fuzz testing
				-- local RANGE = 2 ^ 31 - 1
				-- local seed = math.random(-RANGE, RANGE)
				-- print("Proportion fuzz seed:", seed)

				-- A pre-determined seed to ensure determinism
				local seed = 1719500710

				local segment1Count = 0
				local segment2Count = 0
				local random = Random.new(seed)

				for _ = 1, 10000 do
					local userId = random:NextInteger(100000, 2 ^ 40)
					local active = isActive("abSegments", {
						userId = userId,
						abSegments = { segment1 = true },
					})
					if active then
						segment1Count += 1
					else
						segment2Count += 1
					end
				end

				expect(segment2Count).to.be.near(segment1Count * 2, 500)
			end)

			it("should be false when there are multiple segments and none match", function()
				Flags.create("abSegments", {
					ruleSets = {
						{
							abSegments = { segment1 = 1, segment2 = 1 },
						},
					},
				})
				local active = isActive("abSegments", {
					userId = 1,
					abSegments = { segment3 = true },
				})
				expect(active).to.equal(false)
			end)

			it("should be true when there are multiple segments and one matches", function()
				Flags.create("abSegments", {
					ruleSets = {
						{
							abSegments = { segment1 = 1, segment2 = 1 },
						},
					},
				})
				local active = isActive("abSegments", {
					userId = 1,
					abSegments = { segment1 = true, segment2 = true },
				})
				expect(active).to.equal(true)
			end)
		end)

		describe("activation", function()
			it("should invoke the activation function", function()
				local activated = false
				Flags.create("activation", {
					ruleSets = {
						{
							activation = function()
								activated = true
							end,
						},
					},
				})

				expect(activated).to.equal(false)
				isActive("activation")
				expect(activated).to.equal(true)
			end)

			it("should pass the user context to the activation function", function()
				local originalContext = {}
				local matchedContext = false

				Flags.create("activation", {
					ruleSets = {
						{
							activation = function(passedContext)
								matchedContext = passedContext == originalContext
							end,
						},
					},
				})

				expect(matchedContext).to.equal(false)
				isActive("activation", originalContext)
				expect(matchedContext).to.equal(true)
			end)

			it("should pass the current rule set to the activation function", function()
				local matchedRuleSet = false
				local originalRuleSet

				originalRuleSet = {
					activation = function(_, passedRuleSet)
						matchedRuleSet = passedRuleSet == originalRuleSet
					end,
				}

				Flags.create("activation", {
					ruleSets = { originalRuleSet },
				})

				expect(matchedRuleSet).to.equal(false)
				isActive("activation")
				expect(matchedRuleSet).to.equal(true)
			end)

			it("should be true when the activation function returns true", function()
				Flags.create("activation", {
					ruleSets = {
						{
							activation = function()
								return true
							end,
						},
					},
				})

				local active = isActive("activation")
				expect(active).to.equal(true)
			end)

			it("should be false when the activation function returns false", function()
				Flags.create("activation", {
					ruleSets = {
						{
							activation = function()
								return false
							end,
						},
					},
				})

				local active = isActive("activation")
				expect(active).to.equal(false)
			end)

			it("should be true when the activation function returns nil", function()
				Flags.create("activation", {
					ruleSets = {
						{
							activation = function()
								return nil
							end,
						},
					},
				})

				local active = isActive("activation")
				expect(active).to.equal(true)
			end)
		end)
	end)
end
