diff --git a/ngcp/utils.lua b/ngcp/utils.lua index ac7fe43..1333e2c 100644 --- a/ngcp/utils.lua +++ b/ngcp/utils.lua @@ -159,12 +159,26 @@ end -- GLOBAL Stack = { - __class__ = 'Stack', + __class__ = 'Stack' } Stack_MT = { - __index = Stack, __tostring = function(t) return table.tostring(Stack.list(t)) + end, + -- this works only on Lua5.2 + __len = function(t) + return Stack.size(t) + end, + __index = function(t,k) + if type(k) == 'number' then + return Stack.get(t,k) + end + return rawget(Stack,k) + end, + __newindex = function(t,k,v) + if type(k) == 'number' then + Stack.set(t,k,v) + end end } @@ -174,6 +188,7 @@ Stack_MT = { setmetatable(t, Stack_MT) return t end + -- push a value on to the stack function Stack:push(...) if ... then @@ -208,6 +223,30 @@ Stack_MT = { return unpack(entries) end + -- get pos ( starts on 0) + function Stack:get(pos) + assert(pos) + assert(pos>=0) + local indx = #self._et - pos + if indx>0 then + return self._et[indx] + end + end + + -- set a value in a pos (stars on 0) + function Stack:set(pos, value) + assert(pos) + assert(pos>=0) + local indx = #self._et - pos + if indx>0 then + if self._et[indx] then + self._et[indx] = value + else + error("No pos:"..pos) + end + end + end + -- get entries function Stack:size() return #self._et diff --git a/tests/utils.lua b/tests/utils.lua index 5029968..98cd463 100644 --- a/tests/utils.lua +++ b/tests/utils.lua @@ -103,23 +103,117 @@ TestUtils = {} --class TestStack = {} function TestStack:test() - s = Stack:new() - assertEquals(#s._et,0) + local s = Stack:new() + assertEquals(type(s), 'table') + assertEquals(s.__class__, 'Stack') + end + + function TestStack:test_size() + local s = Stack:new() + assertEquals(s:size(),0) + s:push(1) + assertEquals(s:size(),1) + s:pop() + assertEquals(s:size(),0) + end + + function TestStack:test_push() + local s s = Stack:new() + s:push(1) + assertEquals(s:size(),1) + end + + function TestStack:test_pop() + local s = Stack:new() assertEquals(s:pop(), nil) s:push(1) - assertEquals(#s._et,1) + assertEquals(s:size(),1) assertEquals(s:pop(),1) assertEquals(s:size(),0) + end + + function TestStack:test_get() + local s = Stack:new() s:push(1) + assertEquals(s:get(0),1) s:push({1,2,3}) + assertEquals(s:get(0),{1,2,3}) + assertEquals(s:get(1),1) + assertError(s.get, s, -1) + assertIsNil(s:get(2)) + end + + function TestStack:test_get_op() + local s = Stack:new() + s:push(1) + assertEquals(s[0],1) + s:push({1,2,3}) + assertEquals(s[0],{1,2,3}) + assertEquals(s[1],1) + assertIsNil(s[2]) + end + + function TestStack:test_set() + local s = Stack:new() + s:push(1) + s:push({1,2,3}) + assertEquals(s:size(),2) + assertEquals(s:get(0),{1,2,3}) + assertEquals(s:get(1),1) + s:set(1, 2) + assertEquals(s:size(),2) + assertEquals(s:get(0),{1,2,3}) + assertEquals(s:get(1),2) + s:set(2, 3) + assertEquals(s:size(),2) + assertEquals(s:get(0),{1,2,3}) + assertEquals(s:get(1),2) + assertIsNil(s:get(2)) + assertError(s.set, s, "no", -1) + assertError(s.set, s, -1, 2) + end + + function TestStack:test_set_op() + local s = Stack:new() + s:push(1) + s:push({1,2,3}) + assertEquals(s:size(),2) + assertEquals(s:get(0),{1,2,3}) + assertEquals(s:get(1),1) + s[1] = 2 assertEquals(s:size(),2) + assertEquals(s:get(0),{1,2,3}) + assertEquals(s:get(1),2) + s[0] = "new" + assertEquals(s:size(),2) + assertEquals(s:get(0),"new") + assertEquals(s:get(1),2) + s[1] = "old" + assertEquals(s:get(0),"new") + assertEquals(s:get(1),"old") + assertEquals(s:size(),2) + s[2] = "error" + assertEquals(s:get(0),"new") + assertEquals(s:get(1),"old") + assertIsNil(s:get(2)) + assertEquals(s:size(),2) + end + + function TestStack:test_list() + local s = Stack:new() local l = s:list() + assertEquals(#l, 0) + s:push(1) + s:push({1,2,3}) + assertEquals(s:size(),2) + l = s:list() assertItemsEquals(l[1],{1,2,3}) assertEquals(l[2],1) + assertEquals(s:size(),2) end function TestStack:test_tostring() - s = Stack:new() + local s = Stack:new() s:push(1) assertEquals(tostring(s), "{1}") s:push(2)