rpnifs/tests/tests_rpn_tokens.py

162 lines
5.9 KiB
Python
Executable file

#!/usr/bin/python3
# Copyright 2023 Weber Yann
#
# This file is part of rpnifs.
#
# geneifs is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# geneifs is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with geneifs. If not, see <http://www.gnu.org/licenses/>.
#
import sys
import random
import unittest
try:
import pyrpn
except (ImportError, NameError) as e:
print("Error importing pyrpn. Try to run make.",
file=sys.stderr)
raise e
class TestRpnToken(unittest.TestCase):
""" Testing tokens submodule """
def test_token_str_convertion(self):
""" Testing token <-> str convvertion """
expl = ('+', '-', '&',
'A1', 'A0', 'A1337',
'0x0', '0x1312')
for estr in expl:
t = pyrpn.tokens.Token.from_str(estr)
with self.subTest(str=estr, token=t):
self.assertEqual(str(t), estr)
class TestRpnTokenOperand(unittest.TestCase):
""" Testing operand tokens """
def test_str_init(self):
""" Testing operand token initialization """
test_str = ('add', '+', '-', 'sub', 'and', 'xor')
for op in test_str:
t = pyrpn.tokens.Operand(op)
with self.subTest(opstr=op, token=t):
self.assertIn(str(t), [t.chr(), t.str()])
def test_int_init(self):
""" Testing operand token initialization with all opcodes """
for i in range(pyrpn.tokens.Operand.opcode_max()+1):
t = pyrpn.tokens.Operand(i)
with self.subTest(opcode=i, token=t):
self.assertEqual(i, t.opcode)
def test_badarg_init(self):
""" Testing operand token initialization with bad argument """
badargs = ('cxwccseuhefsdfiyg', -1, -150,
pyrpn.tokens.Operand.opcode_max()+1,
pyrpn.tokens.Operand.opcode_max()*2)
badtypes = ('0x12', 'A1',
dict(), tuple(), b'+')
for badarg in badargs:
with self.subTest(badarg=badarg):
with self.assertRaises(ValueError):
t = pyrpn.tokens.Operand(badarg)
for badtype in badtypes:
with self.subTest(badtype=badtype):
with self.assertRaises(TypeError):
t = pyrpn.tokens.Operand(badtype)
class TestRpnTokenValue(unittest.TestCase):
""" Testing value tokens """
def test_init(self):
""" Testing value token initialization """
for _ in range(1000):
rnd = random.randint(0,(1<<64) -1 )
t = pyrpn.tokens.Value(rnd)
with self.subTest(token=t, value=rnd):
self.assertEqual(int(str(t), 16), rnd)
def test_badarg_init(self):
""" Testing value token initialization with bad argument """
badtypes = ('A1', 'add', '+', dict(), tuple(), 5.0)
for badtype in badtypes:
with self.subTest(badarg=badtype):
with self.assertRaises(TypeError):
t = pyrpn.tokens.Value(badtype)
self.assertEqual(int(str(t), 16), badtype)
def test_badarg_overflow(self):
""" Testing value token initialization overflow """
badtypes = (1<<64, -1)
for badtype in badtypes:
with self.subTest(badarg=badtype):
with self.assertRaises(OverflowError):
t = pyrpn.tokens.Value(badtype)
self.assertEqual(int(str(t), 16), badtype)
class TestRpnTokenArgument(unittest.TestCase):
""" Testing argument tokens """
def test_init(self):
""" Testing argument token initialization """
for _ in range(1000):
rnd = random.randint(0,(1<<64) -1 )
t = pyrpn.tokens.Argument(rnd)
with self.subTest(token=t, argument=rnd):
self.assertEqual(int(str(t)[1:],10), rnd)
def test_badarg_init(self):
""" Testing argument token initialization with bad argument """
badtypes = ('0x1', 'add', '+', dict(), tuple(), 5.0)
for badtype in badtypes:
with self.subTest(badarg=badtype):
with self.assertRaises(TypeError):
t = pyrpn.tokens.Argument(badtype)
self.assertEqual(int(str(t), 16), badtype)
def test_badarg_overflow(self):
""" Testing argument token initialization overflow """
badtypes = (1<<64, -1)
for badtype in badtypes:
with self.subTest(badarg=badtype):
with self.assertRaises(OverflowError):
t = pyrpn.tokens.Argument(badtype)
self.assertEqual(int(str(t), 16), badtype)
#TODO move in a file dedicated to RPNExpr checks
class TestTokenExprRepr(unittest.TestCase):
""" Test RPNExpr sequence implementation """
def test_rpnexpr_sequence(self):
""" Testing sequence implementation of RPNExpr """
for _ in range(100):
argc = random.randint(0,100)
token_count = random.randint(0, 200)
expr_str = pyrpn.random_expr(argc, token_count)
expr = pyrpn.RPNExpr(expr_str, argc)
with self.subTest(argc=argc, token_count=token_count,
expr=expr, expr_str=expr_str):
self.assertEqual(token_count, len(expr))
self.assertEqual(' '.join([str(token) for token in expr]),
expr_str)
if __name__ == '__main__':
unittest.main()