add gs
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
# Generated by Rotriever. Format subject to change in future releases.
|
||||
name = "tutils"
|
||||
version = "0.1.0"
|
||||
commit = "937da4f7f354ebe6cf62348a80cc82fda91be2f0"
|
||||
source = "git+https://github.com/roblox/tutils#master"
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
--[[
|
||||
Returns false if the given table has any of the following:
|
||||
- a key that is neither a number or a string
|
||||
- a mix of number and string keys
|
||||
- number keys which are not exactly 1..#t
|
||||
]]
|
||||
return function(t)
|
||||
local containsNumberKey = false
|
||||
local containsStringKey = false
|
||||
local numberConsistency = true
|
||||
|
||||
local index = 1
|
||||
for x, _ in pairs(t) do
|
||||
if type(x) == 'string' then
|
||||
containsStringKey = true
|
||||
elseif type(x) == 'number' then
|
||||
if index ~= x then
|
||||
numberConsistency = false
|
||||
end
|
||||
containsNumberKey = true
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
if containsStringKey and containsNumberKey then
|
||||
return false
|
||||
end
|
||||
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
if containsNumberKey then
|
||||
return numberConsistency
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
return function()
|
||||
local checkListConsistency = require(script.Parent.checkListConsistency)
|
||||
|
||||
describe("WHEN given a valid table", function()
|
||||
it("SHOULD return true for lists", function()
|
||||
expect(checkListConsistency({ 1, 2, 3 })).to.equal(true)
|
||||
end)
|
||||
|
||||
it("SHOULD return false for lists with holes", function()
|
||||
local list = {
|
||||
[1] = true,
|
||||
[2] = nil,
|
||||
[3] = true,
|
||||
}
|
||||
expect(checkListConsistency(list)).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD return true for dictionary with string keys", function()
|
||||
local dictionary = {
|
||||
foo = "bar",
|
||||
hello = "world",
|
||||
}
|
||||
expect(checkListConsistency(dictionary)).to.equal(true)
|
||||
end)
|
||||
|
||||
it("SHOULD return false for dictionary with mixed keys", function()
|
||||
local dictionary = {
|
||||
foo = "bar",
|
||||
[100] = "hundred",
|
||||
}
|
||||
expect(checkListConsistency(dictionary)).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD return false for dictionary with keys that are not a string or number", function()
|
||||
local dictionary = {
|
||||
[{}] = true,
|
||||
}
|
||||
expect(checkListConsistency(dictionary)).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD return false for dictionary with number keys which are not exactly 1..#t", function()
|
||||
local dictionary = {
|
||||
[1] = "bar",
|
||||
[2] = "foo",
|
||||
[5] = "woof"
|
||||
}
|
||||
expect(checkListConsistency(dictionary)).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
--[[
|
||||
Returns a deep copy of the given table.
|
||||
Both the keys and the values of the table are deep copied.
|
||||
Metatable of the table is copied.
|
||||
If table is used as key in the input table,
|
||||
the deep copy will not be deepEqual to the original.
|
||||
]]
|
||||
|
||||
local function deepCopy(A, seen)
|
||||
if type(A) ~= 'table' then
|
||||
return A
|
||||
end
|
||||
|
||||
if seen and seen[A] then
|
||||
return seen[A]
|
||||
end
|
||||
|
||||
local alreadySeen = seen or {}
|
||||
local newTable = setmetatable({}, getmetatable(A))
|
||||
alreadySeen[A] = newTable
|
||||
for key, value in pairs(A) do
|
||||
newTable[deepCopy(key, alreadySeen)] = deepCopy(value, alreadySeen)
|
||||
end
|
||||
return newTable
|
||||
end
|
||||
|
||||
return deepCopy
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
return function()
|
||||
local deepCopy = require(script.Parent.deepCopy)
|
||||
local deepEqual = require(script.Parent.deepEqual)
|
||||
|
||||
local function deepCopyAndCompare(value)
|
||||
local aDeepCopyOfValue = deepCopy(value)
|
||||
expect(deepEqual(value, aDeepCopyOfValue)).to.equal(true)
|
||||
end
|
||||
|
||||
it("SHOULD work for primitive data types", function()
|
||||
deepCopyAndCompare(true)
|
||||
deepCopyAndCompare(false)
|
||||
deepCopyAndCompare(nil)
|
||||
deepCopyAndCompare(100)
|
||||
deepCopyAndCompare("Deep Copy")
|
||||
end)
|
||||
|
||||
local table1 = {
|
||||
num = 1,
|
||||
innerTable = {
|
||||
innerString = "str"
|
||||
}
|
||||
}
|
||||
local table2 = {
|
||||
num = 1,
|
||||
innerTable = {
|
||||
innerString = "str",
|
||||
innerInnerTable = table1,
|
||||
},
|
||||
}
|
||||
it("SHOULD correctly copy table without table as key ", function()
|
||||
deepCopyAndCompare(table2)
|
||||
|
||||
local deepCopyOfTable2 = deepCopy(table2)
|
||||
|
||||
expect(table2.innerTable).to.never.equal(deepCopyOfTable2.innerTable)
|
||||
expect(deepEqual(table2.innerTable, deepCopyOfTable2.innerTable)).to.equal(true)
|
||||
|
||||
expect(table2.innerTable.innerInnerTable).to.never.equal(deepCopyOfTable2.innerTable.innerInnerTable)
|
||||
expect(deepEqual(table2.innerTable.innerInnerTable, deepCopyOfTable2.innerTable.innerInnerTable)).to.equal(true)
|
||||
end)
|
||||
|
||||
local table3 = {
|
||||
[table1] = table2,
|
||||
}
|
||||
it("SHOULD correctly copy table with table as key", function()
|
||||
local deepCopyOfTable3 = deepCopy(table3)
|
||||
expect(deepEqual(table3, deepCopyOfTable3)).to.equal(false)
|
||||
|
||||
local table3Key, table3Value = next(table3)
|
||||
local deepCopyOfTable3Key, deepCopyOfTable3Value = next(deepCopyOfTable3)
|
||||
expect(table3Key).to.never.equal(deepCopyOfTable3Key)
|
||||
expect(deepEqual(table3Key, deepCopyOfTable3Key)).to.equal(true)
|
||||
expect(table3Value).to.never.equal(deepCopyOfTable3Value)
|
||||
expect(deepEqual(table3Value, deepCopyOfTable3Value)).to.equal(true)
|
||||
end)
|
||||
|
||||
it("SHOULD create only one copy of a table in the table", function()
|
||||
local deepCopyOfTable3 = deepCopy(table3)
|
||||
local key, value = next(deepCopyOfTable3)
|
||||
|
||||
expect(key).to.never.be.equal(table1)
|
||||
expect(key).to.be.equal(value.innerTable.innerInnerTable)
|
||||
expect(deepEqual(key, value.innerTable.innerInnerTable)).to.equal(true)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
--[[
|
||||
Takes two tables A and B, returns if they are deeply equal. ignoreMetatables specifies if metatables should be ignored
|
||||
in the deep compare
|
||||
Assumes tables do not have self-references
|
||||
]]
|
||||
|
||||
local function deepEqual(A, B, ignoreMetatables)
|
||||
if A == B then
|
||||
return true
|
||||
end
|
||||
local AType = type(A)
|
||||
local BType = type(B)
|
||||
if AType ~= BType then
|
||||
return false
|
||||
end
|
||||
if AType ~= "table" then
|
||||
return false
|
||||
end
|
||||
|
||||
if not ignoreMetatables then
|
||||
local mt1 = getmetatable(A)
|
||||
if mt1 and mt1.__eq then
|
||||
--compare using built in method
|
||||
return A == B
|
||||
end
|
||||
end
|
||||
|
||||
local keySet = {}
|
||||
|
||||
for key1, value1 in pairs(A) do
|
||||
local value2 = B[key1]
|
||||
if value2 == nil or not deepEqual(value1, value2, ignoreMetatables) then
|
||||
return false
|
||||
end
|
||||
keySet[key1] = true
|
||||
end
|
||||
|
||||
for key2, _ in pairs(B) do
|
||||
if not keySet[key2] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return deepEqual
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
return function()
|
||||
local deepEqual = require(script.Parent.deepEqual)
|
||||
|
||||
it("SHOULD work for primitive data types", function()
|
||||
expect(deepEqual(1, 1)).to.equal(true)
|
||||
expect(deepEqual("str1", "str1")).to.equal(true)
|
||||
expect(deepEqual(1, 2)).to.equal(false)
|
||||
expect(deepEqual("str1", "str2")).to.equal(false)
|
||||
expect(deepEqual(nil, nil)).to.equal(true)
|
||||
expect(deepEqual(nil, false)).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD correctly identifies deeply-equal tables", function()
|
||||
local table1 = {
|
||||
num = 1,
|
||||
innerTable = {
|
||||
innerString = "str"
|
||||
}
|
||||
}
|
||||
local table2 = {
|
||||
num = 1,
|
||||
innerTable = {
|
||||
innerString = "str"
|
||||
}
|
||||
}
|
||||
expect(deepEqual(table1, table2)).to.equal(true)
|
||||
end)
|
||||
|
||||
it("SHOULD correctly rejects non-deeply-equal tables", function()
|
||||
local table1 = {
|
||||
num = 1,
|
||||
innerTable = {
|
||||
innerString = "str"
|
||||
}
|
||||
}
|
||||
local table2 = {
|
||||
num = 1,
|
||||
innerTable = {
|
||||
innerString = "differentStr"
|
||||
}
|
||||
}
|
||||
expect(deepEqual(table1, table2)).to.equal(false)
|
||||
local table3 = {
|
||||
num = 1,
|
||||
innerTable = {
|
||||
innerString = "str"
|
||||
}
|
||||
}
|
||||
local table4 = {
|
||||
num = 1,
|
||||
innerTableWithDifferentKey = {
|
||||
innerString = "str"
|
||||
}
|
||||
}
|
||||
expect(deepEqual(table3, table4)).to.equal(false)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
--[[
|
||||
Takes two tables A, B and a key, returns if two tables have the same value at key
|
||||
]]
|
||||
|
||||
return function(A, B, key)
|
||||
if A and B and key and key ~= "" and A[key] and B[key] and A[key] == B[key] then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
return function()
|
||||
local equalKey = require(script.Parent.equalKey)
|
||||
|
||||
describe("WHEN given nil values", function()
|
||||
it("SHOULD return false", function()
|
||||
local testCase = function(tableA, tableB)
|
||||
expect(equalKey(tableA, tableB)).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "")).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "key1")).to.equal(false)
|
||||
end
|
||||
|
||||
testCase(nil, nil)
|
||||
testCase(nil, {})
|
||||
testCase({}, nil)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("WHEN given table values", function()
|
||||
it("SHOULD return false if key does not exist in either table (empty tables)", function()
|
||||
local tableA, tableB = {}, {}
|
||||
expect(equalKey(tableA, tableB)).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "")).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "key1")).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD return false if key does not exist in either table (single keys)", function()
|
||||
local tableA = {
|
||||
key1 = "value1",
|
||||
}
|
||||
local tableB = {
|
||||
key2 = "value1",
|
||||
}
|
||||
expect(equalKey(tableA, tableB)).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "")).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "key1")).to.equal(false)
|
||||
end)
|
||||
|
||||
describe("WHEN key exists in both tables", function()
|
||||
it("SHOULD return true if value of key is the same", function()
|
||||
local tableA = {
|
||||
key1 = "value1",
|
||||
}
|
||||
local tableB = {
|
||||
key1 = "value1",
|
||||
}
|
||||
expect(equalKey(tableA, tableB)).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "")).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "key1")).to.equal(true)
|
||||
end)
|
||||
|
||||
it("SHOULD return false if value of key is not the same", function()
|
||||
local tableA = {
|
||||
key1 = "value1",
|
||||
}
|
||||
local tableB = {
|
||||
key1 = "value2",
|
||||
}
|
||||
expect(equalKey(tableA, tableB)).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "")).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "key1")).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
it("should return whether tables are equal to each other at key", function()
|
||||
local tableA = {
|
||||
key1 = "value1",
|
||||
}
|
||||
local tableB = {
|
||||
key1 = "value1",
|
||||
key2 = "value2",
|
||||
}
|
||||
expect(equalKey(tableA, tableB)).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "")).to.equal(false)
|
||||
expect(equalKey(tableA, tableB, "key1")).to.equal(true)
|
||||
expect(equalKey(tableA, tableB, "key2")).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
--[[
|
||||
Takes a table and returns the field count
|
||||
]]
|
||||
return function(t)
|
||||
local fieldCount = 0
|
||||
for _ in pairs(t) do
|
||||
fieldCount = fieldCount + 1
|
||||
end
|
||||
return fieldCount
|
||||
end
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
return function()
|
||||
local fieldCount = require(script.Parent.fieldCount)
|
||||
|
||||
describe("WHEN given empty tables", function()
|
||||
it("SHOULD return zero", function()
|
||||
expect(fieldCount({})).to.equal(0)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("WHEN given a valid dictionary", function()
|
||||
it("should return table's field count", function()
|
||||
local table1 = {
|
||||
key1 = "value1",
|
||||
}
|
||||
expect(fieldCount(table1)).to.equal(1)
|
||||
|
||||
local table2 = {
|
||||
key1 = "value1",
|
||||
key2 = "value2",
|
||||
}
|
||||
expect(fieldCount(table2)).to.equal(2)
|
||||
end)
|
||||
|
||||
it("should return list's count", function()
|
||||
local list1 = {1, 2, 3}
|
||||
expect(fieldCount(list1)).to.equal(3)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
--[[
|
||||
Provides functions for comparing and printing lua tables.
|
||||
]]
|
||||
|
||||
return {
|
||||
checkListConsistency = require(script.checkListConsistency),
|
||||
deepEqual = require(script.deepEqual),
|
||||
deepCopy = require(script.deepCopy),
|
||||
equalKey = require(script.equalKey),
|
||||
fieldCount = require(script.fieldCount),
|
||||
listDifferences = require(script.listDifferences),
|
||||
print = require(script.print)(print),
|
||||
shallowEqual = require(script.shallowEqual),
|
||||
tableDifference = require(script.tableDifference),
|
||||
toString = require(script.toString),
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
local tableDifference = require(script.Parent.tableDifference)
|
||||
|
||||
--[[
|
||||
Takes a list and returns a table whose
|
||||
keys are elements of the list and whose
|
||||
values are all true
|
||||
]]
|
||||
local function membershipTable(list)
|
||||
local result = {}
|
||||
for i = 1, #list do
|
||||
result[list[i]] = true
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
Takes a table and returns a list of keys in that table
|
||||
]]
|
||||
local function listOfKeys(t)
|
||||
local result = {}
|
||||
for key,_ in pairs(t) do
|
||||
table.insert(result, key)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
Takes two lists A and B, returns a new list of elements of A
|
||||
which are not in B
|
||||
]]
|
||||
return function(A, B)
|
||||
return listOfKeys(tableDifference(membershipTable(A), membershipTable(B)))
|
||||
end
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
return function()
|
||||
local listDifferences = require(script.Parent.listDifferences)
|
||||
local expectTable = require(script.Parent.unitTests.expectTable)
|
||||
|
||||
describe("GIVEN two tables", function()
|
||||
describe("WHEN the tables are lists", function()
|
||||
it("SHOULD return an empty table if the lists share the same values", function()
|
||||
local listA = { 1, 2, 3 }
|
||||
local listB = { 1, 2, 3 }
|
||||
expectTable(listDifferences(listA, listB)).toEqual({})
|
||||
end)
|
||||
|
||||
it("SHOULD return a list of delta values if first parameter has extra values", function()
|
||||
local listA = { 1, 2, 3, 4 }
|
||||
local listB = { 1, 2, 3 }
|
||||
expectTable(listDifferences(listA, listB)).toEqual({ 4 })
|
||||
end)
|
||||
|
||||
it("SHOULD return a list of delta values if the second parameter has extra values", function()
|
||||
local listA = { 1, 2, 3 }
|
||||
local listB = { 1, 2, 3, 4 }
|
||||
expectTable(listDifferences(listA, listB)).toEqual({ 4 })
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("WHEN the tables are dictionaries", function()
|
||||
it("SHOULD always return an empty table (same dictionaries)", function()
|
||||
local dictionaryA = { foo = "bar" }
|
||||
local dictionaryB = { foo = "bar" }
|
||||
expectTable(listDifferences(dictionaryA, dictionaryB)).toEqual({})
|
||||
end)
|
||||
|
||||
it("SHOULD always return an empty table (second has extra keys)", function()
|
||||
local dictionaryA = { foo = "bar" }
|
||||
local dictionaryB = { foo = "bar", hello = "world" }
|
||||
expectTable(listDifferences(dictionaryA, dictionaryB)).toEqual({})
|
||||
end)
|
||||
|
||||
it("SHOULD always return an empty table (first has extra keys)", function()
|
||||
local dictionaryA = { foo = "bar" }
|
||||
local dictionaryB = { foo = "bar", hello = "world" }
|
||||
expectTable(listDifferences(dictionaryA, dictionaryB)).toEqual({})
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,73 @@
|
||||
return function(print)
|
||||
local function makeKeyString(key)
|
||||
if type(key) == "string" then
|
||||
return string.format("%s", key)
|
||||
else
|
||||
return string.format("[%s]", tostring(key))
|
||||
end
|
||||
end
|
||||
|
||||
local function makeValueString(value)
|
||||
local valueType = type(value)
|
||||
if valueType == "string" then
|
||||
return string.format("%q", value)
|
||||
elseif valueType == "function" or valueType == "table" then
|
||||
return string.format("<%s>", tostring(value))
|
||||
else
|
||||
return string.format("%s", tostring(value))
|
||||
end
|
||||
end
|
||||
|
||||
local function printKeypair(key, value, indentStr, comment)
|
||||
local keyString = makeKeyString(key)
|
||||
local valueString = makeValueString(value)
|
||||
|
||||
local commentStr = comment and string.format(" -- %s", comment) or ""
|
||||
print(string.format("%s%s = %s,%s", indentStr, keyString, valueString, commentStr))
|
||||
end
|
||||
|
||||
--[[
|
||||
For debugging. Prints the table on multiple lines to overcome log-line length
|
||||
limitations which are otherwise necessary for performance. Use sparingly.
|
||||
]]
|
||||
return function(t, indent)
|
||||
indent = indent or ' '
|
||||
|
||||
if type(t) ~= "table" then
|
||||
error("tutils.Print must be passed a table", 2)
|
||||
end
|
||||
|
||||
-- For cycle detection
|
||||
local printedTables = {}
|
||||
|
||||
local function recurse(subTable, tableKey, level)
|
||||
-- Prevent cycles by keeping track of what tables we have printed
|
||||
printedTables[subTable] = true
|
||||
|
||||
local indentStr = string.rep(indent, level)
|
||||
local valueIndentStr = string.rep(indent, level + 1)
|
||||
|
||||
if tableKey then
|
||||
print(string.format("%s%s = %s {", indentStr, makeKeyString(tableKey), makeValueString(subTable)))
|
||||
else
|
||||
print(string.format("%s%s {", indentStr, makeValueString(subTable)))
|
||||
end
|
||||
|
||||
for key, value in pairs(subTable) do
|
||||
if type(value) == "table" then
|
||||
if printedTables[value] then
|
||||
printKeypair(key, value, valueIndentStr, "Possible cycle")
|
||||
else
|
||||
recurse(value, key, level + 1)
|
||||
end
|
||||
else
|
||||
printKeypair(key, value, valueIndentStr)
|
||||
end
|
||||
end
|
||||
|
||||
print(string.format("%s}%s", indentStr, (level > 0 and "," or "")))
|
||||
end
|
||||
|
||||
recurse(t, nil, 0)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,92 @@
|
||||
return function()
|
||||
local history = {}
|
||||
local mockPrint = function(...)
|
||||
local str = table.concat({ ... }, " " )
|
||||
table.insert(history, str)
|
||||
end
|
||||
local clearHistory = function()
|
||||
history = {}
|
||||
end
|
||||
|
||||
local print = require(script.Parent.print)(mockPrint)
|
||||
|
||||
describe("GIVEN a table", function()
|
||||
it("SHOULD handle an empty table appropriately", function()
|
||||
print({})
|
||||
|
||||
local firstLine = history[1]
|
||||
expect(firstLine:sub(-1)).to.equal("{")
|
||||
local secondLine = history[2]
|
||||
expect(secondLine).to.equal("}")
|
||||
|
||||
clearHistory()
|
||||
end)
|
||||
|
||||
it("SHOULD handle a simple list appropriately", function()
|
||||
print({ 1, 2, 3 })
|
||||
|
||||
local firstLine = history[1]
|
||||
expect(firstLine:sub(-1)).to.equal("{")
|
||||
local lastLine = history[#history]
|
||||
expect(lastLine).to.equal("}")
|
||||
|
||||
local firstElement = history[2]
|
||||
expect(firstElement).to.equal(" [1] = 1,")
|
||||
local secondElement = history[3]
|
||||
expect(secondElement).to.equal(" [2] = 2,")
|
||||
local thirdElement = history[4]
|
||||
expect(thirdElement).to.equal(" [3] = 3,")
|
||||
|
||||
clearHistory()
|
||||
end)
|
||||
|
||||
it("SHOULD handle a simple dictionary appropriately", function()
|
||||
print({ foo = "bar", hello = "world" })
|
||||
|
||||
local firstLine = history[1]
|
||||
expect(firstLine:sub(-1)).to.equal("{")
|
||||
local lastLine = history[#history]
|
||||
expect(lastLine).to.equal("}")
|
||||
|
||||
local firstElement = history[2]
|
||||
expect(firstElement).to.equal(" hello = \"world\",")
|
||||
local secondElement = history[3]
|
||||
expect(secondElement).to.equal(" foo = \"bar\",")
|
||||
|
||||
clearHistory()
|
||||
end)
|
||||
|
||||
it("SHOULD handle a cyclic dictionary by printing a warning", function()
|
||||
local tab = {}
|
||||
tab.element1 = tab
|
||||
print(tab)
|
||||
|
||||
local firstLine = history[1]
|
||||
expect(firstLine:sub(-1)).to.equal("{")
|
||||
local lastLine = history[#history]
|
||||
expect(lastLine).to.equal("}")
|
||||
|
||||
local firstElement = history[2]
|
||||
local isFound = firstElement:find("Possible cycle$")
|
||||
expect(isFound).to.be.ok()
|
||||
|
||||
clearHistory()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("GIVEN anything else", function()
|
||||
it("SHOULD throw", function()
|
||||
expect(function()
|
||||
print(1)
|
||||
end).to.throw()
|
||||
|
||||
expect(function()
|
||||
print(true)
|
||||
end).to.throw()
|
||||
|
||||
expect(function()
|
||||
print("hello world")
|
||||
end).to.throw()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
--[[
|
||||
Takes two tables A and B, returns if they have the same key-value pairs
|
||||
Except ignored keys
|
||||
]]
|
||||
return function(A, B, ignore)
|
||||
if not A or not B then
|
||||
return false
|
||||
elseif A == B then
|
||||
return true
|
||||
end
|
||||
if not ignore then
|
||||
ignore = {}
|
||||
end
|
||||
|
||||
for key, value in pairs(A) do
|
||||
if B[key] ~= value and not ignore[key] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
for key, value in pairs(B) do
|
||||
if A[key] ~= value and not ignore[key] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
return function()
|
||||
local shallowEqual = require(script.Parent.shallowEqual)
|
||||
|
||||
describe("WHEN given nil values", function()
|
||||
it("SHOULD return false if both values are nil", function()
|
||||
expect(shallowEqual(nil, nil)).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD return false if either value is nil", function()
|
||||
expect(shallowEqual(nil, {})).to.equal(false)
|
||||
expect(shallowEqual({}, nil)).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("WHEN given similar table values", function()
|
||||
it("SHOULD return true for two empty tables", function()
|
||||
expect(shallowEqual({}, {})).to.equal(true)
|
||||
end)
|
||||
|
||||
it("SHOULD return true for one key dictionaries", function()
|
||||
local tableA = {
|
||||
key1 = "value1",
|
||||
}
|
||||
local tableB = {
|
||||
key1 = "value1",
|
||||
}
|
||||
expect(shallowEqual(tableA, tableB)).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("WHEN given dissimilar table values", function()
|
||||
it("SHOULD return false for same key, different values", function()
|
||||
local tableA = {
|
||||
key1 = "value1",
|
||||
}
|
||||
local tableB = {
|
||||
key1 = "value2",
|
||||
}
|
||||
expect(shallowEqual(tableA, tableB)).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD return false for different keys, same values", function()
|
||||
local tableA = {
|
||||
key1 = "value1",
|
||||
}
|
||||
local tableB = {
|
||||
key2 = "value1",
|
||||
}
|
||||
expect(shallowEqual(tableA, tableB)).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD return false for different keys, different values", function()
|
||||
local tableA = {
|
||||
key1 = "value1",
|
||||
}
|
||||
local tableB = {
|
||||
key2 = "value2",
|
||||
}
|
||||
expect(shallowEqual(tableA, tableB)).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD return false for extra keys", function()
|
||||
local tableA = {
|
||||
key1 = "value1",
|
||||
}
|
||||
local tableB = {
|
||||
key1 = "value1",
|
||||
key2 = "value2",
|
||||
}
|
||||
expect(shallowEqual(tableA, tableB)).to.equal(false)
|
||||
end)
|
||||
|
||||
it("SHOULD return false if the different table value exist in inner level of nesting tables", function()
|
||||
local tableA = {
|
||||
value1 = "value1",
|
||||
value2 = {
|
||||
innerValue1 = "value2",
|
||||
innerValue2 = "value3",
|
||||
}
|
||||
}
|
||||
local tableB = {
|
||||
value1 = "value1",
|
||||
value2 = {
|
||||
innerValue1 = "value2",
|
||||
innerValue2 = "value4",
|
||||
}
|
||||
}
|
||||
expect(shallowEqual(tableA, tableB)).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("WHEN given ignore table", function()
|
||||
it("SHOULD return true if the different table value exist in ignore table", function()
|
||||
local tableA = {
|
||||
value1 = "value1",
|
||||
value2 = "value2",
|
||||
}
|
||||
local tableB = {
|
||||
value1 = "value1",
|
||||
value2 = "value1",
|
||||
}
|
||||
local ignore = {
|
||||
value2 = "value1",
|
||||
}
|
||||
expect(shallowEqual(tableA, tableB, ignore)).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
--[[
|
||||
Takes two tables A and B, returns a new table with elements of A
|
||||
which are either not keys in B or have a different value in B
|
||||
]]
|
||||
return function(A, B)
|
||||
local new = {}
|
||||
|
||||
for keyA, valueA in pairs(A) do
|
||||
if B[keyA] ~= A[keyA] then
|
||||
new[keyA] = valueA
|
||||
end
|
||||
end
|
||||
|
||||
for keyB, valueB in pairs(B) do
|
||||
if B[keyB] ~= A[keyB] then
|
||||
new[keyB] = valueB
|
||||
end
|
||||
end
|
||||
|
||||
return new
|
||||
end
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
return function()
|
||||
local tableDifference = require(script.Parent.tableDifference)
|
||||
local expectTable = require(script.Parent.unitTests.expectTable)
|
||||
|
||||
describe("WHEN given two tables", function()
|
||||
it("SHOULD return an empty table if lists are the same", function()
|
||||
local listA = {1, 2, 3}
|
||||
local listB = {1, 2, 3}
|
||||
|
||||
expectTable(tableDifference(listA, listB)).toEqual({})
|
||||
end)
|
||||
|
||||
it("SHOULD return a dictionary of the key value if the first list has an extra value", function()
|
||||
local listA = {1, 2, 3, 4}
|
||||
local listB = {1, 2, 3}
|
||||
|
||||
expectTable(tableDifference(listA, listB)).toEqual({[4] = 4})
|
||||
end)
|
||||
|
||||
it("SHOULD return a dictionary of the key value if the second list has an extra value", function()
|
||||
local listA = {1, 2, 3}
|
||||
local listB = {1, 2, 3, 4}
|
||||
|
||||
expectTable(tableDifference(listA, listB)).toEqual({ [4] = 4 })
|
||||
end)
|
||||
|
||||
it("SHOULD return a dictionary of the key value if a dictionary has an extra value", function()
|
||||
local dictionaryA = { foo = "bar", hello = "world" }
|
||||
local dictionaryB = { foo = "bar" }
|
||||
|
||||
expectTable(tableDifference(dictionaryA, dictionaryB)).toEqual({ hello = "world" })
|
||||
end)
|
||||
|
||||
it("SHOULD return a dictionary of the second table's key value if the key has different value in two tables", function()
|
||||
local dictionaryA = { foo = "foo" }
|
||||
local dictionaryB = { foo = "bar" }
|
||||
|
||||
expectTable(tableDifference(dictionaryA, dictionaryB)).toEqual({ foo = "bar" })
|
||||
end)
|
||||
|
||||
it("SHOULD return both keys and their value if there are 2 keys with same value in 2 tables", function()
|
||||
local dictionaryA = { foo = "bar", hello = "world" }
|
||||
local dictionaryB = { bar = "bar", hello = "world" }
|
||||
|
||||
expectTable(tableDifference(dictionaryA, dictionaryB)).toEqual({ foo = "bar", bar = "bar" })
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
local checkListConsistency = require(script.Parent.checkListConsistency)
|
||||
|
||||
--[[
|
||||
Serializes the given table to a reasonable string that might even interpret as lua.
|
||||
]]
|
||||
local function recursiveToString(t, indent)
|
||||
indent = indent or ''
|
||||
|
||||
if type(t) == 'table' then
|
||||
local result = ""
|
||||
if not checkListConsistency(t) then
|
||||
result = result .. "-- WARNING: this table fails the list consistency test\n"
|
||||
end
|
||||
result = result .. "{\n"
|
||||
for k,v in pairs(t) do
|
||||
if type(k) == 'string' then
|
||||
result = result
|
||||
.. " "
|
||||
.. indent
|
||||
.. tostring(k)
|
||||
.. " = "
|
||||
.. recursiveToString(v, " "..indent)
|
||||
..";\n"
|
||||
end
|
||||
if type(k) == 'number' then
|
||||
result = result .. " " .. indent .. recursiveToString(v, " "..indent)..",\n"
|
||||
end
|
||||
end
|
||||
result = result .. indent .. "}"
|
||||
return result
|
||||
else
|
||||
return tostring(t)
|
||||
end
|
||||
end
|
||||
|
||||
return recursiveToString
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
return function()
|
||||
local toString = require(script.Parent.toString)
|
||||
|
||||
describe("WHEN given a table", function()
|
||||
it("SHOULD handle simple lists", function()
|
||||
local indent = "."
|
||||
local result = toString({ 1, 2, 3 }, indent)
|
||||
|
||||
expect(result).to.equal("{\n .1,\n .2,\n .3,\n.}")
|
||||
end)
|
||||
|
||||
it("SHOULD handle simple dictionaries", function()
|
||||
local indent = "."
|
||||
local result = toString({ hello = "world" }, indent)
|
||||
|
||||
expect(result).to.equal("{\n .hello = world;\n.}")
|
||||
end)
|
||||
|
||||
it("SHOULD handle tables within tables", function()
|
||||
local indent = "."
|
||||
local result = toString({ {} }, indent)
|
||||
|
||||
expect(result).to.equal("{\n .{\n .},\n.}")
|
||||
end)
|
||||
|
||||
it("SHOULD show a warning for mixed tables", function()
|
||||
local result = toString({ 1, 2, hello = "world" })
|
||||
local findResult = result:find("WARNING: this table fails the list consistency test")
|
||||
expect(findResult).to.be.ok()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("WHEN given anything else", function()
|
||||
it("SHOULD return the tostring equivalent", function()
|
||||
expect(toString(1)).to.equal(tostring(1))
|
||||
expect(toString(true)).to.equal(tostring(true))
|
||||
expect(toString("hello")).to.equal(tostring("hello"))
|
||||
end)
|
||||
end)
|
||||
end
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
local shallowEqual = require(script.Parent.Parent.shallowEqual)
|
||||
local toString = require(script.Parent.Parent.toString)
|
||||
|
||||
local function expectTable(tab)
|
||||
return {
|
||||
toEqual = function(value)
|
||||
assert(
|
||||
shallowEqual(tab, value),
|
||||
string.format("expected: %s\ninstead got: %s", toString(value), toString(tab))
|
||||
)
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
return expectTable
|
||||
Reference in New Issue
Block a user