local e=require(script.Parent.serializeFlagsToDirectory)return function()describe("\067\104\097\110\103\101\115",function()it("\115\104\111\117\108\100 \109\097\107\101 \110\111 \099\104\097\110\103\101\115 \119\104\101\110 \116\104\101\114\101 \097\114\101 \110\111 \102\108\097\103 \099\104\097\110\103\101\115",function()local Q={flag1={managed=true;repository="\048",version=1},flag2={managed=true;repository="\048",version=1},flag3={managed=true;repository="\048";version=1}}local U={flag1={managed=true,repository="\048";version=1};flag2={managed=true,repository="\048";version=1},flag3={managed=true,repository="\048",version=1}}local P,m,g=e(Q,U,{});(expect(next(m))).never.to.be.ok();(expect(next(g))).never.to.be.ok()end)it("\115\104\111\117\108\100 \109\097\107\101 \099\104\097\110\103\101\115 \119\104\101\110 \117\112\100\097\116\105\110\103 \097 \102\108\097\103",function()local Q={flag1={managed=true,repository="\048",version=1},flag2={managed=true;repository="\048",version=1},flag3={managed=true;repository="\048",version=1}}local U={flag1={managed=true;repository="\048",version=1},flag2={managed=true,repository="\048",version=1},flag3={managed=true;repository="\048",version=1}}local P,m,g=e(Q,U,{flag2={change={active=true,retired=false;ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\048"])).to.be.ok();(expect(m["\048"].flag2)).to.be.ok()end)it("\115\104\111\117\108\100 \109\097\107\101 \109\097\110\121 \099\104\097\110\103\101\115 \119\104\101\110 \117\112\100\097\116\105\110\103 \109\097\110\121 \102\108\097\103\115",function()local Q={flag1={managed=true,repository="\048",version=1},flag2={managed=true,repository="\048",version=1};flag3={managed=true,repository="\048",version=1}}local U={flag1={managed=true,repository="\048",version=1};flag2={managed=true;repository="\048";version=1},flag3={managed=true;repository="\048",version=1}}local P,m,g=e(Q,U,{flag1={change={active=true,retired=false;ruleSets={}}};flag2={change={active=true;retired=false,ruleSets={}}};flag3={change={active=true,retired=false;ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\048"])).to.be.ok();(expect(m["\048"].flag1)).to.be.ok();(expect(m["\048"].flag2)).to.be.ok();(expect(m["\048"].flag3)).to.be.ok()end)it("\115\104\111\117\108\100 \109\097\107\101 \099\104\097\110\103\101\115 \116\111 \116\104\101 \097\112\112\114\111\112\114\105\097\116\101 \114\101\112\111\115\105\116\111\114\105\101\115",function()local Q={flag1={managed=true,repository="\048",version=1};flag2={managed=true;repository="\050";version=1};flag3={managed=true;repository="\051";version=1}}local U={flag1={managed=true,repository="\048";version=1},flag2={managed=true,repository="\050";version=1},flag3={managed=true;repository="\051",version=1}}local P,m,g=e(Q,U,{flag1={change={active=true;retired=false,ruleSets={}}},flag2={change={active=true,retired=false,ruleSets={}}};flag3={change={active=true,retired=false;ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\048"])).to.be.ok();(expect(m["\048"].flag1)).to.be.ok();(expect(m["\050"])).to.be.ok();(expect(m["\050"].flag2)).to.be.ok();(expect(m["\051"])).to.be.ok();(expect(m["\051"].flag3)).to.be.ok()end)it("\115\104\111\117\108\100 \109\097\107\101 \099\104\097\110\103\101\115 \116\111 \116\104\101 \097\112\112\114\111\112\114\105\097\116\101 \114\101\112\111\115\105\116\111\114\105\101\115 \119\104\101\110 \116\104\101 \099\097\099\104\101 \100\105\102\102\101\114\115",function()local Q={flag1={managed=true,repository="\048";version=1};flag2={managed=true,repository="\048",version=1};flag3={managed=true;repository="\048",version=1}}local U={flag1={managed=true;repository="\048",version=1},flag2={managed=true;repository="\050";version=1},flag3={managed=true;repository="\051",version=1}}local P,m,g=e(Q,U,{flag1={change={active=true;retired=false;ruleSets={}}},flag2={change={active=true,retired=false,ruleSets={}}};flag3={change={active=true,retired=false,ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\048"])).to.be.ok();(expect(m["\048"].flag1)).to.be.ok();(expect(m["\050"])).to.be.ok();(expect(m["\050"].flag2)).to.be.ok();(expect(m["\051"])).to.be.ok();(expect(m["\051"].flag3)).to.be.ok()end)it("\115\104\111\117\108\100 \112\114\111\118\105\100\101 \099\104\097\110\103\101 \118\101\114\115\105\111\110\115",function()local Q={flag1={managed=true,repository="\048";version=1},flag2={managed=true;repository="\048";version=2},flag3={managed=true,repository="\048",version=3}}local U={flag1={managed=true;repository="\048";version=1},flag2={managed=true;repository="\048";version=2};flag3={managed=true,repository="\048";version=3}}local P,m,g=e(Q,U,{flag1={change={active=true,retired=false,ruleSets={}}},flag2={change={active=true,retired=false,ruleSets={}}},flag3={change={active=true,retired=false;ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\048"])).to.be.ok();(expect(m["\048"].flag1)).to.be.ok();(expect(m["\048"].flag1.version)).to.equal(2);(expect(m["\048"].flag2)).to.be.ok();(expect(m["\048"].flag2.version)).to.equal(3);(expect(m["\048"].flag3)).to.be.ok();(expect(m["\048"].flag3.version)).to.equal(4)end)end)describe("\068\105\114\101\099\116\111\114\121",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \110\101\119 \100\105\114\101\099\116\111\114\121 \102\111\114 \099\111\110\118\101\110\105\101\110\099\101",function()local Q={}local U={}local P=e(Q,U,{});(expect(P)).to.equal(U)end)it("\115\104\111\117\108\100 \109\097\107\101 \110\111 \099\104\097\110\103\101\115 \116\111 \097\110 \101\109\112\116\121 \100\105\114\101\099\116\111\114\121 \119\104\101\110 \112\114\111\118\105\100\101\100 \110\111 \099\104\097\110\103\101\115",function()local Q={}local U={}local P=e(Q,U,{});(expect(next(P))).never.to.be.ok()end)it("\115\104\111\117\108\100 \109\097\107\101 \110\111 \099\104\097\110\103\101\115 \116\111 \097 \100\105\114\101\099\116\111\114\121 \119\104\101\110 \112\114\111\118\105\100\101\100 \110\111 \099\104\097\110\103\101\115",function()local Q={flag1={managed=true;repository="\048",version=1};flag2={managed=true,repository="\048";version=1},flag3={managed=true,repository="\048",version=1}}local U={flag1={managed=true,repository="\048",version=1};flag2={managed=true;repository="\048";version=1},flag3={managed=true,repository="\048";version=1}}local P=e(Q,U,{});(expect(P)).to.be.ok();(expect(P.flag1)).to.be.ok();(expect(P.flag1.version)).to.be.ok();(expect(P.flag2)).to.be.ok();(expect(P.flag2.version)).to.be.ok();(expect(P.flag3)).to.be.ok();(expect(P.flag3.version)).to.be.ok()end)it("\115\104\111\117\108\100 \112\114\111\118\105\100\101 \116\104\101 \099\111\114\114\101\099\116 \118\101\114\115\105\111\110\115",function()local Q={flag1={managed=true,repository="\048",version=1},flag2={managed=true,repository="\048",version=2},flag3={managed=true;repository="\048";version=3}}local U={flag1={managed=true,repository="\048",version=1};flag2={managed=true,repository="\048",version=2};flag3={managed=true,repository="\048";version=3}}local P=e(Q,U,{});(expect(P)).to.be.ok();(expect(P.flag1)).to.be.ok();(expect(P.flag1.version)).to.equal(1);(expect(P.flag2)).to.be.ok();(expect(P.flag2.version)).to.equal(2);(expect(P.flag3)).to.be.ok();(expect(P.flag3.version)).to.equal(3)end)it("\115\104\111\117\108\100 \112\114\111\118\105\100\101 \116\104\101 \110\101\119 \100\105\114\101\099\116\111\114\121 \105\102 \116\104\101 \099\097\099\104\101\100 \102\108\097\103 \105\115 \111\108\100",function()local Q={flag1={managed=true;repository="\048",version=1},flag2={managed=true,repository="\048",version=1},flag3={managed=true;repository="\048";version=1}}local U={flag1={managed=true,repository="\048";version=2};flag2={managed=true,repository="\048";version=1},flag3={managed=true;repository="\048",version=1}}local P=e(Q,U,{flag1={change={active=true;retired=false;ruleSets={}}}});(expect(P)).to.be.ok();(expect(P.flag1)).to.be.ok();(expect(P.flag1.version)).to.equal(2)end)it("\115\104\111\117\108\100 \117\112\100\097\116\101 \116\104\101 \111\108\100 \100\105\114\101\099\116\111\114\121 \105\102 \116\104\101 \110\101\119 \100\105\114\101\099\116\111\114\121 \105\115 \109\111\114\101 \114\101\099\101\110\116",function()local Q={flag1={managed=true,repository="\048",version=1};flag2={managed=true,repository="\048";version=1};flag3={managed=true;repository="\048";version=1}}local U={flag1={managed=true,repository="\048",version=2},flag2={managed=true;repository="\048",version=1},flag3={managed=true,repository="\048",version=1}}e(Q,U,{flag1={change={active=true,retired=false;ruleSets={}}}});(expect(Q.flag1)).to.be.ok();(expect(Q.flag1.version)).to.equal(2)end)it("\115\104\111\117\108\100 \117\112\100\097\116\101 \116\104\101 \110\101\119 \100\105\114\101\099\116\111\114\121 \105\102 \116\104\101 \111\108\100 \100\105\114\101\099\116\111\114\121 \105\115 \109\111\114\101 \114\101\099\101\110\116",function()local Q={flag1={managed=true,repository="\048",version=2};flag2={managed=true,repository="\048";version=1};flag3={managed=true,repository="\048";version=1}}local U={flag1={managed=true;repository="\048";version=1};flag2={managed=true,repository="\048";version=1},flag3={managed=true;repository="\048";version=1}}e(Q,U,{flag1={change={active=true,retired=false,ruleSets={}}}});(expect(U.flag1)).to.be.ok();(expect(U.flag1.version)).to.equal(3)end)it("\115\104\111\117\108\100 \110\111\116 \117\112\100\097\116\101 \101\110\116\114\105\101\115 \116\104\097\116 \097\114\101 \110\111\116 \099\104\097\110\103\105\110\103",function()local Q={flag1={managed=true;repository="\048";version=1};flag2={managed=true;repository="\048",version=1};flag3={managed=true;repository="\048";version=2}}local U={flag1={managed=true,repository="\048";version=1},flag2={managed=true;repository="\048";version=2},flag3={managed=true;repository="\048";version=1}}e(Q,U,{flag1={change={active=true,retired=false;ruleSets={}}}});(expect(Q.flag2)).to.be.ok();(expect(Q.flag2.version)).to.equal(1);(expect(U.flag3)).to.be.ok();(expect(U.flag3.version)).to.equal(1)end)end)describe("\078\101\119 \069\110\116\114\105\101\115",function()it("\115\104\111\117\108\100 \099\114\101\097\116\101 \110\101\119 \101\110\116\114\105\101\115 \119\104\101\110 \116\104\101\121 \100\111 \110\111\116 \101\120\105\115\116",function()local Q={}local U={}local P,m,g=e(Q,U,{flag1={change={active=true,retired=false,ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\048"])).to.be.ok();(expect(m["\048"].flag1)).to.be.ok();(expect(m["\048"].flag1.version)).to.equal(0);(expect(P)).to.be.ok();(expect(P.flag1)).to.be.ok();(expect(P.flag1.version)).to.equal(0)end)it("\115\104\111\117\108\100 \099\114\101\097\116\101 \110\101\119 \101\110\116\114\105\101\115 \119\104\101\110 \116\104\101\121 \100\111 \110\111\116 \101\120\105\115\116 \097\110\100 \116\104\101 \099\097\099\104\101 \105\115 \111\108\100",function()local Q={}local U={flag1={managed=true,repository="\048";version=1}}local P,m,g=e(Q,U,{flag2={change={active=true;retired=false;ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\048"])).to.be.ok();(expect(m["\048"].flag2)).to.be.ok();(expect(m["\048"].flag2.version)).to.equal(0);(expect(P)).to.be.ok();(expect(P.flag2)).to.be.ok();(expect(P.flag2.version)).to.equal(0)end)it("\115\104\111\117\108\100 \099\114\101\097\116\101 \110\101\119 \101\110\116\114\105\101\115 \119\104\101\110 \116\104\101\121 \100\111 \110\111\116 \101\120\105\115\116 \097\110\100 \116\104\101 \099\097\099\104\101 \099\111\110\116\097\105\110\115 \116\104\101\109",function()local Q={flag1={managed=true;repository="\048",version=1}}local U={}local P,m,g=e(Q,U,{flag1={change={active=true,retired=false;ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\048"])).to.be.ok();(expect(m["\048"].flag1)).to.be.ok();(expect(m["\048"].flag1.version)).to.equal(2);(expect(P)).to.be.ok();(expect(P.flag1)).to.be.ok();(expect(P.flag1.version)).to.equal(2)end)it("\115\104\111\117\108\100 \112\108\097\099\101 \110\101\119 \101\110\116\114\105\101\115 \105\110\116\111 \097 \114\101\112\111\115\105\116\111\114\121 \105\102 \105\116 \099\111\110\116\097\105\110\115 \102\101\119\101\114 \116\104\097\110 \049\048\050\052 \102\108\097\103\115",function()local Q={}local U={}for e=1,1023,1 do U["\102\108\097\103"..e]={managed=true;repository="\048",version=1}end local P,m,g=e(Q,U,{flag1024={change={active=true,retired=false,ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\048"])).to.be.ok();(expect(m["\048"].flag1024)).to.be.ok();(expect(m["\048"].flag1024.version)).to.equal(0);(expect(P)).to.be.ok();(expect(P.flag1024)).to.be.ok();(expect(P.flag1024.version)).to.equal(0)end)it("\115\104\111\117\108\100 \112\108\097\099\101 \110\101\119 \101\110\116\114\105\101\115 \105\110\116\111 \097 \110\101\119 \114\101\112\111\115\105\116\111\114\121 \105\102 \105\116 \099\111\110\116\097\105\110\115 \049\048\050\052 \102\108\097\103\115 \111\114 \109\111\114\101",function()local Q={}local U={}for e=1,1024,1 do U["\102\108\097\103"..e]={managed=true;repository="\048";version=1}end local P,m,g=e(Q,U,{flag1025={change={active=true;retired=false,ruleSets={}}}});(expect(next(g))).never.to.be.ok();(expect(m["\049"])).to.be.ok();(expect(m["\049"].flag1025)).to.be.ok();(expect(m["\049"].flag1025.version)).to.equal(0);(expect(P)).to.be.ok();(expect(P.flag1025)).to.be.ok();(expect(P.flag1025.version)).to.equal(0)end)it("\115\104\111\117\108\100 \112\108\097\099\101 \110\101\119 \101\110\116\114\105\101\115 \105\110\116\111 \097 \116\104\101 \102\105\114\115\116 \114\101\112\111\115\105\116\111\114\121 \119\105\116\104 \114\111\111\109",function()local Q={}local U={}local P=1024 local m=1023 local g=1024 for e=1,P,1 do U["\102\108\097\103"..e]={managed=true,repository="\048",version=1}end for e=1,m,1 do U["\102\108\097\103"..e+P]={managed=true;repository="\049",version=1}end for e=1,g,1 do U["\102\108\097\103"..(e+P)+m]={managed=true;repository="\050";version=1}end local X,f,x=e(Q,U,{flag3072={change={active=true,retired=false,ruleSets={}}}});(expect(next(x))).never.to.be.ok();(expect(f["\049"])).to.be.ok();(expect(f["\049"].flag3072)).to.be.ok();(expect(f["\049"].flag3072.version)).to.equal(0);(expect(X)).to.be.ok();(expect(X.flag3072)).to.be.ok();(expect(X.flag3072.version)).to.equal(0)end)end)end
local serializeFlagsToDirectory = require(script.Parent.serializeFlagsToDirectory)

return function()
	describe("Changes", function()
		it("should make no changes when there are no flag changes", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local _, managedChanges, userChanges =
				serializeFlagsToDirectory(oldDirectory, newDirectory, {})

			expect((next(managedChanges))).never.to.be.ok()
			expect((next(userChanges))).never.to.be.ok()
		end)

		it("should make changes when updating a flag", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local _, managedChanges, userChanges =
				serializeFlagsToDirectory(oldDirectory, newDirectory, {
					flag2 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
				})

			expect((next(userChanges))).never.to.be.ok()

			expect(managedChanges["0"]).to.be.ok()
			expect(managedChanges["0"].flag2).to.be.ok()
		end)

		it("should make many changes when updating many flags", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local _, managedChanges, userChanges =
				serializeFlagsToDirectory(oldDirectory, newDirectory, {
					flag1 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
					flag2 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
					flag3 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
				})

			expect((next(userChanges))).never.to.be.ok()

			expect(managedChanges["0"]).to.be.ok()
			expect(managedChanges["0"].flag1).to.be.ok()
			expect(managedChanges["0"].flag2).to.be.ok()
			expect(managedChanges["0"].flag3).to.be.ok()
		end)

		it("should make changes to the appropriate repositories", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "2",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "3",
					version = 1,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "2",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "3",
					version = 1,
				},
			}

			local _, managedChanges, userChanges =
				serializeFlagsToDirectory(oldDirectory, newDirectory, {
					flag1 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
					flag2 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
					flag3 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
				})

			expect((next(userChanges))).never.to.be.ok()

			expect(managedChanges["0"]).to.be.ok()
			expect(managedChanges["0"].flag1).to.be.ok()
			expect(managedChanges["2"]).to.be.ok()
			expect(managedChanges["2"].flag2).to.be.ok()
			expect(managedChanges["3"]).to.be.ok()
			expect(managedChanges["3"].flag3).to.be.ok()
		end)

		it("should make changes to the appropriate repositories when the cache differs", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "2",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "3",
					version = 1,
				},
			}

			local _, managedChanges, userChanges =
				serializeFlagsToDirectory(oldDirectory, newDirectory, {
					flag1 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
					flag2 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
					flag3 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
				})

			expect((next(userChanges))).never.to.be.ok()

			expect(managedChanges["0"]).to.be.ok()
			expect(managedChanges["0"].flag1).to.be.ok()
			expect(managedChanges["2"]).to.be.ok()
			expect(managedChanges["2"].flag2).to.be.ok()
			expect(managedChanges["3"]).to.be.ok()
			expect(managedChanges["3"].flag3).to.be.ok()
		end)

		it("should provide change versions", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 2,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 3,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 2,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 3,
				},
			}

			local _, managedChanges, userChanges =
				serializeFlagsToDirectory(oldDirectory, newDirectory, {
					flag1 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
					flag2 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
					flag3 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
				})

			expect((next(userChanges))).never.to.be.ok()

			expect(managedChanges["0"]).to.be.ok()
			expect(managedChanges["0"].flag1).to.be.ok()
			expect(managedChanges["0"].flag1.version).to.equal(2)
			expect(managedChanges["0"].flag2).to.be.ok()
			expect(managedChanges["0"].flag2.version).to.equal(3)
			expect(managedChanges["0"].flag3).to.be.ok()
			expect(managedChanges["0"].flag3.version).to.equal(4)
		end)
	end)

	describe("Directory", function()
		it("should return the new directory for convenience", function()
			local oldDirectory = {}
			local newDirectory = {}

			local updatedDirectory = serializeFlagsToDirectory(oldDirectory, newDirectory, {})

			expect(updatedDirectory).to.equal(newDirectory)
		end)

		it("should make no changes to an empty directory when provided no changes", function()
			local oldDirectory = {}
			local newDirectory = {}

			local updatedDirectory = serializeFlagsToDirectory(oldDirectory, newDirectory, {})

			expect((next(updatedDirectory))).never.to.be.ok()
		end)

		it("should make no changes to a directory when provided no changes", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local updatedDirectory = serializeFlagsToDirectory(oldDirectory, newDirectory, {})

			expect(updatedDirectory).to.be.ok()
			expect(updatedDirectory.flag1).to.be.ok()
			expect(updatedDirectory.flag1.version).to.be.ok()
			expect(updatedDirectory.flag2).to.be.ok()
			expect(updatedDirectory.flag2.version).to.be.ok()
			expect(updatedDirectory.flag3).to.be.ok()
			expect(updatedDirectory.flag3.version).to.be.ok()
		end)

		it("should provide the correct versions", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 2,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 3,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 2,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 3,
				},
			}

			local updatedDirectory = serializeFlagsToDirectory(oldDirectory, newDirectory, {})

			expect(updatedDirectory).to.be.ok()
			expect(updatedDirectory.flag1).to.be.ok()
			expect(updatedDirectory.flag1.version).to.equal(1)
			expect(updatedDirectory.flag2).to.be.ok()
			expect(updatedDirectory.flag2.version).to.equal(2)
			expect(updatedDirectory.flag3).to.be.ok()
			expect(updatedDirectory.flag3.version).to.equal(3)
		end)

		it("should provide the new directory if the cached flag is old", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 2,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local updatedDirectory = serializeFlagsToDirectory(oldDirectory, newDirectory, {
				flag1 = {
					change = {
						active = true,
						retired = false,
						ruleSets = {},
					},
				},
			})

			expect(updatedDirectory).to.be.ok()
			expect(updatedDirectory.flag1).to.be.ok()
			expect(updatedDirectory.flag1.version).to.equal(2)
		end)

		it("should update the old directory if the new directory is more recent", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 2,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			serializeFlagsToDirectory(oldDirectory, newDirectory, {
				flag1 = {
					change = {
						active = true,
						retired = false,
						ruleSets = {},
					},
				},
			})

			expect(oldDirectory.flag1).to.be.ok()
			expect(oldDirectory.flag1.version).to.equal(2)
		end)

		it("should update the new directory if the old directory is more recent", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 2,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			serializeFlagsToDirectory(oldDirectory, newDirectory, {
				flag1 = {
					change = {
						active = true,
						retired = false,
						ruleSets = {},
					},
				},
			})

			expect(newDirectory.flag1).to.be.ok()
			expect(newDirectory.flag1.version).to.equal(3)
		end)

		it("should not update entries that are not changing", function()
			local oldDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 2,
				},
			}

			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
				flag2 = {
					managed = true,
					repository = "0",
					version = 2,
				},
				flag3 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			serializeFlagsToDirectory(oldDirectory, newDirectory, {
				flag1 = {
					change = {
						active = true,
						retired = false,
						ruleSets = {},
					},
				},
			})

			expect(oldDirectory.flag2).to.be.ok()
			expect(oldDirectory.flag2.version).to.equal(1)
			expect(newDirectory.flag3).to.be.ok()
			expect(newDirectory.flag3.version).to.equal(1)
		end)
	end)

	describe("New Entries", function()
		it("should create new entries when they do not exist", function()
			local oldDirectory = {}
			local newDirectory = {}

			local updatedDirectory, managedChanges, userChanges =
				serializeFlagsToDirectory(oldDirectory, newDirectory, {
					flag1 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
				})

			expect((next(userChanges))).never.to.be.ok()

			expect(managedChanges["0"]).to.be.ok()
			expect(managedChanges["0"].flag1).to.be.ok()
			expect(managedChanges["0"].flag1.version).to.equal(0)

			expect(updatedDirectory).to.be.ok()
			expect(updatedDirectory.flag1).to.be.ok()
			expect(updatedDirectory.flag1.version).to.equal(0)
		end)

		it("should create new entries when they do not exist and the cache is old", function()
			local oldDirectory = {}
			local newDirectory = {
				flag1 = {
					managed = true,
					repository = "0",
					version = 1,
				},
			}

			local updatedDirectory, managedChanges, userChanges =
				serializeFlagsToDirectory(oldDirectory, newDirectory, {
					flag2 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
				})

			expect((next(userChanges))).never.to.be.ok()

			expect(managedChanges["0"]).to.be.ok()
			expect(managedChanges["0"].flag2).to.be.ok()
			expect(managedChanges["0"].flag2.version).to.equal(0)

			expect(updatedDirectory).to.be.ok()
			expect(updatedDirectory.flag2).to.be.ok()
			expect(updatedDirectory.flag2.version).to.equal(0)
		end)

		it(
			"should create new entries when they do not exist and the cache contains them",
			function()
				local oldDirectory = {
					flag1 = {
						managed = true,
						repository = "0",
						version = 1,
					},
				}

				local newDirectory = {}

				local updatedDirectory, managedChanges, userChanges =
					serializeFlagsToDirectory(oldDirectory, newDirectory, {
						flag1 = {
							change = {
								active = true,
								retired = false,
								ruleSets = {},
							},
						},
					})

				expect((next(userChanges))).never.to.be.ok()

				expect(managedChanges["0"]).to.be.ok()
				expect(managedChanges["0"].flag1).to.be.ok()
				expect(managedChanges["0"].flag1.version).to.equal(2)

				expect(updatedDirectory).to.be.ok()
				expect(updatedDirectory.flag1).to.be.ok()
				expect(updatedDirectory.flag1.version).to.equal(2)
			end
		)

		it(
			"should place new entries into a repository if it contains fewer than 1024 flags",
			function()
				local oldDirectory = {}
				local newDirectory = {}

				for i = 1, 1023 do
					newDirectory["flag" .. i] = {
						managed = true,
						repository = "0",
						version = 1,
					}
				end

				local updatedDirectory, managedChanges, userChanges =
					serializeFlagsToDirectory(oldDirectory, newDirectory, {
						flag1024 = {
							change = {
								active = true,
								retired = false,
								ruleSets = {},
							},
						},
					})

				expect((next(userChanges))).never.to.be.ok()

				expect(managedChanges["0"]).to.be.ok()
				expect(managedChanges["0"].flag1024).to.be.ok()
				expect(managedChanges["0"].flag1024.version).to.equal(0)

				expect(updatedDirectory).to.be.ok()
				expect(updatedDirectory.flag1024).to.be.ok()
				expect(updatedDirectory.flag1024.version).to.equal(0)
			end
		)

		it(
			"should place new entries into a new repository if it contains 1024 flags or more",
			function()
				local oldDirectory = {}
				local newDirectory = {}

				for i = 1, 1024 do
					newDirectory["flag" .. i] = {
						managed = true,
						repository = "0",
						version = 1,
					}
				end

				local updatedDirectory, managedChanges, userChanges =
					serializeFlagsToDirectory(oldDirectory, newDirectory, {
						flag1025 = {
							change = {
								active = true,
								retired = false,
								ruleSets = {},
							},
						},
					})

				expect((next(userChanges))).never.to.be.ok()

				expect(managedChanges["1"]).to.be.ok()
				expect(managedChanges["1"].flag1025).to.be.ok()
				expect(managedChanges["1"].flag1025.version).to.equal(0)

				expect(updatedDirectory).to.be.ok()
				expect(updatedDirectory.flag1025).to.be.ok()
				expect(updatedDirectory.flag1025.version).to.equal(0)
			end
		)

		it("should place new entries into a the first repository with room", function()
			local oldDirectory = {}
			local newDirectory = {}

			local REPO_0_COUNT = 1024
			local REPO_1_COUNT = 1023
			local REPO_2_COUNT = 1024

			for i = 1, REPO_0_COUNT do
				newDirectory["flag" .. i] = {
					managed = true,
					repository = "0",
					version = 1,
				}
			end

			for i = 1, REPO_1_COUNT do
				newDirectory["flag" .. i + REPO_0_COUNT] = {
					managed = true,
					repository = "1",
					version = 1,
				}
			end

			for i = 1, REPO_2_COUNT do
				newDirectory["flag" .. i + REPO_0_COUNT + REPO_1_COUNT] = {
					managed = true,
					repository = "2",
					version = 1,
				}
			end

			local updatedDirectory, managedChanges, userChanges =
				serializeFlagsToDirectory(oldDirectory, newDirectory, {
					flag3072 = {
						change = {
							active = true,
							retired = false,
							ruleSets = {},
						},
					},
				})

			expect((next(userChanges))).never.to.be.ok()

			expect(managedChanges["1"]).to.be.ok()
			expect(managedChanges["1"].flag3072).to.be.ok()
			expect(managedChanges["1"].flag3072.version).to.equal(0)

			expect(updatedDirectory).to.be.ok()
			expect(updatedDirectory.flag3072).to.be.ok()
			expect(updatedDirectory.flag3072.version).to.equal(0)
		end)
	end)
end
