You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lua-lemock/src/argv.nw

159 lines
4.3 KiB

Lua Easy Mock -- LeMock
Copyright (C) 2009 Tommy Pettersson <ptp@lysator.liu.se>
See terms in file COPYRIGHT, or at http://lemock.luaforge.net
@
Class Argv
##########
It is convenient to handle argument lists and return lists as an abstract
type.
<<Userguide Anyargs>>=
An //anyarg// is a special argument used when recording, that will match
any argument during replay. It can appear anywhere and any times in an
argument list, or as the argument in an assignment, to replace real
arguments. There is also //anyargs//, which will match any number
(including zero) of any arguments. Anyargs can only appear as the last
argument of an argument list. Anyarg and anyargs are handy when the actual
values of the arguments during replay are unimportant or unknown.
@
new
---
<<Unit test for class Argv method new>>=
function new_test ()
Argv:new( Argv.ANYARGS )
Argv:new( 1, Argv.ANYARGS )
Argv:new( 1, 2, Argv.ANYARGS )
end
function new_anyargs_with_extra_arguments_fails_test ()
local l = {}
l['ANYARGS,1'] = { Argv.ANYARGS, 1 }
l['ANYARGS,ANYARGS' ] = { Argv.ANYARGS, Argv.ANYARGS }
l['1,ANYARGS,1'] = { 1, Argv.ANYARGS, 1 }
l['1,ANYARGS,ANYARGS'] = { 1, Argv.ANYARGS, Argv.ANYARGS }
for msg, args in pairs( l ) do
local ok, err = pcall( function() Argv:new( unpack(args) ) end )
assert_false( ok, "Bad ANYARGS accepted for "..msg )
assert_match( "ANYARGS not at end", err )
end
end
<<Class Argv method new>>=
function Argv:new (...)
local av = object( self )
av.v = {...}
av.len = select('#',...)
for i = 1, av.len - 1 do
if av.v[i] == Argv.ANYARGS then
error( "ANYARGS not at end.", 0 )
end
end
return av
end
@
equal
-----
<<Unit test for class Argv method equal>>=
local l = {}
local function p (...) l[#l+1] = { n=select('#',...), ... } end
p() p(nil) p(nil,nil) p(false) p({}) p(false,nil,{},nil) p(nil,p)
p(true) p(0.1,'','a') p(1/0,nil,0/0) p(0/0) p(0/0, true) p(0/0, false)
function equal_test ()
local a1, a2, f, op
for i = 1, #l do
ai = Argv:new( unpack( l[i], 1, l[i].n ))
for j = 1, #l do
aj = Argv:new( unpack( l[j], 1, l[j].n ))
if i == j then
f, op = assert_true, ') ~= ('
else
f, op = assert_false, ') == ('
end
f( ai:equal(aj), '('..ai:tostring()..op..aj:tostring()..')' )
end
end
end
function equal_anyargs_test ()
local a, b = {}, {}
a[1] = Argv:new( Argv.ANYARGS )
a[2] = Argv:new( 6, Argv.ANYARGS )
a[3] = Argv:new( 6, 5, Argv.ANYARGS )
for i = 1, #l do
b[1] = Argv:new( unpack( l[i], 1, l[i].n ))
b[2] = Argv:new( 6, unpack( l[i], 1, l[i].n ))
b[3] = Argv:new( 6, 5, unpack( l[i], 1, l[i].n ))
for j = 1, 3 do
local astr = '('..a[j]:tostring()..')'
local bstr = '('..b[j]:tostring()..')'
assert_true( a[j]:equal(b[j]), astr..' ~= '..bstr )
assert_true( b[j]:equal(a[j]), bstr..' ~= '..astr )
end
end
end
function equal_anyarg_test ()
local l = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
local a1 = Argv:new( unpack(l) )
for i = 1, 9 do
l[i] = Argv.ANYARG
local a2 = Argv:new( unpack(l) )
assert_true( a1:equal(a2) )
assert_true( a2:equal(a1) )
l[i] = i
end
end
@
The comparison with ANYARGS is a bit tricky, because it must match the
empty list. The list //excluding// the final ANYARGS argument (its length
minus one) must match the other list.
ANYARG and ANYARGS are created as unique identifiers, with local aliases
for speed.
<<Class Argv method equal>>=
Argv.ANYARGS = newproxy() local ANYARGS = Argv.ANYARGS
Argv.ANYARG = newproxy() local ANYARG = Argv.ANYARG
function Argv:equal (other)
local a1, n1 = self.v, self.len
local a2, n2 = other.v, other.len
if n1-1 <= n2 and a1[n1] == ANYARGS then
n1 = n1-1
n2 = n1
elseif n2-1 <= n1 and a2[n2] == ANYARGS then
n2 = n2-1
n1 = n2
end
if n1 ~= n2 then
return false
end
for i = 1, n1 do
local v1, v2 = a1[i], a2[i]
if not value_equal(v1,v2) and v1 ~= ANYARG and v2 ~= ANYARG then
return false
end
end
return true
end
@
unpack
------
<<Unit test for class Argv method unpack>>=
function unpack_test ()
local a, b, c = Argv:new( false, nil, 7 ):unpack()
assert_equal( false, a )
assert_equal( nil, b )
assert_equal( 7, c )
end
<<Class Argv method unpack>>=
function Argv:unpack ()
return unpack( self.v, 1, self.len )
end