Skip to content

Commit

Permalink
Fix some asserts, add tablex.sub
Browse files Browse the repository at this point in the history
  • Loading branch information
andrew-d committed Feb 22, 2013
1 parent 07d0be6 commit 8d55cb5
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 42 deletions.
97 changes: 55 additions & 42 deletions spec/tablex_spec.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
local tx = require('tablex')


local function assert_lists_equal(l1, l2)
assert.is_true(tx.compare(l1, l2))
end

describe("Table extension library", function()
describe('copy', function()
local t, c
Expand Down Expand Up @@ -83,7 +78,7 @@ describe("Table extension library", function()
describe('sort', function()
it('will return the original table', function()
local t = {3, 2, 1}
assert.equal(tx.sort(t), t)
assert.same(tx.sort(t), t)
end)
end)

Expand Down Expand Up @@ -121,31 +116,27 @@ describe("Table extension library", function()
it('will return the keys of a table', function()
local ks = tx.keys({foo='bar', asdf='baz'})

assert.equal(ks[1], 'foo')
assert.equal(ks[2], 'asdf')
assert.same({'foo', 'asdf'}, ks)
end)

it('will return the keys of a list-like table', function()
local ks = tx.keys({1, 2})

assert.equal(ks[1], 1)
assert.equal(ks[2], 2)
assert.same({1,2}, ks)
end)
end)

describe('values', function()
it('will return the values of a table', function()
local vs = tx.values({foo='bar', asdf='baz'})

assert.equal(vs[1], 'bar')
assert.equal(vs[2], 'baz')
assert.same({'bar', 'baz'}, vs)
end)

it('will return the values of a list-like table', function()
local vs = tx.values({3, 4})

assert.equal(vs[1], 3)
assert.equal(vs[2], 4)
assert.same({3, 4}, vs)
end)
end)

Expand Down Expand Up @@ -179,9 +170,7 @@ describe("Table extension library", function()

tx.update(t, u)

assert.equal(t[1], 1)
assert.equal(t[2], 2)
assert.equal(t['foo'], 'bar')
assert.same({1,2,foo='bar'}, t)
end)

it('will overwrite the existing values', function()
Expand All @@ -190,15 +179,14 @@ describe("Table extension library", function()

tx.update(t, u)

assert.equal(t[1], 1)
assert.equal(t['foo'], 'bar')
assert.same({1,foo='bar'}, t)
end)
end)

describe('range', function()
local function assert_range(t, ...)
local ra = tx.range(...)
assert_lists_equal(ra, t)
assert.same(t, ra)
end

it('will generate a simple range', function()
Expand Down Expand Up @@ -232,9 +220,7 @@ describe("Table extension library", function()
local t = {1, 3, foo='bar'}
local u = tx.transpose(t)

assert.equal(u[1], 1)
assert.equal(u[3], 2)
assert.equal(u['bar'], 'foo')
assert.same({1,[3]=2,bar='foo'}, u)
end)

it('will do nothing to an empty table', function()
Expand Down Expand Up @@ -345,9 +331,7 @@ describe("Table extension library", function()

local t = tx.map({1,2,foo=3}, map_fn)

assert.equal(t[1], 2)
assert.equal(t[2], 3)
assert.equal(t['foo'], 4)
assert.same({2,3,foo=4}, t)
end)

it('will copy the metatable', function()
Expand All @@ -365,10 +349,8 @@ describe("Table extension library", function()
local t = {1,2,foo=3}
local u = tx.transform(t, function(x) return x + 1 end)

assert.same({2,3,foo=4}, u)
assert.equal(u, t)
assert.equal(u[1], 2)
assert.equal(u[2], 3)
assert.equal(u['foo'], 4)
end)
end)

Expand All @@ -377,9 +359,7 @@ describe("Table extension library", function()
local t = {1,2,foo=3}
local u = tx.mapi(t, function(x) return x + 1 end)

assert.equal(u[1], 2)
assert.equal(u[2], 3)
assert.equal(u['foo'], nil)
assert.same({2,3,foo=nil}, u)
end)

it('will copy the metatable', function()
Expand All @@ -395,41 +375,45 @@ describe("Table extension library", function()
describe('mapn', function()
it('will map a single table', function()
local ret = tx.mapn(function(x) return x + 1 end, {1,2,3})
assert_lists_equal(ret, {2,3,4})
assert.same({2,3,4}, ret)
end)

it('will map multiple tables', function()
local ret = tx.mapn(function(x, y) return x + y end, {1,2,3}, {3,2,1})
assert_lists_equal(ret, {4,4,4})
assert.same({4,4,4}, ret)
end)

it('properly handles no tables', function()
assert_lists_equal({}, tx.mapn(function() end, {}))
assert.same(tx.mapn(function() end, {}), {})
end)

it('will truncate to the shortest list', function()
local ret = tx.mapn(function(x, y) return x + y end, {1,2,3}, {1,2})
assert_lists_equal(ret, {2,4})
assert.same({2,4}, ret)
end)
end)

describe('reduce', function()
local function add(x, y) return x + y end

it('will reduce a simple sequence', function()
assert.equal(tx.reduce({1,2,3}, add), 6)
assert.equal(6, tx.reduce({1,2,3}, add))
end)

it('will reduce with a default value', function()
assert.equal(tx.reduce({1,2,3}, add, 4), 10)
assert.equal(10, tx.reduce({1,2,3}, add, 4))
end)

it('will reduce an empty sequence to nil', function()
assert.equal(tx.reduce({}, add), nil)
assert.equal(nil, tx.reduce({}, add))
end)

it('will reduce an empty sequence with initial to initial', function()
assert.equal(tx.reduce({}, add, 1), 1)
assert.equal(1, tx.reduce({}, add, 1))
end)

it('is also aliased as "foldl"', function()
assert.equal(tx.reduce, tx.foldl)
end)
end)

Expand All @@ -438,7 +422,7 @@ describe("Table extension library", function()
local z = tx.zip(...)
assert.equal(#z, num)
for i, v in ipairs(z) do
assert_lists_equal(res[i], v)
assert.same(res[i], v)
end
end

Expand All @@ -462,7 +446,7 @@ describe("Table extension library", function()
local z = tx.zipn(...)
assert.equal(#z, num)
for i, v in ipairs(z) do
assert_lists_equal(res[i], v)
assert.same(res[i], v)
end
end

Expand All @@ -485,4 +469,33 @@ describe("Table extension library", function()
end)
end)

-- Note that this also tests normalize_slice too.
describe('sub', function()
local t = {1,2,3,4,5,6,7,8,9,10}

it('will extract simple ranges from the list', function()
assert.same({3,4,5}, tx.sub(t, 3, 5))
end)

it('will extract given just a start', function()
assert.same({8,9,10}, tx.sub(t, 8))
end)

it('will extract given just a end', function()
assert.same({1,2,3}, tx.sub(t, nil, 3))
end)

it('supports using negative start indexes', function()
assert.same({8,9,10}, tx.sub(t, -3))
end)

it('supports using negative end indexes', function()
assert.same({1,2,3}, tx.sub(t, nil, -8))
end)

it('supports both negative indexes', function()
assert.same({8,9}, tx.sub(t, -3, -2))
end)
end)

end)
42 changes: 42 additions & 0 deletions src/tablex.lua
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ end

-------------------------------------------------------------------------------
-- Apply a function to all values of a table, modifying the table in-place.
-- This is the same as the map() function, except it operates in-place.
-- @param t The table
-- @param func A function that takes 1 or more arguments
-- @param ... Any additional arguments to pass to the function
Expand Down Expand Up @@ -426,6 +427,7 @@ end
-- If the 'initial' parameter is given, then it will also act as the default
-- value if the sequence is empty. Otherwise, if the sequence is empty and
-- no initial value is given, this function will return nil.
-- Note: this function is aliased as "foldl".
-- @param t The table
-- @param func A function that takes two arguments and returns a single value
-- @param initial (optional) The initial value to use. If present, this is
Expand All @@ -451,6 +453,7 @@ function reduce(t, func, initial)

return ret
end
foldl = reduce


-------------------------------------------------------------------------------
Expand Down Expand Up @@ -505,6 +508,45 @@ function zipn(...)
end


-- Normalize given values of a slice (i.e. t[start:end] in python terms)
function normalize_slice(t, start, fin)
local len = #t

start = start or 1
fin = fin or len

if start < 0 then
start = len + start + 1
end

if fin < 0 then
fin = len + fin + 1
end

return start, fin
end


-------------------------------------------------------------------------------
-- Extract a range of values from a list-like table.
-- @param t A list-like table
-- @param start If given, the start index. Defaults to 1, negative indexes are
-- from the end of the table.
-- @param fin If given, the end index. Defaults to #t, negative indexes are
-- from the end of the table.
-- @return A list-like table with the contents of the specified slice.
function sub(t, start, fin)
start, fin = normalize_slice(t, start, fin)

local ret = {}
for i = start,fin do
table.insert(ret, t[i])
end

return ret
end


-- We need to exclude certain things from being patched (mainly, the patch
-- function itself).
patch = nil
Expand Down

0 comments on commit 8d55cb5

Please sign in to comment.