Changed Telescope to busted

master
Yonaba 2018-08-22 23:46:50 +00:00
parent 883948808e
commit 66970fbe7c
13 changed files with 1364 additions and 1461 deletions

52
.luacov Normal file
View File

@ -0,0 +1,52 @@
--- Global configuration file. Copy, customize and store in your
-- project folder as '.luacov' for project specific configuration
-- @class module
-- @name luacov.defaults
return {
-- default filename to load for config options if not provided
-- only has effect in 'luacov.defaults.lua'
['configfile'] = '.luacov',
-- filename to store stats collected
['statsfile'] = 'luacov.stats.out',
-- filename to store report
['reportfile'] = 'luacov.report.out',
-- Run reporter on completion? (won't work for ticks)
runreport = true,
-- Delete stats file after reporting?
deletestats = true,
-- Patterns for files to include when reporting
-- all will be included if nothing is listed
-- (exclude overrules include, do not include
-- the .lua extension)
['include'] = {
'moses'
},
-- Patterns for files to exclude when reporting
-- all will be included if nothing is listed
-- (exclude overrules include, do not include
-- the .lua extension)
['exclude'] = {
'luacov$',
'luacov.reporter$',
'luacov.defaults$',
'luacov.runner$',
'luacov.stats$',
'luacov.tick$',
'mediator.*$',
'busted$',
'busted.*$',
'luassert.*$',
'pl.*$',
'say.*$',
'spec.*$'
},
}

View File

@ -1,33 +1,32 @@
language: c
language: python
sudo: false
env:
global:
- LUAROCKS=2.3.0
matrix:
- LUA=lua5.1
- LUA=lua5.2
- LUA=lua5.3
- LUA=luajit # latest stable version (2.0.4)
- LUA=luajit2.0 # current head of 2.0 branch
- LUA=luajit2.1 # current head of 2.1 branc
branches:
only:
- master
- LUA="lua=5.1"
- LUA="lua=5.2"
- LUA="lua=5.3"
- LUA="luajit=2.0"
- LUA="luajit=2.1"
before_install:
- source .travis/setenv_lua.sh
- pip install --user cpp-coveralls
- luarocks install Lua-cURL --server=https://luarocks.org/dev
- luarocks install luacov-coveralls --server=https://luarocks.org/dev
- luarocks install telescope 0.6.0 --server=http://rocks.moonscript.org
- pip install hererocks
- hererocks lua_install -r^ --$LUA
- export PATH=$PATH:$PWD/lua_install/bin # Add directory with all installed binaries to PATH
script: "tsc -f spec/*"
install:
- luarocks install busted
- luarocks install luacov
- luarocks install luacov-coveralls
script:
- busted --verbose --coverage
after_success:
- luacov-coveralls -c specs/.luacov
- luacov-coveralls --exclude $TRAVIS_BUILD_DIR/lua_install
branches:
except:
- gh-pages
notifications:
email:

View File

@ -1,15 +0,0 @@
if [ -z "${PLATFORM:-}" ]; then
PLATFORM=$TRAVIS_OS_NAME;
fi
if [ "$PLATFORM" == "osx" ]; then
PLATFORM="macosx";
fi
if [ -z "$PLATFORM" ]; then
if [ "$(uname)" == "Linux" ]; then
PLATFORM="linux";
else
PLATFORM="macosx";
fi;
fi

View File

@ -1,3 +0,0 @@
export PATH=${PATH}:$HOME/.lua:$HOME/.local/bin:${TRAVIS_BUILD_DIR}/install/luarocks/bin
bash .travis/setup_lua.sh
eval `$HOME/.lua/luarocks path`

View File

@ -1,122 +0,0 @@
#! /bin/bash
# A script for setting up environment for travis-ci testing.
# Sets up Lua and Luarocks.
# LUA must be "lua5.1", "lua5.2" or "lua5.3" or "luajit".
# luajit2.0 - master v2.0
# luajit2.1 - master v2.1
set -eufo pipefail
LUAJIT_VERSION="2.0.4"
LUAJIT_BASE="LuaJIT-$LUAJIT_VERSION"
source .travis/platform.sh
LUA_HOME_DIR=$TRAVIS_BUILD_DIR/install/lua
LR_HOME_DIR=$TRAVIS_BUILD_DIR/install/luarocks
mkdir $HOME/.lua
LUAJIT="no"
if [ "$PLATFORM" == "macosx" ]; then
if [ "$LUA" == "luajit" ]; then
LUAJIT="yes";
fi
if [ "$LUA" == "luajit2.0" ]; then
LUAJIT="yes";
fi
if [ "$LUA" == "luajit2.1" ]; then
LUAJIT="yes";
fi;
elif [ "$(expr substr $LUA 1 6)" == "luajit" ]; then
LUAJIT="yes";
fi
mkdir -p "$LUA_HOME_DIR"
if [ "$LUAJIT" == "yes" ]; then
if [ "$LUA" == "luajit" ]; then
curl --location https://github.com/LuaJIT/LuaJIT/archive/v$LUAJIT_VERSION.tar.gz | tar xz;
else
git clone https://github.com/LuaJIT/LuaJIT.git $LUAJIT_BASE;
fi
cd $LUAJIT_BASE
if [ "$LUA" == "luajit2.1" ]; then
git checkout v2.1;
# force the INSTALL_TNAME to be luajit
perl -i -pe 's/INSTALL_TNAME=.+/INSTALL_TNAME= luajit/' Makefile
fi
make && make install PREFIX="$LUA_HOME_DIR"
ln -s $LUA_HOME_DIR/bin/luajit $HOME/.lua/luajit
ln -s $LUA_HOME_DIR/bin/luajit $HOME/.lua/lua;
else
if [ "$LUA" == "lua5.1" ]; then
curl http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz
cd lua-5.1.5;
elif [ "$LUA" == "lua5.2" ]; then
curl http://www.lua.org/ftp/lua-5.2.4.tar.gz | tar xz
cd lua-5.2.4;
elif [ "$LUA" == "lua5.3" ]; then
curl http://www.lua.org/ftp/lua-5.3.5.tar.gz | tar xz
cd lua-5.3.2;
fi
# Build Lua without backwards compatibility for testing
perl -i -pe 's/-DLUA_COMPAT_(ALL|5_2)//' src/Makefile
make $PLATFORM
make INSTALL_TOP="$LUA_HOME_DIR" install;
ln -s $LUA_HOME_DIR/bin/lua $HOME/.lua/lua
ln -s $LUA_HOME_DIR/bin/luac $HOME/.lua/luac;
fi
cd $TRAVIS_BUILD_DIR
lua -v
LUAROCKS_BASE=luarocks-$LUAROCKS
curl --location http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz | tar xz
cd $LUAROCKS_BASE
if [ "$LUA" == "luajit" ]; then
./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.0" --prefix="$LR_HOME_DIR";
elif [ "$LUA" == "luajit2.0" ]; then
./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.0" --prefix="$LR_HOME_DIR";
elif [ "$LUA" == "luajit2.1" ]; then
./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.1" --prefix="$LR_HOME_DIR";
else
./configure --with-lua="$LUA_HOME_DIR" --prefix="$LR_HOME_DIR"
fi
make build && make install
ln -s $LR_HOME_DIR/bin/luarocks $HOME/.lua/luarocks
cd $TRAVIS_BUILD_DIR
luarocks --version
rm -rf $LUAROCKS_BASE
if [ "$LUAJIT" == "yes" ]; then
rm -rf $LUAJIT_BASE;
elif [ "$LUA" == "lua5.1" ]; then
rm -rf lua-5.1.5;
elif [ "$LUA" == "lua5.2" ]; then
rm -rf lua-5.2.4;
elif [ "$LUA" == "lua5.3" ]; then
rm -rf lua-5.3.2;
fi

View File

@ -94,10 +94,10 @@ Find a complete set of code examples in [tutorial.md](https://github.com/Yonaba/
## Specification
Run [spec tests](https://github.com/Yonaba/Moses/blob/master/spec) from Lua using [Telescope](https://github.com/norman/telescope) with the following command from the root folder:
Run [spec tests](https://github.com/Yonaba/Moses/blob/master/spec) from Lua using [busted](https://github.com/Olivine-Labs/busted/) with the following command from the root folder:
````
lua tsc -f spec/*
busted
````
## License

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +1,34 @@
require 'luacov'
local _ = require 'moses'
local M = require 'moses'
context('Chaining specs', function()
describe('Chaining specs', function()
context('chain', function()
describe('chain', function()
test('Chains a value',function()
local v = _.chain({1,2,3,4})
:filter(function(i,k) return k%2~=0 end)
it('Chains a value',function()
local v = M.chain({1,2,3,4})
:filter(function(k) return k%2~=0 end)
:max()
:value()
assert_equal(v, 3)
assert.equal(v, 3)
end)
test('_(value) is the same as _.chain(value)', function()
local v = _({1,2,3,4})
:filter(function(i,k) return k%2~=0 end)
it('M(value) is the same as M.chain(value)', function()
local v = M({1,2,3,4})
:filter(function(k) return k%2~=0 end)
:max()
:value()
assert_equal(v, 3)
assert.equal(v, 3)
end)
end)
context('value', function()
describe('value', function()
test('Unwraps a chained object',function()
it('Unwraps a chained object',function()
local t = {1,2,3}
assert_equal(_.chain(t):value(), t)
assert_equal(_(t):value(), t)
assert.equal(M.chain(t):value(), t)
assert.equal(M(t):value(), t)
end)
end)

View File

@ -1,46 +1,46 @@
require 'luacov'
local M = require 'moses'
context('Utility functions specs', function()
describe('Utility functions specs', function()
context('noop', function()
describe('noop', function()
test('the no-operation function',function()
assert_nil(M.noop())
assert_nil(M.noop(nil))
assert_nil(M.noop(false))
assert_nil(M.noop({}))
assert_nil(M.noop(function() end))
assert_nil(M.noop(M.noop))
it('the no-operation function',function()
assert.is_nil(M.noop())
assert.is_nil(M.noop(nil))
assert.is_nil(M.noop(false))
assert.is_nil(M.noop({}))
assert.is_nil(M.noop(function() end))
assert.is_nil(M.noop(M.noop))
end)
end)
context('identity', function()
describe('identity', function()
test('returns the received value',function()
assert_equal(M.identity(1),1)
it('returns the received value',function()
assert.equal(M.identity(1),1)
local v = {x = 0}
assert_equal(M.identity(v),v)
assert_not_equal(v,{x = 0})
assert.equal(M.identity(v),v)
assert.is_not.equals(v,{x = 0})
end)
end)
context('constant', function()
describe('constant', function()
test('creates a constant function',function()
it('creates a constant function',function()
local gravity = M.constant(9.81)
assert_equal(gravity(),9.81)
assert_equal(gravity(10), 9.81)
assert_equal(gravity(nil), 9.81)
assert.equal(gravity(),9.81)
assert.equal(gravity(10), 9.81)
assert.equal(gravity(nil), 9.81)
end)
end)
context('applySpec', function()
describe('applySpec', function()
test('returns a spec function which produces objects',function()
it('returns a spec function which produces objects',function()
local stats = M.applySpec({
min = function(...) return math.min(...) end,
max = function(...) return math.max(...) end,
@ -52,219 +52,219 @@ context('Utility functions specs', function()
table.sort(t)
local unpack = unpack or table.unpack
local r = stats(unpack(t))
assert_equal(r.min, t[1])
assert_equal(r.max, t[#t])
assert.equal(r.min, t[1])
assert.equal(r.max, t[#t])
end
end)
end)
context('memoize', function()
describe('memoize', function()
local fib_time, fib_value, mfib_time, mfib_value
local fib, mfib
test('memoizes an expensive function by caching its results',function()
it('memoizes an expensive function by caching its results',function()
local function fib(n) return n < 2 and n or fib(n-1)+fib(n-2) end
local mfib = M.memoize(fib)
assert_equal(fib(10), mfib(10))
assert_equal(fib(15), mfib(15))
assert_equal(fib(8), mfib(8))
assert_equal(fib(13), mfib(13))
assert.equal(fib(10), mfib(10))
assert.equal(fib(15), mfib(15))
assert.equal(fib(8), mfib(8))
assert.equal(fib(13), mfib(13))
end)
end)
context('unfold', function()
describe('unfold', function()
test('builds a list from a seed value using a iterator',function()
it('builds a list from a seed value using a iterator',function()
local function iter(seed)
if seed < 100 then return seed, seed * 2 end
end
assert_true(M.isEqual(M.unfold(iter,1),{1,2,4,8,16,32,64}))
assert_true(M.isEqual(M.unfold(iter,5),{5, 10,20,40,80}))
assert_true(M.isEqual(M.unfold(iter,10),{10,20,40,80}))
assert.is_true(M.isEqual(M.unfold(iter,1),{1,2,4,8,16,32,64}))
assert.is_true(M.isEqual(M.unfold(iter,5),{5, 10,20,40,80}))
assert.is_true(M.isEqual(M.unfold(iter,10),{10,20,40,80}))
end)
end)
context('once', function()
describe('once', function()
test('returns a version of a function that runs once',function()
it('returns a version of a function that runs once',function()
local sq = M.once(function(a) return a*a end)
assert_equal(sq(2),4)
assert.equal(sq(2),4)
end)
test('successive calls will keep yielding the original answer',function()
it('successive calls will keep yielding the original answer',function()
local sq = M.once(function(a) return a*a end)
for i = 1,10 do
assert_equal(sq(i),1)
assert.equal(sq(i),1)
end
end)
end)
context('before', function()
describe('before', function()
test('returns a version of a function that runs no more than count-th calls',function()
it('returns a version of a function that runs no more than count-th calls',function()
local function say(something) return something end
local speak3times = M.before(say, 3)
assert_equal(speak3times('a'), 'a')
assert_equal(speak3times('b'), 'b')
assert_equal(speak3times('c'), 'c')
assert_equal(speak3times('d'), 'c')
assert_equal(speak3times('e'), 'c')
assert_equal(speak3times('f'), 'c')
assert.equal(speak3times('a'), 'a')
assert.equal(speak3times('b'), 'b')
assert.equal(speak3times('c'), 'c')
assert.equal(speak3times('d'), 'c')
assert.equal(speak3times('e'), 'c')
assert.equal(speak3times('f'), 'c')
end)
end)
context('after', function()
describe('after', function()
test('returns a function that will respond on its count-th call',function()
it('returns a function that will respond on its count-th call',function()
local function a(r) return (r) end
a = M.after(a,5)
for i = 1,10 do
if i < 5 then
assert_nil(a(i))
assert.is_nil(a(i))
else
assert_equal(a(i),i)
assert.equal(a(i),i)
end
end
end)
end)
context('compose', function()
describe('compose', function()
test('can compose commutative functions',function()
it('can compose commutative functions',function()
local greet = function(name) return "hi: " .. name end
local exclaim = function(sentence) return sentence .. "!" end
assert_equal(M.compose(greet,exclaim)('moe'),'hi: moe!')
assert_equal(M.compose(exclaim,greet)('moe'),'hi: moe!')
assert.equal(M.compose(greet,exclaim)('moe'),'hi: moe!')
assert.equal(M.compose(exclaim,greet)('moe'),'hi: moe!')
end)
test('composes mutiple functions',function()
it('composes mutiple functions',function()
local function f(x) return x^2 end
local function g(x) return x+1 end
local function h(x) return x/2 end
local compositae = M.compose(f,g,h)
assert_equal(compositae(10),36)
assert_equal(compositae(20),121)
assert.equal(compositae(10),36)
assert.equal(compositae(20),121)
end)
test('compose non commutative functions in reverse order',function()
it('compose non commutative functions in reverse order',function()
local function f(s) return (s or '')..'f' end
local function g(s) return (s or '')..'g' end
local function h(s) return (s or '')..'h' end
assert_equal(M.compose(f,g,h)(),'hgf')
assert_equal(M.compose(h,g,f)(),'fgh')
assert_equal(M.compose(f,h,g)(),'ghf')
assert_equal(M.compose(g,h,f)(),'fhg')
assert.equal(M.compose(f,g,h)(),'hgf')
assert.equal(M.compose(h,g,f)(),'fgh')
assert.equal(M.compose(f,h,g)(),'ghf')
assert.equal(M.compose(g,h,f)(),'fhg')
end)
end)
context('pipe', function()
describe('pipe', function()
test('pipes a value through a series of functions',function()
it('pipes a value through a series of functions',function()
local function f(x) return x^2 end
local function g(x) return x+1 end
local function h(x) return x/2 end
assert_equal(M.pipe(10,f,g,h),36)
assert_equal(M.pipe(20,f,g,h),121)
assert.equal(M.pipe(10,f,g,h),36)
assert.equal(M.pipe(20,f,g,h),121)
end)
end)
context('complement', function()
describe('complement', function()
test('returns a function which returns the logical complement of a given function',function()
assert_false(M.complement(function() return true end)())
assert_true(M.complement(function() return false end)())
assert_true(M.complement(function() return nil end)())
assert_false(M.complement(function() return 1 end)())
it('returns a function which returns the logical complement of a given function',function()
assert.is_false(M.complement(function() return true end)())
assert.is_true(M.complement(function() return false end)())
assert.is_true(M.complement(function() return nil end)())
assert.is_false(M.complement(function() return 1 end)())
end)
end)
context('juxtapose', function()
describe('juxtapose', function()
test('calls a sequence of functions with the same set of args',function()
it('calls a sequence of functions with the same set of args',function()
local function f(x) return x^2 end
local function g(x) return x+1 end
local function h(x) return x/2 end
local rf, rg, rh = M.juxtapose(10, f, g, h)
assert_equal(rf, 100)
assert_equal(rg, 11)
assert_equal(rh, 5)
assert.equal(rf, 100)
assert.equal(rg, 11)
assert.equal(rh, 5)
end)
end)
context('wrap', function()
describe('wrap', function()
test('wraps a function and passes args',function()
it('wraps a function and passes args',function()
local greet = function(name) return "hi: " .. name end
local backwards = M.wrap(greet, function(f,arg)
return f(arg) ..'\nhi: ' .. arg:reverse()
end)
assert_equal(backwards('john'),'hi: john\nhi: nhoj')
assert.equal(backwards('john'),'hi: john\nhi: nhoj')
end)
end)
context('times', function()
describe('times', function()
test('calls a given function n times',function()
it('calls a given function n times',function()
local f = ('Lua programming'):gmatch('.')
local r = M.times(f, 3)
assert_true(M.isEqual(r,{'L','u','a'}))
assert.is_true(M.isEqual(r,{'L','u','a'}))
local count = 0
local function counter() count = count+1 end
M.times(counter, 10)
assert_equal(count,10)
assert.equal(count,10)
end)
end)
context('bind', function()
describe('bind', function()
test('binds a value to the first arg of a function',function()
it('binds a value to the first arg of a function',function()
local sqrt2 = M.bind(math.sqrt,2)
assert_equal(sqrt2(),math.sqrt(2))
assert.equal(sqrt2(),math.sqrt(2))
end)
end)
context('bind2', function()
describe('bind2', function()
test('binds a value to the second arg of a function',function()
it('binds a value to the second arg of a function',function()
local last2 = M.bind2(M.last,2)
local r = last2({1,2,3,4,5,6})
assert_true(M.isEqual(r, {5,6}))
assert.is_true(M.isEqual(r, {5,6}))
end)
end)
context('bindn', function()
describe('bindn', function()
test('binds n values to as the n-first args of a function',function()
it('binds n values to as the n-first args of a function',function()
local function out(...)
return table.concat {...}
end
out = M.bindn(out,'OutPut',':',' ')
assert_equal(out(1,2,3),'OutPut: 123')
assert_equal(out('a','b','c','d'),'OutPut: abcd')
assert.equal(out(1,2,3),'OutPut: 123')
assert.equal(out('a','b','c','d'),'OutPut: abcd')
end)
end)
context('bindall', function()
describe('bindall', function()
test('binds methods to object',function()
it('binds methods to object',function()
local window = {
setPos = function(w,x,y) w.x, w.y = x, y end,
setName = function(w,name) w.name = name end,
@ -274,17 +274,17 @@ context('Utility functions specs', function()
window.setPos(10,15)
window.setName('fooApp')
assert_equal(window.x, 10)
assert_equal(window.y, 15)
assert_equal(window.name, 'fooApp')
assert_equal(window.getName(), 'fooApp')
assert.equal(window.x, 10)
assert.equal(window.y, 15)
assert.equal(window.name, 'fooApp')
assert.equal(window.getName(), 'fooApp')
end)
end)
context('cond', function()
describe('cond', function()
test('return a function which runs a set of predicates',function()
it('return a function which runs a set of predicates',function()
local multipleOf = M.cond({
{function(v) return v%2==0 end, function(v) return v..' is multiple of 2' end},
{function(v) return v%3==0 end, function(v) return v..' is multiple of 3' end},
@ -292,7 +292,7 @@ context('Utility functions specs', function()
{function() return true end, function(v) return 'could not find an answer for '..v end}
})
for i = 15, 20 do
assert_equal(multipleOf(i),
assert.equal(multipleOf(i),
i%2 == 0 and i..' is multiple of 2' or
i%3 == 0 and i..' is multiple of 3' or
'could not find an answer for '..i)
@ -301,346 +301,342 @@ context('Utility functions specs', function()
end)
context('uniqueId', function()
describe('uniqueId', function()
test('returns an unique (for the current session) integer Id',function()
it('returns an unique (for the current session) integer Id',function()
local ids = {}
for i = 1,100 do
local newId = M.uniqueId()
assert_false(M.include(ids,newId))
assert.is_false(M.include(ids,newId))
M.push(ids,newId)
end
end)
test('accepts a string template to format the returned id',function()
it('accepts a string template to format the returned id',function()
local ids = {}
for i = 1,100 do
local newId = M.uniqueId('ID:%s')
assert_equal(newId,'ID:'..newId:sub(4))
assert_false(M.include(ids,newId))
assert.equal(newId,'ID:'..newId:sub(4))
assert.is_false(M.include(ids,newId))
M.push(ids,newId)
end
end)
test('accepts a function as argument to format the returned id',function()
it('accepts a function as argument to format the returned id',function()
local ids = {}
local formatter = function(ID) return '$'..ID..'$' end
for i = 1,100 do
local newId = M.uniqueId(formatter)
assert_not_nil(newId:match('^%$%d+%$$'))
assert_false(M.include(ids,newId))
assert.is_true(newId:match('^%$%d+%$$') ~= nil)
assert.is_false(M.include(ids,newId))
M.push(ids,newId)
end
end)
end)
context('iterator', function()
describe('iterator', function()
test('creates an iterator which continuously applies f on an input',function()
it('creates an iterator which continuously applies f on an input',function()
local next_even = M.iterator(function(x) return x + 2 end, 0)
assert_equal(next_even(), 2)
assert_equal(next_even(), 4)
assert_equal(next_even(), 6)
assert_equal(next_even(), 8)
assert_equal(next_even(),10)
assert.equal(next_even(), 2)
assert.equal(next_even(), 4)
assert.equal(next_even(), 6)
assert.equal(next_even(), 8)
assert.equal(next_even(),10)
end)
test('can be set to run up to a maximum number of calls',function()
it('can be set to run up to a maximum number of calls',function()
local next_even = M.iterator(function(x) return x + 2 end, 0, 3)
assert_equal(next_even(), 2)
assert_equal(next_even(), 4)
assert_equal(next_even(), 6)
assert_nil(next_even())
assert.equal(next_even(), 2)
assert.equal(next_even(), 4)
assert.equal(next_even(), 6)
assert.is_nil(next_even())
end)
end)
context('array', function()
describe('array', function()
test('iterates a given iterator and returns its values in an array',function()
it('iterates a given iterator and returns its values in an array',function()
local letters = M.array(('Lua'):gmatch('.'))
assert_true(M.isEqual(letters,{'L','u','a'}))
assert.is_true(M.isEqual(letters,{'L','u','a'}))
local numbers = M.array(pairs(M.range(1,10)))
assert_true(M.isEqual(numbers,M.range(1,10)))
assert.is_true(M.isEqual(numbers,M.range(1,10)))
end)
end)
context('castArray', function()
describe('castArray', function()
test('converts value to an array',function()
assert_true(M.isEqual(M.castArray(1),{1}))
assert_true(M.isEqual(M.castArray(print),{print}))
assert_true(M.isEqual(M.castArray(true),{true}))
it('converts value to an array',function()
assert.is_true(M.isEqual(M.castArray(1),{1}))
assert.is_true(M.isEqual(M.castArray(print),{print}))
assert.is_true(M.isEqual(M.castArray(true),{true}))
end)
test('leaves given value untouched if it is an array',function()
it('leaves given value untouched if it is an array',function()
local t1 = {1,2}
local t2 = {nil, true, false}
assert_true(M.isEqual(M.castArray(t1),t1))
assert_true(M.isEqual(M.castArray(t2),t2))
assert.is_true(M.isEqual(M.castArray(t1),t1))
assert.is_true(M.isEqual(M.castArray(t2),t2))
end)
end)
context('flip', function()
describe('flip', function()
test('creates a function which runs f with arguments flipped',function()
it('creates a function which runs f with arguments flipped',function()
local function f(...) return table.concat({...}) end
local flipped = M.flip(f)
assert_equal(flipped('a','b','c'),'cba')
assert.equal(flipped('a','b','c'),'cba')
end)
end)
context('nthArg', function()
describe('nthArg', function()
test('creates a function which returns the nth arg',function()
it('creates a function which returns the nth arg',function()
local f2 = M.nthArg(2)
local f3 = M.nthArg(3)
local f4 = M.nthArg(4)
assert_equal(f2(4,8,5,4,6),8)
assert_equal(f3(4,8,5,4,6),5)
assert_equal(f4(4,8,5,4,6),4)
assert.equal(f2(4,8,5,4,6),8)
assert.equal(f3(4,8,5,4,6),5)
assert.equal(f4(4,8,5,4,6),4)
end)
test('if n is negative, will count from the end',function()
it('if n is negative, will count from the end',function()
local f2 = M.nthArg(-2)
local f3 = M.nthArg(-3)
local f4 = M.nthArg(-4)
assert_equal(f2(4,8,5,4,6),4)
assert_equal(f3(4,8,5,4,6),5)
assert_equal(f4(4,8,5,4,6),8)
assert.equal(f2(4,8,5,4,6),4)
assert.equal(f3(4,8,5,4,6),5)
assert.equal(f4(4,8,5,4,6),8)
end)
end)
context('unary', function()
describe('unary', function()
test('creates a function which accepts only one arg',function()
it('creates a function which accepts only one arg',function()
local f = M.unary(function(...) return ... end)
assert_equal(f(1),1)
assert_equal(f(1,2),1)
assert_equal(f(1,2,3),1)
assert.equal(f(1),1)
assert.equal(f(1,2),1)
assert.equal(f(1,2,3),1)
end)
end)
context('ary', function()
describe('ary', function()
test('creates a function which accepts up to n args',function()
it('creates a function which accepts up to n args',function()
local f = M.ary(function(...) return ... end, 2)
assert_true(M.isEqual({f(1,2)},{1,2}))
assert_true(M.isEqual({f(1,2,3)},{1,2}))
assert_true(M.isEqual({f(1,2,3,4)},{1,2}))
assert.is_true(M.isEqual({f(1,2)},{1,2}))
assert.is_true(M.isEqual({f(1,2,3)},{1,2}))
assert.is_true(M.isEqual({f(1,2,3,4)},{1,2}))
end)
end)
context('rearg', function()
describe('rearg', function()
test('creates a function with args reordered',function()
it('creates a function with args reordered',function()
local f = M.rearg(function(...) return ... end, {3,2,1})
assert_true(M.isEqual({f(1,2,3)},{3,2,1}))
assert_true(M.isEqual({f(2,1,3)},{3,1,2}))
assert_true(M.isEqual({f(3,2,1)},{1,2,3}))
assert.is_true(M.isEqual({f(1,2,3)},{3,2,1}))
assert.is_true(M.isEqual({f(2,1,3)},{3,1,2}))
assert.is_true(M.isEqual({f(3,2,1)},{1,2,3}))
end)
end)
context('over', function()
describe('over', function()
test('returns a function which applies a set of transforms to its args',function()
it('returns a function which applies a set of transforms to its args',function()
local minmax = M.over(math.min, math.max)
local maxmin = M.over(math.max, math.min)
assert_true(M.isEqual(minmax(5,10,12,4,3),{3,12}))
assert_true(M.isEqual(maxmin(5,10,12,4,3),{12,3}))
assert.is_true(M.isEqual(minmax(5,10,12,4,3),{3,12}))
assert.is_true(M.isEqual(maxmin(5,10,12,4,3),{12,3}))
end)
end)
context('overEvery', function()
describe('overEvery', function()
local alleven, allpositive
before(function()
alleven = function(...)
for i, v in ipairs({...}) do if v%2~=0 then return false end end
return true
end
alleven = function(...)
for i, v in ipairs({...}) do if v%2~=0 then return false end end
return true
end
allpositive = function(...)
for i, v in ipairs({...}) do if v < 0 then return false end end
return true
end
end)
allpositive = function(...)
for i, v in ipairs({...}) do if v < 0 then return false end end
return true
end
test('checks if all predicates passes truth with args. ',function()
it('checks if all predicates passes truth with args. ',function()
local allok = M.overEvery(alleven, allpositive)
assert_false(allok(2,4,-1,8))
assert_false(allok(10,3,2,6))
assert_true(allok(8,4,6,10))
assert.is_false(allok(2,4,-1,8))
assert.is_false(allok(10,3,2,6))
assert.is_true(allok(8,4,6,10))
end)
end)
context('overSome', function()
describe('overSome', function()
local alleven, allpositive
before(function()
alleven = function(...)
for i, v in ipairs({...}) do if v%2~=0 then return false end end
return true
end
alleven = function(...)
for i, v in ipairs({...}) do if v%2~=0 then return false end end
return true
end
allpositive = function(...)
for i, v in ipairs({...}) do if v < 0 then return false end end
return true
end
end)
allpositive = function(...)
for i, v in ipairs({...}) do if v < 0 then return false end end
return true
end
test('checks if all predicates passes truth with args. ',function()
it('checks if all predicates passes truth with args. ',function()
local anyok = M.overSome(alleven, allpositive)
assert_false(anyok(2,4,-1,8))
assert_true(anyok(10,3,2,6))
assert_false(anyok(-1,-5,-3))
assert.is_false(anyok(2,4,-1,8))
assert.is_true(anyok(10,3,2,6))
assert.is_false(anyok(-1,-5,-3))
end)
end)
context('overArgs', function()
describe('overArgs', function()
test('Creates a function that invokes `f` with its arguments transformed',function()
it('Creates a function that invokes `f` with its arguments transformed',function()
local function f(x, y) return {x, y} end
local function triple(x) return x*3 end
local function square(x) return x^2 end
local new_f = M.overArgs(f, triple, square)
assert_true(M.isEqual(new_f(1,2), {3,4}))
assert_true(M.isEqual(new_f(10,10), {30,100}))
assert.is_true(M.isEqual(new_f(1,2), {3,4}))
assert.is_true(M.isEqual(new_f(10,10), {30,100}))
end)
test('when supplied more args than transforms, remaining are left as-is',function()
it('when supplied more args than transforms, remaining are left as-is',function()
local function f(x, y, z, k) return {x, y, z, k} end
local function triple(x) return x*3 end
local function square(x) return x^2 end
local new_f = M.overArgs(f, triple, square)
assert_true(M.isEqual(new_f(1,2,3,4), {3,4,3,4}))
assert_true(M.isEqual(new_f(10,10,10,10), {30,100,10,10}))
assert.is_true(M.isEqual(new_f(1,2,3,4), {3,4,3,4}))
assert.is_true(M.isEqual(new_f(10,10,10,10), {30,100,10,10}))
end)
end)
context('converge', function()
describe('converge', function()
test('', function()
it('', function()
local function pow2(x) return x*x end
local function pow3(x) return x*x*x end
local function sum(a,b) return a+b end
local poly = M.converge(sum, pow2, pow3)
assert_equal(poly(5), 150)
assert_equal(poly(1), 2)
assert_equal(poly(3), 36)
assert.equal(poly(5), 150)
assert.equal(poly(1), 2)
assert.equal(poly(3), 36)
end)
end)
context('partial', function()
describe('partial', function()
test('applies partially f',function()
it('applies partially f',function()
local function diff(a, b) return a - b end
local diffFrom20 = M.partial(diff, 20)
assert_equal(diffFrom20(5), 15)
assert_equal(diffFrom20(10), 10)
assert_equal(diffFrom20(-5), 25)
assert.equal(diffFrom20(5), 15)
assert.equal(diffFrom20(10), 10)
assert.equal(diffFrom20(-5), 25)
end)
test('\'_\' can be used as a placeholder',function()
it('\'_\' can be used as a placeholder',function()
local function diff(a, b) return a - b end
local remove10 = M.partial(diff, '_',10)
assert_equal(remove10(5), -5)
assert_equal(remove10(10), 0)
assert_equal(remove10(15), 5)
assert.equal(remove10(5), -5)
assert.equal(remove10(10), 0)
assert.equal(remove10(15), 5)
end)
end)
context('partialRight', function()
describe('partialRight', function()
test('applies partial but from the right',function()
it('applies partial but from the right',function()
local function concat(a,b,c,d) return a..b..c..d end
assert_equal(M.partialRight(concat,'a','b','c')('d'), 'dabc')
assert_equal(M.partialRight(concat,'a','b')('c','d'), 'cdab')
assert_equal(M.partialRight(concat,'a')('b','c','d'), 'bcda')
assert.equal(M.partialRight(concat,'a','b','c')('d'), 'dabc')
assert.equal(M.partialRight(concat,'a','b')('c','d'), 'cdab')
assert.equal(M.partialRight(concat,'a')('b','c','d'), 'bcda')
end)
test('\'_\' can be used as a placeholder',function()
it('\'_\' can be used as a placeholder',function()
local function concat(a,b,c,d) return a..b..c..d end
assert_equal(M.partialRight(concat,'a','_','c')('d','b'), 'badc')
assert_equal(M.partialRight(concat,'a','b','_')('c','d'), 'dabc')
assert_equal(M.partialRight(concat,'_','a')('b','c','d'), 'cdba')
assert.equal(M.partialRight(concat,'a','_','c')('d','b'), 'badc')
assert.equal(M.partialRight(concat,'a','b','_')('c','d'), 'dabc')
assert.equal(M.partialRight(concat,'_','a')('b','c','d'), 'cdba')
end)
end)
context('curry', function()
describe('curry', function()
test('curries a function for a specific number of args',function()
it('curries a function for a specific number of args',function()
local function sumOf5args(a,b,c,d,e) return a+b+c+d+e end
local curried_sumOf5args = M.curry(sumOf5args, 5)
assert_equal(curried_sumOf5args(1)(2)(3)(4)(5),15)
assert_equal(curried_sumOf5args(8)(-2)(4)(-10)(1),1)
assert.equal(curried_sumOf5args(1)(2)(3)(4)(5),15)
assert.equal(curried_sumOf5args(8)(-2)(4)(-10)(1),1)
end)
test('n_args defaults to 2 when not supplied',function()
it('n_args defaults to 2 when not supplied',function()
local function prod(x,y) return x*y end
local curried_prod = M.curry(prod)
assert_equal(curried_prod(2)(3), (M.curry(prod,2))(2)(3))
assert_equal(curried_prod(-2)(6), (M.curry(prod,2))(-2)(6))
assert.equal(curried_prod(2)(3), (M.curry(prod,2))(2)(3))
assert.equal(curried_prod(-2)(6), (M.curry(prod,2))(-2)(6))
end)
test('n_args can be equal to 1',function()
it('n_args can be equal to 1',function()
local curried_identity = M.curry(M.identity,1)
assert_equal(curried_identity('value'), 'value')
assert_equal(curried_identity(1), 1)
assert_equal(curried_identity(true), true)
assert_equal(curried_identity(false), false)
assert.equal(curried_identity('value'), 'value')
assert.equal(curried_identity(1), 1)
assert.equal(curried_identity(true), true)
assert.equal(curried_identity(false), false)
end)
test('giving more args than n_args will raise an error',function()
it('giving more args than n_args will raise an error',function()
local function add(a,b) return a+b end
local curried_add = M.curry(add, 2)
assert_error(function() curried_add(1)(2)(3) end)
assert_error(function() curried_add(4)(5)(6)(7)(8) end)
assert.error(function() curried_add(1)(2)(3) end)
assert.error(function() curried_add(4)(5)(6)(7)(8) end)
end)
test('When given less than n_args, it will wait for missing args',function()
it('When given less than n_args, it will wait for missing args',function()
local function add(a,b,c) return a+b+c end
local curried_add = M.curry(add, 3)
local c1 = curried_add(1)
local c2 = c1(2)
local c3 = c2(3)
assert_type(c1, 'function')
assert_type(c2, 'function')
assert_equal(c3, 6)
assert.equal(type(c1), 'function')
assert.equal(type(c2), 'function')
assert.equal(c3, 6)
end)
end)
context('time', function()
describe('time', function()
test('returns the execution time of a function and its results', function()
it('returns the execution time of a function and its results', function()
local function f(...) return ... end
local duration, r = M.time(f, 'a')
assert_type(duration, 'number')
assert_equal(r, 'a')
assert.equal(type(duration), 'number')
assert.equal(r, 'a')
local duration, a, b, c = M.time(f, 1, 2, 3)
assert_type(duration, 'number')
assert_true(a == 1 and b == 2 and c == 3)
assert.equal(type(duration), 'number')
assert.is_true(a == 1 and b == 2 and c == 3)
end)
end)

View File

@ -1,20 +1,20 @@
require 'luacov'
local _ = require 'moses'
local M = require 'moses'
context('Import specs', function()
describe('Import specs', function()
test('imports all library function to a given context', function()
local funcs = _.functions()
local context = _.import({})
assert_true(_.all(funcs, function(n) return _.has(context, n) end))
it('imports all library function to a given context', function()
local funcs = M.functions()
local context = M.import({})
assert.is_true(M.all(funcs, function(n) return M.has(context, n) end))
end)
test('passing "noConflict" will preserve already existing keys', function()
local funcs = _.functions()
local context = _.import({each = 1, all = 2}, true)
assert_true(_.all(funcs, function(n) return _.has(context, n) end))
assert_equal(context.each, 1)
assert_equal(context.all, 2)
it('passing "noConflict" will preserve already existing keys', function()
local funcs = M.functions()
local context = M.import({each = 1, all = 2}, true)
assert.is_true(M.all(funcs, function(n) return M.has(context, n) end))
assert.equal(context.each, 1)
assert.equal(context.all, 2)
end)
end)

View File

@ -1,31 +1,31 @@
require 'luacov'
local M = require 'moses'
context('Object functions specs', function()
describe('Object functions specs', function()
context('keys', function()
describe('keys', function()
test('collects a given object attributes',function()
assert_true(M.isEqual(M.keys({1,2,3}),{1,2,3}))
assert_true(M.isEqual(M.keys({4,5,6}),{1,2,3}))
assert_true(M.same(M.keys({x = 1, y = 2, 3}),{'x','y',1}))
it('collects a given object attributes',function()
assert.is_true(M.isEqual(M.keys({1,2,3}),{1,2,3}))
assert.is_true(M.isEqual(M.keys({4,5,6}),{1,2,3}))
assert.is_true(M.same(M.keys({x = 1, y = 2, 3}),{'x','y',1}))
end)
end)
context('values', function()
describe('values', function()
test('collects an given object values',function()
assert_true(M.isEqual(M.values({1,2,3}),{1,2,3}))
assert_true(M.isEqual(M.values({4,5,6}),{4,5,6}))
assert_true(M.same(M.values({x = 1, y = 2, 3}),{1,2,3}))
it('collects an given object values',function()
assert.is_true(M.isEqual(M.values({1,2,3}),{1,2,3}))
assert.is_true(M.isEqual(M.values({4,5,6}),{4,5,6}))
assert.is_true(M.same(M.values({x = 1, y = 2, 3}),{1,2,3}))
end)
end)
context('path', function()
describe('path', function()
test('return the value at a given path in object',function()
it('return the value at a given path in object',function()
local entity = {
pos = {x = 1},
engine = {
@ -34,176 +34,176 @@ context('Object functions specs', function()
},
boost = false
}
assert_equal(M.path(entity, 'pos','x'), 1)
assert_equal(M.path(entity, 'engine','left','status'), 'active')
assert_equal(M.path(entity, 'engine','right','damage'), 10)
assert_equal(M.path(entity, 'boost'), false)
assert_nil(M.path(entity, 'x'))
assert.equal(M.path(entity, 'pos','x'), 1)
assert.equal(M.path(entity, 'engine','left','status'), 'active')
assert.equal(M.path(entity, 'engine','right','damage'), 10)
assert.equal(M.path(entity, 'boost'), false)
assert.is_nil(M.path(entity, 'x'))
end)
end)
context('kvpairs', function()
describe('kvpairs', function()
test('converts key-values pairs in object to array-list of k,v pairs',function()
it('converts key-values pairs in object to array-list of k,v pairs',function()
local obj = M.kvpairs({x = 1, y = 2, z = 3})
table.sort(obj, function(a,b) return a[1] < b[1] end)
assert_true(M.isEqual(obj[1],{'x',1}))
assert_true(M.isEqual(obj[2],{'y',2}))
assert_true(M.isEqual(obj[3],{'z',3}))
assert.is_true(M.isEqual(obj[1],{'x',1}))
assert.is_true(M.isEqual(obj[2],{'y',2}))
assert.is_true(M.isEqual(obj[3],{'z',3}))
end)
end)
context('toObj', function()
describe('toObj', function()
test('converts an array-list of {k,v} pairs to an object',function()
it('converts an array-list of {k,v} pairs to an object',function()
local obj = M.toObj({{'x',1},{'y',2},{'z',3}})
assert_equal(obj.x,1)
assert_equal(obj.y,2)
assert_equal(obj.z,3)
assert.equal(obj.x,1)
assert.equal(obj.y,2)
assert.equal(obj.z,3)
end)
end)
context('property', function()
describe('property', function()
test('Returns a function that will return the key property of any passed-in object.',function()
assert_equal(M.property('sin')(math), math.sin)
assert_equal(M.property('find')(string), string.find)
assert_equal(M.property('insert')(table), table.insert)
assert_equal(M.property('yield')(coroutine), coroutine.yield)
it('Returns a function that will return the key property of any passed-in object.',function()
assert.equal(M.property('sin')(math), math.sin)
assert.equal(M.property('find')(string), string.find)
assert.equal(M.property('insert')(table), table.insert)
assert.equal(M.property('yield')(coroutine), coroutine.yield)
end)
end)
context('propertyOf', function()
describe('propertyOf', function()
test('Returns a function which will return the value of an object property.',function()
assert_equal(M.propertyOf(math)('cos'), math.cos)
assert_equal(M.propertyOf(string)('char'), string.char)
assert_equal(M.propertyOf(table)('remove'), table.remove)
assert_equal(M.propertyOf(M)('propertyOf'), M.propertyOf)
it('Returns a function which will return the value of an object property.',function()
assert.equal(M.propertyOf(math)('cos'), math.cos)
assert.equal(M.propertyOf(string)('char'), string.char)
assert.equal(M.propertyOf(table)('remove'), table.remove)
assert.equal(M.propertyOf(M)('propertyOf'), M.propertyOf)
end)
end)
context('toBoolean', function()
describe('toBoolean', function()
test('converts a value to a boolean',function()
assert_true(type(M.toBoolean(true)) == 'boolean')
assert_true(type(M.toBoolean(1)) == 'boolean')
assert_true(type(M.toBoolean(false)) == 'boolean')
assert_true(type(M.toBoolean(nil)) == 'boolean')
assert_true(type(M.toBoolean({})) == 'boolean')
assert_true(type(M.toBoolean(1/0)) == 'boolean')
it('converts a value to a boolean',function()
assert.is_true(type(M.toBoolean(true)) == 'boolean')
assert.is_true(type(M.toBoolean(1)) == 'boolean')
assert.is_true(type(M.toBoolean(false)) == 'boolean')
assert.is_true(type(M.toBoolean(nil)) == 'boolean')
assert.is_true(type(M.toBoolean({})) == 'boolean')
assert.is_true(type(M.toBoolean(1/0)) == 'boolean')
assert_true(M.toBoolean(true))
assert_true(M.toBoolean(1))
assert_false(M.toBoolean(false))
assert_false(M.toBoolean(nil))
assert_true(M.toBoolean({}))
assert_true(M.toBoolean(1/0))
assert.is_true(M.toBoolean(true))
assert.is_true(M.toBoolean(1))
assert.is_false(M.toBoolean(false))
assert.is_false(M.toBoolean(nil))
assert.is_true(M.toBoolean({}))
assert.is_true(M.toBoolean(1/0))
end)
end)
context('extend', function()
describe('extend', function()
test('extends a destination objects with key-values a source object',function()
assert_true(M.isEqual(M.extend({},{a = 'b'}),{a = 'b'}))
it('extends a destination objects with key-values a source object',function()
assert.is_true(M.isEqual(M.extend({},{a = 'b'}),{a = 'b'}))
end)
test('source properties overrides destination properties',function()
assert_true(M.isEqual(M.extend({a = 'a'},{a = 'b'}),{a = 'b'}))
it('source properties overrides destination properties',function()
assert.is_true(M.isEqual(M.extend({a = 'a'},{a = 'b'}),{a = 'b'}))
end)
test('leaves source object untouched',function()
it('leaves source object untouched',function()
local source = {i = 'i'}
assert_true(M.isEqual(M.extend({a = 'a'},source),{a = 'a',i = 'i'}))
assert_true(M.isEqual(source,{i = 'i'}))
assert.is_true(M.isEqual(M.extend({a = 'a'},source),{a = 'a',i = 'i'}))
assert.is_true(M.isEqual(source,{i = 'i'}))
end)
test('can extend destination from multiple sources',function()
it('can extend destination from multiple sources',function()
local sourceA = {a = 'a'}; local sourceBC = {b = 'b', c = 'c'}
assert_true(M.isEqual(M.extend({},sourceA, sourceBC),{a = 'a', b = 'b', c = 'c'}))
assert.is_true(M.isEqual(M.extend({},sourceA, sourceBC),{a = 'a', b = 'b', c = 'c'}))
end)
test('extending from multiple source, latter properties overrides',function()
it('extending from multiple source, latter properties overrides',function()
local sourceA = {a = 'a'}; local sourceBC = {b = 'b', a = 'c'}
assert_true(M.isEqual(M.extend({},sourceA, sourceBC),{a = 'c', b = 'b'}))
assert.is_true(M.isEqual(M.extend({},sourceA, sourceBC),{a = 'c', b = 'b'}))
end)
test('will not copy nil values',function()
it('will not copy nil values',function()
local sourceA = {a = nil}; local sourceBC = {b = 'b', c = nil}
assert_true(M.isEqual(M.extend({},sourceA, sourceBC),{b = 'b'}))
assert.is_true(M.isEqual(M.extend({},sourceA, sourceBC),{b = 'b'}))
end)
end)
context('functions', function()
describe('functions', function()
test('collects function names within an object',function()
it('collects function names within an object',function()
local x = {}
function x.a() return end; function x.b() return end
assert_true(M.isEqual(M.functions(x),{'a','b'}))
assert.is_true(M.isEqual(M.functions(x),{'a','b'}))
end)
test('collects metatable functions if "recurseMt" arg is supplied',function()
it('collects metatable functions if "recurseMt" arg is supplied',function()
local x = {} ; x.__index = x
function x.a() return end; function x.b() return end
local xx = setmetatable({},x)
function xx.c() return end
assert_true(M.same(M.functions(xx),{'c'}))
assert_true(M.same(M.functions(xx,true),{'a','b','c'}))
assert.is_true(M.same(M.functions(xx),{'c'}))
assert.is_true(M.same(M.functions(xx,true),{'a','b','c'}))
end)
test('when given no obj as argument, returns all library functions',function()
it('when given no obj as argument, returns all library functions',function()
local functions = M.functions()
M.each(functions, function(v)
assert_true(M.isFunction(M[v]))
assert.is_true(M.isFunction(M[v]))
end)
end)
end)
context('clone', function()
describe('clone', function()
test('clones the attributes of an object',function()
it('clones the attributes of an object',function()
local vector = {x = 0, y = 0}
assert_true(M.isEqual(M.clone(vector),vector))
assert.is_true(M.isEqual(M.clone(vector),vector))
end)
test('By default, cloning is deep (clones nested tables)',function()
it('By default, cloning is deep (clones nested tables)',function()
local particle = {position = {x = 0,y=0},mass = 1}
local particle_clone = M.clone (particle)
assert_true(M.isEqual(particle_clone,particle))
assert.is_true(M.isEqual(particle_clone,particle))
particle_clone.position.x = 3
assert_false(M.isEqual(particle_clone,particle))
assert.is_false(M.isEqual(particle_clone,particle))
end)
test('Unless "shallow" arg is provided',function()
it('Unless "shallow" arg is provided',function()
local particle = {position = {x = 0,y=0},mass = 1}
local particle_clone = M.clone (particle,true)
assert_true(M.isEqual(particle_clone,particle))
assert.is_true(M.isEqual(particle_clone,particle))
particle_clone.position.x = 3
assert_true(M.isEqual(particle_clone,particle))
assert.is_true(M.isEqual(particle_clone,particle))
end)
test('Non objects are simply returned',function()
assert_equal(M.clone(1),1)
assert_equal(M.clone(false),false)
assert_equal(M.clone(true),true)
assert_equal(M.clone(nil),nil)
assert_equal(M.clone('hello'),'hello')
assert_equal(M.clone(print),print)
it('Non objects are simply returned',function()
assert.equal(M.clone(1),1)
assert.equal(M.clone(false),false)
assert.equal(M.clone(true),true)
assert.equal(M.clone(nil),nil)
assert.equal(M.clone('hello'),'hello')
assert.equal(M.clone(print),print)
end)
end)
context('tap', function()
describe('tap', function()
test('tap-into a method chain', function()
it('tap-into a method chain', function()
local t = {}
local catchMax = function(k) t[#t+1] = M.max(k) end
local catchMin = function(k) t[#t+1] = M.min(k) end
@ -215,418 +215,418 @@ context('Object functions specs', function()
:tap(catchMin)
:value()
assert_equal(t[1],6)
assert_equal(t[2],4)
assert.equal(t[1],6)
assert.equal(t[2],4)
end)
end)
context('has', function()
describe('has', function()
test('checks if an object has an attribute',function()
assert_true(M.has(M,'has'))
assert_true(M.has(table,'concat'))
assert_true(M.has(string,'format'))
assert_true(M.has(os,'time'))
assert_true(M.has(math,'random'))
it('checks if an object has an attribute',function()
assert.is_true(M.has(M,'has'))
assert.is_true(M.has(table,'concat'))
assert.is_true(M.has(string,'format'))
assert.is_true(M.has(os,'time'))
assert.is_true(M.has(math,'random'))
end)
end)
context('pick', function()
describe('pick', function()
test('collect specified properties',function()
it('collect specified properties',function()
local object = {a = 1, b = 2, c = 3}
assert_true(M.isEqual(M.pick(object,'a','c'),{a = 1, c = 3}))
assert.is_true(M.isEqual(M.pick(object,'a','c'),{a = 1, c = 3}))
end)
test('given args can be nested as well',function()
it('given args can be nested as well',function()
local object = {a = 1, b = 2, c = 3}
assert_true(M.isEqual(M.pick(object,{{'b','a'}},'c'),{a = 1,b = 2, c = 3}))
assert.is_true(M.isEqual(M.pick(object,{{'b','a'}},'c'),{a = 1,b = 2, c = 3}))
end)
test('will ignore properties the object do not have',function()
it('will ignore properties the object do not have',function()
local object = {a = 1, b = 2, c = 3}
assert_true(M.isEqual(M.pick(object,{{'k'}},'c'),{c = 3}))
assert.is_true(M.isEqual(M.pick(object,{{'k'}},'c'),{c = 3}))
end)
test('returns an empty table when given no properties to pick',function()
it('returns an empty table when given no properties to pick',function()
local object = {a = 1, b = 2, c = 3}
assert_true(M.isEqual(M.pick(object),{}))
assert.is_true(M.isEqual(M.pick(object),{}))
end)
test('should also pick attributes having falsy values',function()
it('should also pick attributes having falsy values',function()
local object = {a = false, b = false, c = true}
assert_true(M.isEqual(M.pick(object,'a','b'),{a = false,b = false}))
assert.is_true(M.isEqual(M.pick(object,'a','b'),{a = false,b = false}))
end)
end)
context('omit', function()
describe('omit', function()
test('collect all properties leaving those given as args',function()
it('collect all properties leaving those given as args',function()
local object = {a = 1, b = 2, c = 3}
assert_true(M.isEqual(M.omit(object,'a','c'),{b=2}))
assert.is_true(M.isEqual(M.omit(object,'a','c'),{b=2}))
end)
test('given args can be nested as well',function()
it('given args can be nested as well',function()
local object = {a = 1, b = 2, c = 3}
assert_true(M.isEqual(M.omit(object,{{'b'}},'c'),{a = 1}))
assert.is_true(M.isEqual(M.omit(object,{{'b'}},'c'),{a = 1}))
end)
test('will ignore properties the object do not have',function()
it('will ignore properties the object do not have',function()
local object = {a = 1, b = 2, c = 3}
assert_true(M.isEqual(M.omit(object,{{'k'}},'c'),{a = 1, b=2}))
assert.is_true(M.isEqual(M.omit(object,{{'k'}},'c'),{a = 1, b=2}))
end)
test('returns the original object clone when given no properties to omit',function()
it('returns the original object clone when given no properties to omit',function()
local object = {a = 1, b = 2, c = 3}
assert_true(M.isEqual(M.omit(object),{a = 1, b = 2, c = 3}))
assert.is_true(M.isEqual(M.omit(object),{a = 1, b = 2, c = 3}))
end)
end)
context('template', function()
describe('template', function()
test('applies a template on an object',function()
assert_true(M.isEqual(M.template({},{a = 1, b = 2, c = 3}),{a = 1, b = 2, c = 3}))
it('applies a template on an object',function()
assert.is_true(M.isEqual(M.template({},{a = 1, b = 2, c = 3}),{a = 1, b = 2, c = 3}))
end)
test('does not override existing properies',function()
assert_true(M.isEqual(M.template({a = 10, b = 10},{a = 1, b = 2, c = 3}),{a = 10, b = 10, c = 3}))
it('does not override existing properies',function()
assert.is_true(M.isEqual(M.template({a = 10, b = 10},{a = 1, b = 2, c = 3}),{a = 10, b = 10, c = 3}))
end)
test('returns the object when given no template arg',function()
assert_true(M.isEqual(M.template({a = 10, b = 10}),{a = 10, b = 10}))
it('returns the object when given no template arg',function()
assert.is_true(M.isEqual(M.template({a = 10, b = 10}),{a = 10, b = 10}))
end)
end)
context('isEqual', function()
describe('isEqual', function()
test('compares values',function()
assert_true(M.isEqual(1,1))
assert_true(M.isEqual(1.0,1))
assert_false(M.isEqual(1,2))
assert_false(M.isEqual(2,2.0001))
it('compares values',function()
assert.is_true(M.isEqual(1,1))
assert.is_true(M.isEqual(1.0,1))
assert.is_false(M.isEqual(1,2))
assert.is_false(M.isEqual(2,2.0001))
end)
test('compares objects by reference and components',function()
it('compares objects by reference and components',function()
local oldprint = print
assert_true(M.isEqual(print,oldprint))
assert.is_true(M.isEqual(print,oldprint))
local t = {}
local v = t
assert_true(M.isEqual(t,v))
assert_true(M.isEqual({},{}))
assert.is_true(M.isEqual(t,v))
assert.is_true(M.isEqual({},{}))
assert_false(M.isEqual('a','b'))
assert.is_false(M.isEqual('a','b'))
assert_false(M.isEqual(true, false))
assert_false(M.isEqual(nil, false))
assert_false(M.isEqual(true, nil))
assert.is_false(M.isEqual(true, false))
assert.is_false(M.isEqual(nil, false))
assert.is_false(M.isEqual(true, nil))
end)
test('compares nested properties',function()
assert_true(M.isEqual({x = 0,{x1 = 0,{x2 =0}}}, {x = 0,{x1 = 0,{x2 =0}}}))
assert_false(M.isEqual({x = 0,{x1 = 0,{x2 =0}}}, {x = 0,{x1 = 0,{x2 =1}}}))
it('compares nested properties',function()
assert.is_true(M.isEqual({x = 0,{x1 = 0,{x2 =0}}}, {x = 0,{x1 = 0,{x2 =0}}}))
assert.is_false(M.isEqual({x = 0,{x1 = 0,{x2 =0}}}, {x = 0,{x1 = 0,{x2 =1}}}))
end)
test('can compare tables on the basis of their metatable',function()
it('can compare tables on the basis of their metatable',function()
local a, b = {x = 1, y = 2}, {x = 2, y = 1}
setmetatable(a,{__eq = function(a,b) return (a.x and b.x and a.y and b.y)~=nil end})
assert_false(M.isEqual(a, b))
assert_true(M.isEqual(a, b, true))
assert.is_false(M.isEqual(a, b))
assert.is_true(M.isEqual(a, b, true))
end)
end)
context('result', function()
describe('result', function()
test('calls an object method, passing it as a first arg the object itself',function()
assert_equal(M.result('a','len'),1)
assert_equal(M.result('hello','reverse'),'olleh')
assert_equal(M.result({'a','b','c'},table.concat),'abc')
it('calls an object method, passing it as a first arg the object itself',function()
assert.equal(M.result('a','len'),1)
assert.equal(M.result('hello','reverse'),'olleh')
assert.equal(M.result({'a','b','c'},table.concat),'abc')
end)
test('handles extra-args to be passed to the so-called method',function()
assert_equal(M.result('Hello','match','%u'),'H')
assert_equal(M.result({'a','b','c'},table.concat,' '),'a b c')
it('handles extra-args to be passed to the so-called method',function()
assert.equal(M.result('Hello','match','%u'),'H')
assert.equal(M.result({'a','b','c'},table.concat,' '),'a b c')
end)
test('returns the property itself if not callable',function()
assert_equal(M.result({size = 0},'size'),0)
it('returns the property itself if not callable',function()
assert.equal(M.result({size = 0},'size'),0)
end)
end)
context('isTable', function()
describe('isTable', function()
test('returns "true" if arg is table or array',function()
assert_true(M.isTable({}))
assert_true(M.isTable({1,2}))
assert_true(M.isTable({x = 1, 2}))
assert_true(M.isTable(string))
assert_true(M.isTable(table))
assert_true(M.isTable(math))
it('returns "true" if arg is table or array',function()
assert.is_true(M.isTable({}))
assert.is_true(M.isTable({1,2}))
assert.is_true(M.isTable({x = 1, 2}))
assert.is_true(M.isTable(string))
assert.is_true(M.isTable(table))
assert.is_true(M.isTable(math))
end)
test('returns "false" otherwise',function()
assert_false(M.isTable(1))
assert_false(M.isTable(''))
assert_false(M.isTable(function() end))
assert_false(M.isTable(print))
assert_false(M.isTable(false))
assert_false(M.isTable(nil))
assert_false(M.isTable(true))
it('returns "false" otherwise',function()
assert.is_false(M.isTable(1))
assert.is_false(M.isTable(''))
assert.is_false(M.isTable(function() end))
assert.is_false(M.isTable(print))
assert.is_false(M.isTable(false))
assert.is_false(M.isTable(nil))
assert.is_false(M.isTable(true))
end)
end)
context('isCallable', function()
describe('isCallable', function()
test('returns "true" if arg is callable',function()
assert_true(M.isCallable(print))
assert_true(M.isCallable(function() end))
assert_true(M.isCallable(string.gmatch))
assert_true(M.isCallable(setmetatable({},{__index = string}).upper))
assert_true(M.isCallable(setmetatable({},{__call = function() return end})))
it('returns "true" if arg is callable',function()
assert.is_true(M.isCallable(print))
assert.is_true(M.isCallable(function() end))
assert.is_true(M.isCallable(string.gmatch))
assert.is_true(M.isCallable(setmetatable({},{__index = string}).upper))
assert.is_true(M.isCallable(setmetatable({},{__call = function() return end})))
end)
test('returns "false" otherwise',function()
assert_false(M.isCallable(1))
assert_false(M.isCallable(''))
assert_false(M.isCallable({}))
assert_false(M.isCallable(false))
assert_false(M.isCallable(nil))
assert_false(M.isCallable(true))
it('returns "false" otherwise',function()
assert.is_false(M.isCallable(1))
assert.is_false(M.isCallable(''))
assert.is_false(M.isCallable({}))
assert.is_false(M.isCallable(false))
assert.is_false(M.isCallable(nil))
assert.is_false(M.isCallable(true))
end)
end)
context('isArray', function()
describe('isArray', function()
test('returns "true" if arg is an array',function()
assert_true(M.isArray({}))
assert_true(M.isArray({1,2,3}))
assert_true(M.isArray({'a','b','c',{}}))
assert_true(M.isArray({false,true}))
assert_true(M.isArray({1,nil}))
it('returns "true" if arg is an array',function()
assert.is_true(M.isArray({}))
assert.is_true(M.isArray({1,2,3}))
assert.is_true(M.isArray({'a','b','c',{}}))
assert.is_true(M.isArray({false,true}))
assert.is_true(M.isArray({1,nil}))
end)
test('returns "false" otherwise',function()
assert_false(M.isArray(1))
assert_false(M.isArray(''))
assert_false(M.isArray(false))
assert_false(M.isArray(nil))
assert_false(M.isArray(true))
assert_false(M.isArray(print))
assert_false(M.isArray({a = 1, x = 1}))
assert_false(M.isArray({a = 1, 1, 2,3}))
assert_false(M.isArray({1,nil,2}))
assert_false(M.isArray({1,nil,3,k=4}))
assert_false(M.isArray({a=1}))
it('returns "false" otherwise',function()
assert.is_false(M.isArray(1))
assert.is_false(M.isArray(''))
assert.is_false(M.isArray(false))
assert.is_false(M.isArray(nil))
assert.is_false(M.isArray(true))
assert.is_false(M.isArray(print))
assert.is_false(M.isArray({a = 1, x = 1}))
assert.is_false(M.isArray({a = 1, 1, 2,3}))
assert.is_false(M.isArray({1,nil,2}))
assert.is_false(M.isArray({1,nil,3,k=4}))
assert.is_false(M.isArray({a=1}))
end)
test('returns false on "sparse arrays"',function()
assert_false(M.isArray({[1] = true, [10] = false}))
it('returns false on "sparse arrays"',function()
assert.is_false(M.isArray({[1] = true, [10] = false}))
end)
end)
context('isIterable', function()
describe('isIterable', function()
test('checks if the given object is iterable with pairs',function()
assert_true(M.isIterable({}))
assert_false(M.isIterable(function() end))
assert_false(M.isIterable(false))
assert_false(M.isIterable(1))
it('checks if the given object is iterable with pairs',function()
assert.is_true(M.isIterable({}))
assert.is_false(M.isIterable(function() end))
assert.is_false(M.isIterable(false))
assert.is_false(M.isIterable(1))
end)
end)
context('isEmpty', function()
describe('isEmpty', function()
test('returns "true" if arg is an empty array',function()
assert_true(M.isEmpty({}))
it('returns "true" if arg is an empty array',function()
assert.is_true(M.isEmpty({}))
end)
test('returns "false" otherwise',function()
assert_false(M.isEmpty({1,2,3}))
assert_false(M.isEmpty({'a','b','c',{}}))
assert_false(M.isEmpty({nil,false,true}))
it('returns "false" otherwise',function()
assert.is_false(M.isEmpty({1,2,3}))
assert.is_false(M.isEmpty({'a','b','c',{}}))
assert.is_false(M.isEmpty({nil,false,true}))
end)
test('booleans, nil and functions are considered empty',function()
assert_true(M.isEmpty(print))
assert_true(M.isEmpty(nil))
assert_true(M.isEmpty(false))
assert_true(M.isEmpty(true))
it('booleans, nil and functions are considered empty',function()
assert.is_true(M.isEmpty(print))
assert.is_true(M.isEmpty(nil))
assert.is_true(M.isEmpty(false))
assert.is_true(M.isEmpty(true))
end)
test('handles strings',function()
assert_true(M.isEmpty(''))
assert_false(M.isEmpty('a'))
assert_false(M.isEmpty('bcd'))
assert_false(M.isEmpty(' '))
it('handles strings',function()
assert.is_true(M.isEmpty(''))
assert.is_false(M.isEmpty('a'))
assert.is_false(M.isEmpty('bcd'))
assert.is_false(M.isEmpty(' '))
end)
end)
context('isString', function()
describe('isString', function()
test('returns "true" if arg is a string',function()
assert_true(M.isString(''))
assert_true(M.isString('a'))
assert_true(M.isString(' '))
assert_true(M.isString(type(nil)))
it('returns "true" if arg is a string',function()
assert.is_true(M.isString(''))
assert.is_true(M.isString('a'))
assert.is_true(M.isString(' '))
assert.is_true(M.isString(type(nil)))
end)
test('returns "false" otherwise',function()
assert_false(M.isString(false))
assert_false(M.isString(print))
assert_false(M.isString(nil))
assert_false(M.isString(true))
assert_false(M.isString({}))
it('returns "false" otherwise',function()
assert.is_false(M.isString(false))
assert.is_false(M.isString(print))
assert.is_false(M.isString(nil))
assert.is_false(M.isString(true))
assert.is_false(M.isString({}))
end)
end)
context('isFunction', function()
describe('isFunction', function()
test('returns "true" if arg is a function',function()
assert_true(M.isFunction(print))
assert_true(M.isFunction(string.match))
assert_true(M.isFunction(function() end))
it('returns "true" if arg is a function',function()
assert.is_true(M.isFunction(print))
assert.is_true(M.isFunction(string.match))
assert.is_true(M.isFunction(function() end))
end)
test('returns "false" otherwise',function()
assert_false(M.isFunction({}))
assert_false(M.isFunction(nil))
assert_false(M.isFunction(false))
assert_false(M.isFunction(true))
assert_false(M.isFunction('a'))
it('returns "false" otherwise',function()
assert.is_false(M.isFunction({}))
assert.is_false(M.isFunction(nil))
assert.is_false(M.isFunction(false))
assert.is_false(M.isFunction(true))
assert.is_false(M.isFunction('a'))
end)
end)
context('isNil', function()
describe('isNil', function()
test('returns "true" if arg is nil',function()
assert_true(M.isNil(nil))
assert_true(M.isNil())
assert_true(M.isNil(a))
it('returns "true" if arg is nil',function()
assert.is_true(M.isNil(nil))
assert.is_true(M.isNil())
assert.is_true(M.isNil(a))
end)
test('returns "false" otherwise',function()
assert_false(M.isNil(false))
assert_false(M.isNil(true))
assert_false(M.isNil(table))
assert_false(M.isNil(function() end))
assert_false(M.isNil('a'))
it('returns "false" otherwise',function()
assert.is_false(M.isNil(false))
assert.is_false(M.isNil(true))
assert.is_false(M.isNil(table))
assert.is_false(M.isNil(function() end))
assert.is_false(M.isNil('a'))
end)
end)
context('isNumber', function()
describe('isNumber', function()
test('returns "true" if arg is a number',function()
assert_true(M.isNumber(1))
assert_true(M.isNumber(0.5))
assert_true(M.isNumber(math.pi))
assert_true(M.isNumber(1/0))
assert_true(M.isNumber(math.huge))
assert_true(M.isNumber(0/0))
it('returns "true" if arg is a number',function()
assert.is_true(M.isNumber(1))
assert.is_true(M.isNumber(0.5))
assert.is_true(M.isNumber(math.pi))
assert.is_true(M.isNumber(1/0))
assert.is_true(M.isNumber(math.huge))
assert.is_true(M.isNumber(0/0))
end)
test('returns "false" otherwise',function()
assert_false(M.isNumber(print))
assert_false(M.isNumber(nil))
assert_false(M.isNumber(true))
assert_false(M.isNumber(false))
assert_false(M.isNumber({1}))
assert_false(M.isNumber('1'))
it('returns "false" otherwise',function()
assert.is_false(M.isNumber(print))
assert.is_false(M.isNumber(nil))
assert.is_false(M.isNumber(true))
assert.is_false(M.isNumber(false))
assert.is_false(M.isNumber({1}))
assert.is_false(M.isNumber('1'))
end)
end)
context('isNaN', function()
describe('isNaN', function()
test('returns "true" if arg is NaN',function()
assert_true(M.isNaN(0/0))
it('returns "true" if arg is NaN',function()
assert.is_true(M.isNaN(0/0))
end)
test('returns "false" for not NaN values',function()
assert_false(M.isNaN(1/0))
assert_false(M.isNaN(math.huge))
assert_false(M.isNaN(math.pi))
assert_false(M.isNaN(1))
assert_false(M.isNaN(''))
assert_false(M.isNaN('0'))
assert_false(M.isNaN({}))
assert_false(M.isNaN(nil))
assert_false(M.isNaN(false))
assert_false(M.isNaN(true))
it('returns "false" for not NaN values',function()
assert.is_false(M.isNaN(1/0))
assert.is_false(M.isNaN(math.huge))
assert.is_false(M.isNaN(math.pi))
assert.is_false(M.isNaN(1))
assert.is_false(M.isNaN(''))
assert.is_false(M.isNaN('0'))
assert.is_false(M.isNaN({}))
assert.is_false(M.isNaN(nil))
assert.is_false(M.isNaN(false))
assert.is_false(M.isNaN(true))
end)
end)
context('isFinite', function()
describe('isFinite', function()
test('returns "true" if arg is a finite number',function()
assert_true(M.isFinite(1))
assert_true(M.isFinite(0))
assert_true(M.isFinite(math.pi))
assert_true(M.isFinite(99e99))
it('returns "true" if arg is a finite number',function()
assert.is_true(M.isFinite(1))
assert.is_true(M.isFinite(0))
assert.is_true(M.isFinite(math.pi))
assert.is_true(M.isFinite(99e99))
end)
test('returns "false" otherwise',function()
assert_false(M.isFinite(math.huge))
assert_false(M.isFinite(1/0))
assert_false(M.isFinite(0/0))
it('returns "false" otherwise',function()
assert.is_false(M.isFinite(math.huge))
assert.is_false(M.isFinite(1/0))
assert.is_false(M.isFinite(0/0))
end)
test('returns "false" for non-numbers',function()
assert_false(M.isFinite(''))
assert_false(M.isFinite(function() end))
assert_false(M.isFinite({}))
it('returns "false" for non-numbers',function()
assert.is_false(M.isFinite(''))
assert.is_false(M.isFinite(function() end))
assert.is_false(M.isFinite({}))
end)
end)
context('isBoolean', function()
describe('isBoolean', function()
test('returns "true" if arg is a boolean or a thruthy statement',function()
assert_true(M.isBoolean(true))
assert_true(M.isBoolean(false))
assert_true(M.isBoolean(1==1))
assert_true(M.isBoolean(print==tostring))
it('returns "true" if arg is a boolean or a thruthy statement',function()
assert.is_true(M.isBoolean(true))
assert.is_true(M.isBoolean(false))
assert.is_true(M.isBoolean(1==1))
assert.is_true(M.isBoolean(print==tostring))
end)
test('returns "false" otherwise',function()
assert_false(M.isBoolean(''))
assert_false(M.isBoolean(nil))
assert_false(M.isBoolean({}))
assert_false(M.isBoolean(function() end))
it('returns "false" otherwise',function()
assert.is_false(M.isBoolean(''))
assert.is_false(M.isBoolean(nil))
assert.is_false(M.isBoolean({}))
assert.is_false(M.isBoolean(function() end))
assert_false(M.isBoolean(0))
assert_false(M.isBoolean('1'))
assert.is_false(M.isBoolean(0))
assert.is_false(M.isBoolean('1'))
end)
end)
context('isInteger', function()
describe('isInteger', function()
test('returns "true" if arg is a integer, "false" otherwise',function()
assert_true(M.isInteger(1))
assert_true(M.isInteger(0))
assert_false(M.isInteger(math.pi))
assert_true(M.isInteger(1/0))
assert_true(M.isInteger(math.huge))
assert_false(M.isInteger(0/0))
it('returns "true" if arg is a integer, "false" otherwise',function()
assert.is_true(M.isInteger(1))
assert.is_true(M.isInteger(0))
assert.is_false(M.isInteger(math.pi))
assert.is_true(M.isInteger(1/0))
assert.is_true(M.isInteger(math.huge))
assert.is_false(M.isInteger(0/0))
end)
end)

View File

@ -1,160 +1,160 @@
require 'luacov'
local M = require 'moses'
context('Operators specs', function()
describe('Operators specs', function()
context('Arithmetic operators', function()
describe('Arithmetic operators', function()
test('add returns a + b', function()
assert_equal(M.operator.add(1,2), 3)
assert_equal(M.operator.add(0,0), 0)
assert_equal(M.operator.add(0,-5), -5)
it('add returns a + b', function()
assert.equal(M.operator.add(1,2), 3)
assert.equal(M.operator.add(0,0), 0)
assert.equal(M.operator.add(0,-5), -5)
end)
test('sub returns a - b', function()
assert_equal(M.operator.sub(1,2), -1)
assert_equal(M.operator.sub(0,0), 0)
assert_equal(M.operator.sub(0,-5), 5)
it('sub returns a - b', function()
assert.equal(M.operator.sub(1,2), -1)
assert.equal(M.operator.sub(0,0), 0)
assert.equal(M.operator.sub(0,-5), 5)
end)
test('mul returns a * b', function()
assert_equal(M.operator.mul(1,2), 2)
assert_equal(M.operator.mul(0,0), 0)
assert_equal(M.operator.mul(0,-5), 0)
it('mul returns a * b', function()
assert.equal(M.operator.mul(1,2), 2)
assert.equal(M.operator.mul(0,0), 0)
assert.equal(M.operator.mul(0,-5), 0)
end)
test('div returns a / b', function()
assert_equal(M.operator.div(1,2), 0.5)
assert_equal(M.operator.div(5,5), 1)
assert_equal(M.operator.div(8,-2), -4)
it('div returns a / b', function()
assert.equal(M.operator.div(1,2), 0.5)
assert.equal(M.operator.div(5,5), 1)
assert.equal(M.operator.div(8,-2), -4)
end)
test('mod returns a % b', function()
assert_equal(M.operator.mod(6,3), 0)
assert_equal(M.operator.mod(5,2), 1)
it('mod returns a % b', function()
assert.equal(M.operator.mod(6,3), 0)
assert.equal(M.operator.mod(5,2), 1)
end)
test('exp returns a ^ b', function()
assert_equal(M.operator.exp(3,3), 27)
assert_equal(M.operator.exp(5,2), 25)
it('exp returns a ^ b', function()
assert.equal(M.operator.exp(3,3), 27)
assert.equal(M.operator.exp(5,2), 25)
end)
test('unm returns -a', function()
assert_equal(M.operator.unm(3), -3)
assert_equal(M.operator.unm(-5), 5)
it('unm returns -a', function()
assert.equal(M.operator.unm(3), -3)
assert.equal(M.operator.unm(-5), 5)
end)
test('floordiv returns a//b', function()
assert_equal(M.operator.floordiv(5,2), 2)
it('floordiv returns a//b', function()
assert.equal(M.operator.floordiv(5,2), 2)
end)
test('intdiv performs integer division', function()
assert_equal(M.operator.intdiv(5,2), 2)
assert_equal(M.operator.intdiv(-5,2), -2)
it('intdiv performs integer division', function()
assert.equal(M.operator.intdiv(5,2), 2)
assert.equal(M.operator.intdiv(-5,2), -2)
end)
end)
context('Relational operators', function()
describe('Relational operators', function()
test('eq returns a == b', function()
assert_equal(M.operator.eq(5,5), true)
assert_equal(M.operator.eq(5,4.99), false)
it('eq returns a == b', function()
assert.equal(M.operator.eq(5,5), true)
assert.equal(M.operator.eq(5,4.99), false)
end)
test('neq returns a ~= b', function()
assert_equal(M.operator.neq(5,5), false)
assert_equal(M.operator.neq(5,4.99), true)
it('neq returns a ~= b', function()
assert.equal(M.operator.neq(5,5), false)
assert.equal(M.operator.neq(5,4.99), true)
end)
test('lt returns a < b', function()
assert_equal(M.operator.lt(5,5), false)
assert_equal(M.operator.lt(4.99,5), true)
it('lt returns a < b', function()
assert.equal(M.operator.lt(5,5), false)
assert.equal(M.operator.lt(4.99,5), true)
end)
test('gt returns a > b', function()
assert_equal(M.operator.gt(5,5), false)
assert_equal(M.operator.gt(5,4.99), true)
it('gt returns a > b', function()
assert.equal(M.operator.gt(5,5), false)
assert.equal(M.operator.gt(5,4.99), true)
end)
test('le returns a <= b', function()
assert_equal(M.operator.le(5,5), true)
assert_equal(M.operator.le(4.99,5), true)
assert_equal(M.operator.le(5,4.99), false)
it('le returns a <= b', function()
assert.equal(M.operator.le(5,5), true)
assert.equal(M.operator.le(4.99,5), true)
assert.equal(M.operator.le(5,4.99), false)
end)
test('ge returns a >= b', function()
assert_equal(M.operator.ge(5,5), true)
assert_equal(M.operator.ge(4.99,5), false)
assert_equal(M.operator.ge(5,4.99), true)
it('ge returns a >= b', function()
assert.equal(M.operator.ge(5,5), true)
assert.equal(M.operator.ge(4.99,5), false)
assert.equal(M.operator.ge(5,4.99), true)
end)
end)
context('Logical operators', function()
describe('Logical operators', function()
test('land returns a and b', function()
assert_equal(M.operator.land(true, true),true)
assert_equal(M.operator.land(true, false),false)
assert_equal(M.operator.land(false, true),false)
assert_equal(M.operator.land(false, false),false)
assert_equal(M.operator.land(true, nil),nil)
assert_equal(M.operator.land(false, nil),false)
it('land returns a and b', function()
assert.equal(M.operator.land(true, true),true)
assert.equal(M.operator.land(true, false),false)
assert.equal(M.operator.land(false, true),false)
assert.equal(M.operator.land(false, false),false)
assert.equal(M.operator.land(true, nil),nil)
assert.equal(M.operator.land(false, nil),false)
end)
test('lor returns a or b', function()
assert_equal(M.operator.lor(true, true),true)
assert_equal(M.operator.lor(true, false),true)
assert_equal(M.operator.lor(false, true),true)
assert_equal(M.operator.lor(false, false),false)
assert_equal(M.operator.lor(true, nil),true)
assert_equal(M.operator.lor(false, nil),nil)
it('lor returns a or b', function()
assert.equal(M.operator.lor(true, true),true)
assert.equal(M.operator.lor(true, false),true)
assert.equal(M.operator.lor(false, true),true)
assert.equal(M.operator.lor(false, false),false)
assert.equal(M.operator.lor(true, nil),true)
assert.equal(M.operator.lor(false, nil),nil)
end)
test('lnot returns not a', function()
assert_equal(M.operator.lnot(true),false)
assert_equal(M.operator.lnot(false),true)
assert_equal(M.operator.lnot(nil),true)
it('lnot returns not a', function()
assert.equal(M.operator.lnot(true),false)
assert.equal(M.operator.lnot(false),true)
assert.equal(M.operator.lnot(nil),true)
end)
end)
context('Length operator', function()
describe('Length operator', function()
test('length returns #a', function()
assert_equal(M.operator.length({}),0)
assert_equal(M.operator.length({2}),1)
assert_equal(M.operator.length({3,5,3}),3)
assert_equal(M.operator.length('hello'),5)
it('length returns #a', function()
assert.equal(M.operator.length({}),0)
assert.equal(M.operator.length({2}),1)
assert.equal(M.operator.length({3,5,3}),3)
assert.equal(M.operator.length('hello'),5)
end)
end)
context('Concatenation operator', function()
describe('Concatenation operator', function()
test('concat returns a..b', function()
assert_equal(M.operator.concat('a','b'),'ab')
assert_equal(M.operator.concat('1','2'),'12')
it('concat returns a..b', function()
assert.equal(M.operator.concat('a','b'),'ab')
assert.equal(M.operator.concat('1','2'),'12')
end)
end)
context('Aliases', function()
describe('Aliases', function()
test('op is an alias to operator', function()
assert_equal(M.operator, M.op)
it('op is an alias to operator', function()
assert.equal(M.operator, M.op)
end)
test('pow is an alias to exp', function()
assert_equal(M.operator.exp, M.operator.pow)
it('pow is an alias to exp', function()
assert.equal(M.operator.exp, M.operator.pow)
end)
test('neg is an alias to unm', function()
assert_equal(M.operator.neg, M.operator.unm)
it('neg is an alias to unm', function()
assert.equal(M.operator.neg, M.operator.unm)
end)
test('len is alias to length', function()
assert_equal(M.operator.length,M.operator.len)
it('len is alias to length', function()
assert.equal(M.operator.length,M.operator.len)
end)
end)

View File

@ -1,186 +1,182 @@
require 'luacov'
local M = require 'moses'
context('Table functions specs', function()
describe('Table functions specs', function()
context('clear', function()
describe('clear', function()
test('', function()
it('', function()
local t = M.clear({'a', true, 'hello'})
assert_true(M.isEqual(t,{}))
assert_nil(next(t))
assert.is_true(M.isEqual(t,{}))
assert.is_nil(next(t))
end)
end)
context('each', function()
describe('each', function()
test('provides values and iteration count ', function()
it('provides values and iteration count ', function()
local t = {4,2,1}
local inc = 0
M.each(t,function(v, i)
inc = inc+1
assert_equal(i,inc)
assert_equal(t[i],v)
assert.equal(i,inc)
assert.equal(t[i],v)
end)
end)
test('can reference the given table', function()
it('can reference the given table', function()
local t = {1,2,3}
M.each(t,function(v,i,mul)
t[i] = v*mul
end,5)
assert_true(M.isEqual(t,{5,10,15}))
assert.is_true(M.isEqual(t,{5,10,15}))
end)
test('iterates over non-numeric keys and objects', function()
it('iterates over non-numeric keys and objects', function()
local t = {one = 1, two = 2, three = 3}
local copy = {}
M.each(t,function(v,i) copy[i] = v end)
assert_true(M.isEqual(t,copy))
assert.is_true(M.isEqual(t,copy))
end)
end)
context('eachi', function()
describe('eachi', function()
test('provides values and iteration count for integer keys only, in a sorted way', function()
it('provides values and iteration count for integer keys only, in a sorted way', function()
local t = {4,2,1}
local inc = 0
M.eachi(t,function(v,i)
inc = inc+1
assert_equal(i,inc)
assert_equal(t[i],v)
assert.equal(i,inc)
assert.equal(t[i],v)
end)
end)
test('ignores non-integer keys', function()
it('ignores non-integer keys', function()
local t = {a = 1, b = 2, [0] = 1, [-1] = 6, 3, x = 4, 5}
local rk = {-1, 0, 1, 2}
local rv = {6, 1, 3, 5}
local inc = 0
M.eachi(t,function(v,i)
inc = inc+1
assert_equal(i,rk[inc])
assert_equal(v,rv[inc])
assert.equal(i,rk[inc])
assert.equal(v,rv[inc])
end)
end)
end)
context('at', function()
describe('at', function()
test('returns an array of values at numeric keys', function()
it('returns an array of values at numeric keys', function()
local t = {4,5,6}
local values = M.at(t,1,2,3)
assert_true(M.isEqual(values, t))
assert.is_true(M.isEqual(values, t))
local t = {a = 4, bb = true, ccc = false}
local values = M.at(t,'a', 'ccc')
assert_true(M.isEqual(values, {4, false}))
assert.is_true(M.isEqual(values, {4, false}))
end)
end)
context('adjust', function()
describe('adjust', function()
test('adjusts a given value in a table using a function', function()
it('adjusts a given value in a table using a function', function()
local double = function(v) return v * 2 end
local t = {1,2,3}
assert_true(M.isEqual(M.adjust(t,1,double),{2,2,3}))
assert_true(M.isEqual(M.adjust(t,2,double),{1,4,3}))
assert_true(M.isEqual(M.adjust(t,3,double),{1,2,6}))
assert.is_true(M.isEqual(M.adjust(t,1,double),{2,2,3}))
assert.is_true(M.isEqual(M.adjust(t,2,double),{1,4,3}))
assert.is_true(M.isEqual(M.adjust(t,3,double),{1,2,6}))
end)
test('adjusts a given value in a table using a value', function()
it('adjusts a given value in a table using a value', function()
local t = {1,2,3}
assert_true(M.isEqual(M.adjust(t,1,5),{5,2,3}))
assert_true(M.isEqual(M.adjust(t,2,-2),{1,-2,3}))
assert.is_true(M.isEqual(M.adjust(t,1,5),{5,2,3}))
assert.is_true(M.isEqual(M.adjust(t,2,-2),{1,-2,3}))
end)
test('throws an error if key is not found in table', function()
it('throws an error if key is not found in table', function()
local double = function(v) return v * 2 end
local t = {x = 1}
assert_error(function() M.adjust(t,'y', 2) end)
assert.error(function() M.adjust(t,'y', 2) end)
end)
end)
context('count', function()
describe('count', function()
test('count the occurences of value in a list', function()
assert_equal(M.count({1,1,2,3,3,3,2,4,3,2},1),2)
assert_equal(M.count({1,1,2,3,3,3,2,4,3,2},2),3)
assert_equal(M.count({1,1,2,3,3,3,2,4,3,2},3),4)
assert_equal(M.count({1,1,2,3,3,3,2,4,3,2},4),1)
assert_equal(M.count({1,1,2,3,3,3,2,4,3,2},5),0)
assert_equal(M.count({false, false, true},false),2)
assert_equal(M.count({false, false, true},true),1)
assert_equal(M.count({{1,1},{1,1},{1,1},{2,2}},{1,1}),3)
assert_equal(M.count({{1,1},{1,1},{1,1},{2,2}},{2,2}),1)
it('count the occurences of value in a list', function()
assert.equal(M.count({1,1,2,3,3,3,2,4,3,2},1),2)
assert.equal(M.count({1,1,2,3,3,3,2,4,3,2},2),3)
assert.equal(M.count({1,1,2,3,3,3,2,4,3,2},3),4)
assert.equal(M.count({1,1,2,3,3,3,2,4,3,2},4),1)
assert.equal(M.count({1,1,2,3,3,3,2,4,3,2},5),0)
assert.equal(M.count({false, false, true},false),2)
assert.equal(M.count({false, false, true},true),1)
assert.equal(M.count({{1,1},{1,1},{1,1},{2,2}},{1,1}),3)
assert.equal(M.count({{1,1},{1,1},{1,1},{2,2}},{2,2}),1)
end)
test('defaults to size when value is not given', function()
assert_equal(M.count({1,1,2,3,3,3,2,4,3,2}),M.size({1,1,2,3,3,3,2,4,3,2}))
assert_equal(M.count({false, false, true}),M.size({false, false, true}))
it('defaults to size when value is not given', function()
assert.equal(M.count({1,1,2,3,3,3,2,4,3,2}),M.size({1,1,2,3,3,3,2,4,3,2}))
assert.equal(M.count({false, false, true}),M.size({false, false, true}))
end)
end)
context('countf', function()
test('count the occurences of values passing an iterator test in a list', function()
assert_equal(M.countf({1,2,3,4,5,6}, function(v)
return v%2==0
end),3)
assert_equal(M.countf({print, pairs, os, assert, ipairs}, function(v)
return type(v)=='function'
end),4)
describe('countf', function()
it('count the occurences of values passing an iterator test in a list', function()
assert.equal(M.countf({1,2,3,4,5,6}, function(v) return v%2==0 end),3)
assert.equal(M.countf({print, pairs, ipairs}, function(v) return type(v)=='function' end),3)
end)
end)
context('cycle', function()
describe('cycle', function()
test('loops n times on a list', function()
it('loops n times on a list', function()
local times = 3
local t = {1,2,3,4,5}
local kv = {}
for v,k in M.cycle(t,times) do
assert_equal(t[k],v)
assert.equal(t[k],v)
kv[#kv+1] = v
end
for k,v in ipairs(kv) do
assert_equal(M.count(kv,v),times)
assert.equal(M.count(kv,v),times)
end
end)
test('support array-like and map-like tables', function()
it('support array-like and map-like tables', function()
local times = 10
local t = {x = 1, z = 2}
local keys = {}
local values = {}
for v,k in M.cycle(t,times) do
assert_equal(t[k],v)
assert.equal(t[k],v)
keys[#keys+1] = k
values[#values+1] = v
end
for k,v in ipairs(keys) do
assert_equal(M.count(keys,v),times)
assert.equal(M.count(keys,v),times)
end
for k,v in ipairs(values) do
assert_equal(M.count(values,v),times)
assert.equal(M.count(values,v),times)
end
end)
test('n defaults to 1, if not supplied', function()
it('n defaults to 1, if not supplied', function()
local t = {1,2,3,4,5}
for v,k in M.cycle(t) do
t[k] = v + 1
end
M.each(t, function(v, k)
assert_equal(v, k + 1)
assert.equal(v, k + 1)
end)
end)
test('if n is negative or equal to 0, it does nothing', function()
it('if n is negative or equal to 0, it does nothing', function()
local t = {1,2,3,4,5}
for v,k in M.cycle(t, 0) do
t[k] = v + 1
@ -189,471 +185,471 @@ context('Table functions specs', function()
t[k] = v + 1
end
M.each(t, function(v, k)
assert_equal(v, k)
assert.equal(v, k)
end)
end)
end)
context('map', function()
describe('map', function()
test('applies an iterator function over each key-value pair ', function()
assert_true(M.isEqual(M.map({1,2,3},function(v)
it('applies an iterator function over each key-value pair ', function()
assert.is_true(M.isEqual(M.map({1,2,3},function(v)
return v+10
end),{11,12,13}))
end)
test('iterates over non-numeric keys and objects', function()
assert_true(M.isEqual(M.map({a = 1, b = 2},function(v,k)
it('iterates over non-numeric keys and objects', function()
assert.is_true(M.isEqual(M.map({a = 1, b = 2},function(v,k)
return k..v
end),{a = 'a1',b = 'b2'}))
end)
test('maps key-value pairs to key-value pairs', function()
assert_true(M.isEqual(M.map({a = 1, b = 2}, function(v, k)
it('maps key-value pairs to key-value pairs', function()
assert.is_true(M.isEqual(M.map({a = 1, b = 2}, function(v, k)
return k .. k, v + 10
end), {aa = 11, bb = 12}))
end)
end)
context('reduce', function()
describe('reduce', function()
test('folds a collection (left to right) from an initial state', function()
assert_equal(M.reduce({1,2,3,4},function(memo,v) return memo+v end,0),10)
it('folds a collection (left to right) from an initial state', function()
assert.equal(M.reduce({1,2,3,4},function(memo,v) return memo+v end,0),10)
end)
test('initial state defaults to the first value when not given', function()
assert_equal(M.reduce({'a','b','c'},function(memo,v) return memo..v end),'abc')
it('initial state defaults to the first value when not given', function()
assert.equal(M.reduce({'a','b','c'},function(memo,v) return memo..v end),'abc')
end)
test('supports arrays of booleans', function()
assert_equal(M.reduce({true, false, true, true},function(memo,v) return memo and v end), false)
assert_equal(M.reduce({true, true, true},function(memo,v) return memo and v end), true)
assert_equal(M.reduce({false, false, false},function(memo,v) return memo and v end), false)
assert_equal(M.reduce({false, false, true},function(memo,v) return memo or v end), true)
it('supports arrays of booleans', function()
assert.equal(M.reduce({true, false, true, true},function(memo,v) return memo and v end), false)
assert.equal(M.reduce({true, true, true},function(memo,v) return memo and v end), true)
assert.equal(M.reduce({false, false, false},function(memo,v) return memo and v end), false)
assert.equal(M.reduce({false, false, true},function(memo,v) return memo or v end), true)
end)
end)
context('reduceby', function()
describe('reduceby', function()
test('folds a collection (left to right) for specific values', function()
it('folds a collection (left to right) for specific values', function()
local function even(v) return v%2==0 end
local function odd(v) return v%2~=0 end
assert_equal(M.reduceby({1,2,3,4},function(memo,v) return memo+v end,even,0), 6)
assert_equal(M.reduceby({1,2,3,4},function(memo,v) return memo+v end,odd,0), 4)
assert.equal(M.reduceby({1,2,3,4},function(memo,v) return memo+v end,even,0), 6)
assert.equal(M.reduceby({1,2,3,4},function(memo,v) return memo+v end,odd,0), 4)
end)
end)
context('reduceRight', function()
describe('reduceRight', function()
test('folds a collection (right to left) from an initial state', function()
assert_equal(M.reduceRight({1,2,4,16},function(memo,v) return memo/v end,256),2)
it('folds a collection (right to left) from an initial state', function()
assert.equal(M.reduceRight({1,2,4,16},function(memo,v) return memo/v end,256),2)
end)
test('initial state defaults to the first value when not given', function()
assert_equal(M.reduceRight({'a','b','c'},function(memo,v) return memo..v end),'cba')
it('initial state defaults to the first value when not given', function()
assert.equal(M.reduceRight({'a','b','c'},function(memo,v) return memo..v end),'cba')
end)
end)
context('mapReduce', function()
describe('mapReduce', function()
test('folds a collection (left to right) saving intermediate states', function()
assert_true(M.isEqual(M.mapReduce({1,2,4,16},function(memo,v)
it('folds a collection (left to right) saving intermediate states', function()
assert.is_true(M.isEqual(M.mapReduce({1,2,4,16},function(memo,v)
return memo*v
end,0),{0,0,0,0}))
end)
test('initial state defaults to the first value when not given', function()
assert_true(M.isEqual(M.mapReduce({'a','b','c'},function(memo,v)
it('initial state defaults to the first value when not given', function()
assert.is_true(M.isEqual(M.mapReduce({'a','b','c'},function(memo,v)
return memo..v
end),{'a','ab','abc'}))
end)
end)
context('mapReduceRight', function()
describe('mapReduceRight', function()
test('folds a collection (right to left) saving intermediate states', function()
assert_true(M.isEqual(M.mapReduceRight({1,2,4,16},function(memo,v)
it('folds a collection (right to left) saving intermediate states', function()
assert.is_true(M.isEqual(M.mapReduceRight({1,2,4,16},function(memo,v)
return memo/v
end,256),{16,4,2,2}))
end)
test('initial state defaults to the first value when not given', function()
assert_true(M.isEqual(M.mapReduceRight({'a','b','c'},function(memo,v)
it('initial state defaults to the first value when not given', function()
assert.is_true(M.isEqual(M.mapReduceRight({'a','b','c'},function(memo,v)
return memo..v
end),{'c','cb','cba'}))
end)
end)
context('include', function()
describe('include', function()
test('looks for a value in a collection, returns true when found', function()
assert_true(M.include({6,8,10,16,29},16))
it('looks for a value in a collection, returns true when found', function()
assert.is_true(M.include({6,8,10,16,29},16))
end)
test('returns false when value was not found', function()
assert_false(M.include({6,8,10,16,29},1))
it('returns false when value was not found', function()
assert.is_false(M.include({6,8,10,16,29},1))
end)
test('can lookup for a object', function()
assert_true(M.include({6,{18,{2,6}},10,{18,{2,{3}}},29},{18,{2,{3}}}))
it('can lookup for a object', function()
assert.is_true(M.include({6,{18,{2,6}},10,{18,{2,{3}}},29},{18,{2,{3}}}))
end)
test('given an iterator, return the first value passing a truth test', function()
assert_true(M.include({'a','B','c'}, function(array_value)
it('given an iterator, return the first value passing a truth test', function()
assert.is_true(M.include({'a','B','c'}, function(array_value)
return (array_value:upper() == array_value)
end))
end)
end)
context('detect', function()
describe('detect', function()
test('looks for the first occurence of value, returns the key where it was found', function()
assert_equal(M.detect({6,8,10,16},8),2)
it('looks for the first occurence of value, returns the key where it was found', function()
assert.equal(M.detect({6,8,10,16},8),2)
end)
test('returns nil when value was not found', function()
assert_nil(M.detect({nil,true,0,true,true},false))
it('returns nil when value was not found', function()
assert.is_nil(M.detect({nil,true,0,true,true},false))
end)
test('can lookup for a object', function()
assert_equal(M.detect({6,{18,{2,6}},10,{18,{2,{3}}},29},{18,{2,6}}),2)
it('can lookup for a object', function()
assert.equal(M.detect({6,{18,{2,6}},10,{18,{2,{3}}},29},{18,{2,6}}),2)
end)
test('given an iterator, return the key of the first value passing a truth test', function()
assert_equal(M.detect({'a','B','c'}, function(array_value)
it('given an iterator, return the key of the first value passing a truth test', function()
assert.equal(M.detect({'a','B','c'}, function(array_value)
return (array_value:upper() == array_value)
end),2)
end)
end)
context('where', function()
describe('where', function()
test('Returns all values in a list having all of a given set of properties', function()
it('Returns all values in a list having all of a given set of properties', function()
local set = {
{a = 1, b = 2},
{a = 2, b = 2},
{a = 2, b = 4},
{a = 3, b = 4}
}
assert_true(M.isEqual(M.where(set, {a = 2}), {set[2],set[3]}))
assert_true(M.isEqual(M.where(set, {b = 4}), {set[3],set[4]}))
assert_true(M.isEqual(M.where(set, {a = 2, b = 2}), {set[2]}))
assert.is_true(M.isEqual(M.where(set, {a = 2}), {set[2],set[3]}))
assert.is_true(M.isEqual(M.where(set, {b = 4}), {set[3],set[4]}))
assert.is_true(M.isEqual(M.where(set, {a = 2, b = 2}), {set[2]}))
end)
test('returns nil when value was not found', function()
it('returns nil when value was not found', function()
local set = {
{a = 1, b = 2},
{a = 2, b = 2},
}
assert_nil(M.where(set, {a = 3}))
assert_nil(M.where(set, {b = 1}))
assert.is_nil(M.where(set, {a = 3}))
assert.is_nil(M.where(set, {b = 1}))
end)
end)
context('findWhere', function()
describe('findWhere', function()
test('Returns the first value in a list having all of a given set of properties', function()
it('Returns the first value in a list having all of a given set of properties', function()
local a = {a = 1, b = 2}
local b = {a = 2, b = 3}
local c = {a = 3, b = 4}
assert_equal(M.findWhere({a, b, c}, {a = 3, b = 4}), c)
assert.equal(M.findWhere({a, b, c}, {a = 3, b = 4}), c)
end)
test('returns nil when value was not found', function()
it('returns nil when value was not found', function()
local a = {a = 1, b = 2}
local b = {a = 2, b = 3}
local c = {a = 3, b = 4}
assert_nil(M.findWhere({a, b, c}, {a = 3, b = 0}))
assert.is_nil(M.findWhere({a, b, c}, {a = 3, b = 0}))
end)
end)
context('select', function()
describe('select', function()
test('collects all values passing a truth test with an iterator', function()
assert_true(M.isEqual(M.select({7,6,5,4,3,2,1}, function(value)
it('collects all values passing a truth test with an iterator', function()
assert.is_true(M.isEqual(M.select({7,6,5,4,3,2,1}, function(value)
return (value%2==0)
end),{6,4,2}))
assert_true(M.isEqual(M.select({7,6,5,4,3,2,1}, function(value)
assert.is_true(M.isEqual(M.select({7,6,5,4,3,2,1}, function(value)
return (value%2~=0)
end),{7,5,3,1}))
end)
end)
context('reject', function()
describe('reject', function()
test('collects all values failing a truth test with an iterator', function()
assert_true(M.isEqual(M.reject({7,6,5,4,3,2,1}, function(value)
it('collects all values failing a truth test with an iterator', function()
assert.is_true(M.isEqual(M.reject({7,6,5,4,3,2,1}, function(value)
return (value%2==0)
end),{7,5,3,1}))
assert_true(M.isEqual(M.reject({7,6,5,4,3,2,1}, function(value)
assert.is_true(M.isEqual(M.reject({7,6,5,4,3,2,1}, function(value)
return (value%2~=0)
end),{6,4,2}))
end)
end)
context('all', function()
describe('all', function()
test('returns whether all elements matches a truth test', function()
assert_true(M.all({2,4,6}, function(value)
it('returns whether all elements matches a truth test', function()
assert.is_true(M.all({2,4,6}, function(value)
return (value%2==0)
end))
assert_false(M.all({false,true,false}, function(value)
assert.is_false(M.all({false,true,false}, function(value)
return value == false
end))
end)
end)
context('invoke', function()
describe('invoke', function()
test('calls an iterator over each object, passing it as a first arg', function()
assert_true(M.isEqual(M.invoke({'a','bea','cdhza'},string.len),
it('calls an iterator over each object, passing it as a first arg', function()
assert.is_true(M.isEqual(M.invoke({'a','bea','cdhza'},string.len),
{1,3,5}))
assert_true(M.isEqual(M.invoke({{2,3,2},{13,8,10},{0,-5}},M.sort),
assert.is_true(M.isEqual(M.invoke({{2,3,2},{13,8,10},{0,-5}},M.sort),
{{2,2,3},{8,10,13},{-5,0}}))
assert_true(M.isEqual(M.invoke({{x = 1, y = 2},{x = 3, y=4}},'x'), {1,3}))
assert.is_true(M.isEqual(M.invoke({{x = 1, y = 2},{x = 3, y=4}},'x'), {1,3}))
end)
test('given a string, calls the matching object property the same way', function()
it('given a string, calls the matching object property the same way', function()
local a = {}; function a:call() return self end
local b, c, d = {}, {}, {}
b.call, c.call, d.call = a.call, a.call, a.call
assert_true(M.isEqual(M.invoke({a,b,c,d},'call'),
assert.is_true(M.isEqual(M.invoke({a,b,c,d},'call'),
{a,b,c,d}))
end)
end)
context('pluck', function()
describe('pluck', function()
test('fetches a property value in a collection of objects', function()
it('fetches a property value in a collection of objects', function()
local peoples = {
{name = 'John', age = 23},{name = 'Peter', age = 17},
{name = 'Steve', age = 15},{age = 33}}
assert_true(M.isEqual(M.pluck(peoples,'age'),
assert.is_true(M.isEqual(M.pluck(peoples,'age'),
{23,17,15,33}))
assert_true(M.isEqual(M.pluck(peoples,'name'),
assert.is_true(M.isEqual(M.pluck(peoples,'name'),
{'John','Peter','Steve'}))
end)
end)
context('max', function()
describe('max', function()
test('returns the maximum targetted property value in a collection of objects', function()
it('returns the maximum targetted property value in a collection of objects', function()
local peoples = {
{name = 'John', age = 23},{name = 'Peter', age = 17},
{name = 'Steve', age = 15},{age = 33}}
assert_equal(M.max(M.pluck(peoples,'age')),33)
assert_equal(M.max(peoples,function(people) return people.age end),33)
assert.equal(M.max(M.pluck(peoples,'age')),33)
assert.equal(M.max(peoples,function(people) return people.age end),33)
end)
test('directly compares items when given no iterator', function()
assert_equal(M.max({'a','b','c'}),'c')
it('directly compares items when given no iterator', function()
assert.equal(M.max({'a','b','c'}),'c')
end)
end)
context('min', function()
describe('min', function()
test('returns the maximum targetted property value in a collection of objects', function()
it('returns the maximum targetted property value in a collection of objects', function()
local peoples = {
{name = 'John', age = 23},{name = 'Peter', age = 17},
{name = 'Steve', age = 15},{age = 33}}
assert_equal(M.min(M.pluck(peoples,'age')),15)
assert_equal(M.min(peoples,function(people) return people.age end),15)
assert.equal(M.min(M.pluck(peoples,'age')),15)
assert.equal(M.min(peoples,function(people) return people.age end),15)
end)
test('directly compares items when given no iterator', function()
assert_equal(M.min({'a','b','c'}),'a')
it('directly compares items when given no iterator', function()
assert.equal(M.min({'a','b','c'}),'a')
end)
end)
context('same', function()
describe('same', function()
test('returns whether all objects from both given tables exists in each other', function()
it('returns whether all objects from both given tables exists in each other', function()
local a = {'a','b','c','d'}
local b = {'b','a','d','c'}
assert_true(M.same(a,b))
assert.is_true(M.same(a,b))
b[#b+1] = 'e'
assert_false(M.same(a,b))
assert.is_false(M.same(a,b))
end)
end)
context('sort', function()
describe('sort', function()
test('sorts a collection with respect to a given comparison function', function()
assert_true(M.isEqual(M.sort({'b','a','d','c'}, function(a,b)
it('sorts a collection with respect to a given comparison function', function()
assert.is_true(M.isEqual(M.sort({'b','a','d','c'}, function(a,b)
return a:byte() < b:byte()
end),{'a','b','c','d'}))
end)
test('uses "<" operator when no comparison function is given', function()
assert_true(M.isEqual(M.sort({'b','a','d','c'}),{'a','b','c','d'}))
it('uses "<" operator when no comparison function is given', function()
assert.is_true(M.isEqual(M.sort({'b','a','d','c'}),{'a','b','c','d'}))
end)
end)
context('sortBy', function()
describe('sortBy', function()
test('sort values on the result of a transform function', function()
assert_true(M.isEqual(M.sortBy({1,2,3,4,5}, math.sin), {5,4,3,1,2}))
it('sort values on the result of a transform function', function()
assert.is_true(M.isEqual(M.sortBy({1,2,3,4,5}, math.sin), {5,4,3,1,2}))
end)
test('the transform function defaults to M.identity', function()
assert_true(M.isEqual(M.sortBy({1,2,3,4,5}), {1,2,3,4,5}))
it('the transform function defaults to M.identity', function()
assert.is_true(M.isEqual(M.sortBy({1,2,3,4,5}), {1,2,3,4,5}))
end)
test('transform function can be a string name property', function()
it('transform function can be a string name property', function()
local unsorted = {{item = 1, value = 10},{item = 2, value = 5},{item = 3, value = 8}}
local sorted = {{item = 2, value = 5},{item = 3, value = 8},{item = 1, value = 10}}
assert_true(M.isEqual(M.sortBy(unsorted, 'value'), sorted))
assert.is_true(M.isEqual(M.sortBy(unsorted, 'value'), sorted))
end)
test('can use a custom comparison function', function()
it('can use a custom comparison function', function()
local unsorted = {{item = 1, value = 10},{item = 2, value = 5},{item = 3, value = 8}}
local sorted = {{item = 1, value = 10},{item = 3, value = 8},{item = 2, value = 5}}
local function comp(a,b) return a > b end
assert_true(M.isEqual(M.sortBy(unsorted, 'value', comp), sorted))
assert.is_true(M.isEqual(M.sortBy(unsorted, 'value', comp), sorted))
end)
end)
context('groupBy', function()
describe('groupBy', function()
test('splits a collection into subsets of items behaving the same', function()
it('splits a collection into subsets of items behaving the same', function()
assert_true(M.isEqual(M.groupBy({0,1,2,3,4,5,6},function(value)
assert.is_true(M.isEqual(M.groupBy({0,1,2,3,4,5,6},function(value)
return value%2==0 and 'even' or 'odd'
end),{even = {0,2,4,6},odd = {1,3,5}}))
assert_true(M.isEqual(M.groupBy({0,'a',true, false,nil,b,0.5},type),{number = {0,0.5},string = {'a'},boolean = {true,false}}))
assert.is_true(M.isEqual(M.groupBy({0,'a',true, false,nil,b,0.5},type),{number = {0,0.5},string = {'a'},boolean = {true,false}}))
assert_true(M.isEqual(M.groupBy({'one','two','three','four','five'},string.len),{[3] = {'one','two'},[4] = {'four','five'},[5] = {'three'}}))
assert.is_true(M.isEqual(M.groupBy({'one','two','three','four','five'},string.len),{[3] = {'one','two'},[4] = {'four','five'},[5] = {'three'}}))
end)
test('can takes extra-args', function()
it('can takes extra-args', function()
assert_true(M.isEqual(M.groupBy({3,9,10,12,15}, function(v,k,x) return v%x == 0 end,2), {[false] = {3,9,15}, [true] = {10,12}}))
assert_true(M.isEqual(M.groupBy({3,9,10,12,15}, function(v,k,x) return v%x == 0 end,3), {[false] = {10}, [true] = {3,9,12,15}}))
assert.is_true(M.isEqual(M.groupBy({3,9,10,12,15}, function(v,k,x) return v%x == 0 end,2), {[false] = {3,9,15}, [true] = {10,12}}))
assert.is_true(M.isEqual(M.groupBy({3,9,10,12,15}, function(v,k,x) return v%x == 0 end,3), {[false] = {10}, [true] = {3,9,12,15}}))
end)
end)
context('countBy', function()
describe('countBy', function()
test('splits a collection in subsets and counts items inside', function()
it('splits a collection in subsets and counts items inside', function()
assert_true(M.isEqual(M.countBy({0,1,2,3,4,5,6},function(value)
assert.is_true(M.isEqual(M.countBy({0,1,2,3,4,5,6},function(value)
return value%2==0 and 'even' or 'odd'
end),{even = 4,odd = 3}))
assert_true(M.isEqual(M.countBy({0,'a',true, false,nil,b,0.5},type),{number = 2,string = 1,boolean = 2}))
assert.is_true(M.isEqual(M.countBy({0,'a',true, false,nil,b,0.5},type),{number = 2,string = 1,boolean = 2}))
assert_true(M.isEqual(M.countBy({'one','two','three','four','five'},string.len),{[3] = 2,[4] = 2,[5] = 1}))
assert.is_true(M.isEqual(M.countBy({'one','two','three','four','five'},string.len),{[3] = 2,[4] = 2,[5] = 1}))
end)
end)
context('size', function()
describe('size', function()
test('counts the very number of objects in a collection', function()
assert_equal(M.size {1,2,3},3)
it('counts the very number of objects in a collection', function()
assert.equal(M.size {1,2,3},3)
end)
test('counts nested tables elements as an unique value', function()
assert_equal(M.size {1,2,3,{4,5}},4)
it('counts nested tables elements as an unique value', function()
assert.equal(M.size {1,2,3,{4,5}},4)
end)
test('leaves nil values', function()
assert_equal(M.size {1,2,3,nil,8},4)
it('leaves nil values', function()
assert.equal(M.size {1,2,3,nil,8},4)
end)
test('counts objects', function()
assert_equal(M.size {one = 1,2,b = 3, [{}] = 'nil', 'c', [function() end] = 'foo'},6)
it('counts objects', function()
assert.equal(M.size {one = 1,2,b = 3, [{}] = 'nil', 'c', [function() end] = 'foo'},6)
end)
test('returns the size of the first arg when it is a table', function()
assert_equal(M.size ({1,2},3,4,5),2)
it('returns the size of the first arg when it is a table', function()
assert.equal(M.size ({1,2},3,4,5),2)
end)
test('counts the number of non-nil args when the first one is not a table', function()
assert_equal(M.size (1,3,4,5),4)
assert_equal(M.size (nil,1,3,4,5),4)
assert_equal(M.size (nil,1,3,4,nil,5),4)
it('counts the number of non-nil args when the first one is not a table', function()
assert.equal(M.size (1,3,4,5),4)
assert.equal(M.size (nil,1,3,4,5),4)
assert.equal(M.size (nil,1,3,4,nil,5),4)
end)
test('handles nil', function()
assert_equal(M.size(),0)
assert_equal(M.size(nil),0)
it('handles nil', function()
assert.equal(M.size(),0)
assert.equal(M.size(nil),0)
end)
end)
context('containsKeys', function()
describe('containsKeys', function()
test('returns whether a table has all the keys from a given list', function()
assert_true(M.containsKeys({1,2,3},{1,2,3}))
assert_true(M.containsKeys({x = 1, y = 2},{x = 1,y =2}))
it('returns whether a table has all the keys from a given list', function()
assert.is_true(M.containsKeys({1,2,3},{1,2,3}))
assert.is_true(M.containsKeys({x = 1, y = 2},{x = 1,y =2}))
end)
test('does not compare values', function()
assert_true(M.containsKeys({1,2,3},{4,5,6}))
assert_true(M.containsKeys({x = 1, y = 2},{x = 4,y = -1}))
it('does not compare values', function()
assert.is_true(M.containsKeys({1,2,3},{4,5,6}))
assert.is_true(M.containsKeys({x = 1, y = 2},{x = 4,y = -1}))
end)
test('is not commutative', function()
assert_true(M.containsKeys({1,2,3,4},{4,5,6}))
assert_true(M.containsKeys({x = 1, y = 2,z = 5},{x = 4,y = -1}))
assert_false(M.containsKeys({1,2,3},{4,5,6,7}))
assert_false(M.containsKeys({x = 1, y = 2},{x = 4,y = -1,z = 0}))
it('is not commutative', function()
assert.is_true(M.containsKeys({1,2,3,4},{4,5,6}))
assert.is_true(M.containsKeys({x = 1, y = 2,z = 5},{x = 4,y = -1}))
assert.is_false(M.containsKeys({1,2,3},{4,5,6,7}))
assert.is_false(M.containsKeys({x = 1, y = 2},{x = 4,y = -1,z = 0}))
end)
end)
context('sameKeys', function()
describe('sameKeys', function()
test('returns whether both tables features the same keys', function()
assert_true(M.sameKeys({1,2,3},{1,2,3}))
assert_true(M.sameKeys({x = 1, y = 2},{x = 1,y =2}))
it('returns whether both tables features the same keys', function()
assert.is_true(M.sameKeys({1,2,3},{1,2,3}))
assert.is_true(M.sameKeys({x = 1, y = 2},{x = 1,y =2}))
end)
test('does not compare values', function()
assert_true(M.sameKeys({1,2,3},{4,5,6}))
assert_true(M.sameKeys({x = 1, y = 2},{x = 4,y = -1}))
it('does not compare values', function()
assert.is_true(M.sameKeys({1,2,3},{4,5,6}))
assert.is_true(M.sameKeys({x = 1, y = 2},{x = 4,y = -1}))
end)
test('is commutative', function()
assert_false(M.sameKeys({1,2,3,4},{4,5,6}))
assert_false(M.sameKeys({x = 1, y = 2,z = 5},{x = 4,y = -1}))
assert_false(M.sameKeys({1,2,3},{4,5,6,7}))
assert_false(M.sameKeys({x = 1, y = 2},{x = 4,y = -1,z = 0}))
it('is commutative', function()
assert.is_false(M.sameKeys({1,2,3,4},{4,5,6}))
assert.is_false(M.sameKeys({x = 1, y = 2,z = 5},{x = 4,y = -1}))
assert.is_false(M.sameKeys({1,2,3},{4,5,6,7}))
assert.is_false(M.sameKeys({x = 1, y = 2},{x = 4,y = -1,z = 0}))
end)
end)