Skip to content

Commit

Permalink
Argument holes; negative/oob indices
Browse files Browse the repository at this point in the history
- Fixed array/dictionary/set merging not properly handling holes (`nil` values) in arguments.
- Fixed behaviour of negative and out of bounds indices in `Array.insert` (an index of `0` should insert at the end of the array, since arrays are 0-indexed).
  • Loading branch information
cxmeel committed Jun 3, 2022
1 parent 6b1bfd9 commit 95aa755
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 17 deletions.
6 changes: 4 additions & 2 deletions src/Array/concat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ local None = require(Sift.None)
local new = Concat(table1, table2) -- { 1, 2, 3, 4, 5, 6 }
```
]=]
local function concat<T>(...: { T }): { T }
local function concat<T>(...: any): { T }
local result = {}

for _, array in ipairs({ ... }) do
for arrayIndex = 1, select("#", ...) do
local array = select(arrayIndex, ...)

if type(array) ~= "table" then
continue
end
Expand Down
11 changes: 11 additions & 0 deletions src/Array/concat.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ return function()
expect(#new).to.equal(0)
end)

it("should accept nil values", function()
local new = Concat(nil, { 1, 2, 3 })
local new2 = Concat({ 1, 2, 3 }, nil)

expect(new).to.be.a("table")
expect(#new).to.equal(3)

expect(new2).to.be.a("table")
expect(#new2).to.equal(3)
end)

it("should not copy the nested arrays", function()
local table1 = { 1, 2, { 3, 4 } }
local table2 = { 5, 6, { 7, 8 } }
Expand Down
6 changes: 4 additions & 2 deletions src/Array/concatDeep.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ local None = require(Sift.None)
local new = ConcatDeep(table1, table2) -- { 1, 2, { 3, 4 }, 5, 6, { 7, 8 } }
```
]=]
local function concatDeep<T>(...: { T }): { T }
local function concatDeep<T>(...: any): { T }
local result = {}

for _, array in ipairs({ ... }) do
for arrayIndex = 1, select("#", ...) do
local array = select(arrayIndex, ...)

if type(array) ~= "table" then
continue
end
Expand Down
11 changes: 11 additions & 0 deletions src/Array/concatDeep.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ return function()
expect(#new).to.equal(0)
end)

it("should accept nil values", function()
local new = ConcatDeep(nil, { 1, 2, 3 })
local new2 = ConcatDeep({ 1, 2, 3 }, nil)

expect(new).to.be.a("table")
expect(#new).to.equal(3)

expect(new2).to.be.a("table")
expect(#new2).to.equal(3)
end)

it("should join multiple arrays, copying nested arrays", function()
local table1 = { 1, 2, { 3, 4 } }
local table2 = { 5, 6, { 7, 8 } }
Expand Down
13 changes: 12 additions & 1 deletion src/Array/insert.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
Inserts the given values into an array at the given index, shifting all values after it to the right. If the index is negative (or 0), it is counted from the end of the array.
If the index to insert at is out of range, the array is not modified.
```lua
local array = { 1, 2, 3 }
Expand All @@ -20,7 +22,16 @@ local function insert<T>(array: { T }, index: number, ...: T): { T }
local length = #array

if index < 1 then
index += length
index += length + 1
end

if index > length then
if index > length + 1 then
return array
end

index = length + 1
length += 1
end

local result = {}
Expand Down
33 changes: 27 additions & 6 deletions src/Array/insert.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,36 @@ return function()
it("should accept negative indices", function()
local array = { 1, 2, 3 }

local newArray = Insert(array, 0, 4, 5) -- { 1, 2, 4, 5, 3 }
local newArray = Insert(array, 0, 4, 5) -- { 1, 2, 3, 4, 5 }
local newArray2 = Insert(array, -1, 4, 5) -- { 1, 2, 4, 5, 3 }

expect(newArray).to.be.a("table")
expect(#newArray).to.equal(5)
expect(newArray[5]).to.equal(5)

expect(newArray[1]).to.equal(1)
expect(newArray[2]).to.equal(2)
expect(newArray[3]).to.equal(4)
expect(newArray[4]).to.equal(5)
expect(newArray[5]).to.equal(3)
expect(newArray2).to.be.a("table")
expect(#newArray2).to.equal(5)
expect(newArray2[3]).to.equal(4)
expect(newArray2[5]).to.equal(3)
end)

it("should accept length+1", function()
local array = { 1, 2, 3 }

local newArray = Insert(array, 4, 4, 5) -- { 1, 2, 3, 4, 5 }
local newArray2 = Insert(array, 5, 4) -- { 1, 2, 3 }
local newArray3 = Insert(array, 0, 4) -- { 1, 2, 3, 4 }

expect(newArray).to.be.a("table")
expect(#newArray).to.equal(5)
expect(newArray[5]).to.equal(5)

expect(newArray2).to.be.a("table")
expect(#newArray2).to.equal(3)
expect(newArray2[3]).to.equal(3)

expect(newArray3).to.be.a("table")
expect(#newArray3).to.equal(4)
expect(newArray3[4]).to.equal(4)
end)
end
6 changes: 4 additions & 2 deletions src/Dictionary/merge.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ local None = require(Sift.None)
local merged = Merge(dictionary1, dictionary2) -- { hello = "roblox", goodbye = "goodbye" }
```
]=]
local function merge<T>(...: { [any]: any }?): T
local function merge<T>(...: any): T
local result = {}

for _, dictionary in ipairs({ ... }) do
for dictionaryIndex = 1, select("#", ...) do
local dictionary = select(dictionaryIndex, ...)

if type(dictionary) ~= "table" then
continue
end
Expand Down
6 changes: 6 additions & 0 deletions src/Dictionary/merge.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@ return function()
local dictionary1 = { hello = "roblox", goodbye = "world" }

local merged = Merge(dictionary1, nil)
local merged2 = Merge(nil, dictionary1)

expect(merged).to.be.a("table")

expect(merged.hello).to.equal("roblox")
expect(merged.goodbye).to.equal("world")

expect(merged2).to.be.a("table")

expect(merged2.hello).to.equal("roblox")
expect(merged2.goodbye).to.equal("world")
end)

it("should remove values set to None", function()
Expand Down
6 changes: 4 additions & 2 deletions src/Dictionary/mergeDeep.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ local copyDeep = require(script.Parent.copyDeep)
local merged = MergeDeep(dictionary1, dictionary2) -- { hello = "roblox", goodbye = { world = "world" } }
```
]=]
local function mergeDeep<T>(...: { [any]: any }?): T
local function mergeDeep<T>(...: any): T
local result = {}

for _, dictionary in ipairs({ ... }) do
for dictionaryIndex = 1, select("#", ...) do
local dictionary = select(dictionaryIndex, ...)

if type(dictionary) ~= "table" then
continue
end
Expand Down
6 changes: 6 additions & 0 deletions src/Dictionary/mergeDeep.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@ return function()
local dictionary1 = { hello = "roblox", goodbye = { world = "world" } }

local merged = MergeDeep(dictionary1, nil)
local merged2 = MergeDeep(nil, dictionary1)

expect(merged).to.be.a("table")

expect(merged.hello).to.equal("roblox")
expect(merged.goodbye.world).to.equal("world")

expect(merged2).to.be.a("table")

expect(merged2.hello).to.equal("roblox")
expect(merged2.goodbye.world).to.equal("world")
end)

it("should remove values set to None", function()
Expand Down
10 changes: 8 additions & 2 deletions src/Set/merge.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@
local merge = Merge(set1, set2) -- { hello = true, world = true, cat = true, dog = true }
```
]=]
local function merge<T>(...: { [any]: boolean }): { [T]: boolean }
local function merge<T>(...: any): { [T]: boolean }
local result = {}

for _, set in ipairs({ ... }) do
for setIndex = 1, select("#", ...) do
local set = select(setIndex, ...)

if type(set) ~= "table" then
continue
end

for key, _ in pairs(set) do
result[key] = true
end
Expand Down
16 changes: 16 additions & 0 deletions src/Set/merge.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,20 @@ return function()
expect(newSet.panda).to.equal(true)
expect(newSet.cat).to.equal(true)
end)

it("should accept nil values", function()
local set = { hello = true, world = true }
local otherSet = { panda = true, cat = true }

local newSet = merge(set, nil, otherSet)
local newSet2 = merge(nil, set, otherSet)

expect(newSet).to.be.a("table")
expect(newSet.hello).to.equal(true)
expect(newSet.panda).to.equal(true)

expect(newSet2).to.be.a("table")
expect(newSet2.cat).to.equal(true)
expect(newSet2.world).to.equal(true)
end)
end

0 comments on commit 95aa755

Please sign in to comment.