#!/usr/bin/python3 # Copyright 2020 Weber Yann # # This file is part of geneifs. # # 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 . # import sys import random import math import pickle import unittest from unittest import skip IMAX = (1<<64)-1 try: import pyrpn except (ImportError, NameError) as e: print("Error importing pyrpn. Try to run make.", file=sys.stderr) raise e class Test0RpnModule(unittest.TestCase): def test_init(self): """ RPNExpr instanciation """ expr = pyrpn.RPNExpr("42", 2) def test_init_badargs(self): """ RPNExpr instanciation with bad arguments """ badargs = [('', 2), (), ('ab+',), ('ab+',300), (42, 42), ('ab', '42')] for badarg in badargs: with self.assertRaises((ValueError, TypeError)): expr = pyrpn.RPNExpr(*badarg) def test_init_loop(self): """ Testing pyrpn.RPNExpr multiple instanciation """ exprs = [] for i in range(256): expr = pyrpn.RPNExpr("42", 2) def test_init_args(self): """ Testing pyrpn.RPNExpr instanciation with arguments """ for argc in range(0, 256): with self.subTest("RPNExpr('42', %d)" % argc): expr = pyrpn.RPNExpr("42", argc) def test_init_stack_sz(self): """ Instanciate RPNExpr specifiing a stack_size """ for argc in range(0,256, 8): for sz in range(4, 256, 2): with self.subTest("RPNExpr('42', %d,%d)" % (argc, sz)): expr = pyrpn.RPNExpr("42", argc, sz) def test_op_dict(self): """ Testing RPNExpr.get_ops() method """ known_ops = dict([ ('add', '+'), ('sub', '-'), ('mul', '*'), ('div', '/'), ('mod', '%'), ('neg', '!'), ('not', '~'), ('and', '&'), ('or', '|'), ('xor', '^'), ('>>', 'r'), ('<<', 'l'), ('xchg', 'x'), ('dup', 'd'), ('pop', 'p'), ]) for long, short in pyrpn.get_ops().items(): self.assertIn(long, known_ops) self.assertEqual(short, known_ops[long]) def test_rand_expr(self): """ Testing RPNExpr.random_expr() """ result = {} counters = {'vals': 0, 'args': 0} all_count = 0 for sz in range(1,64,3): for argc in range(1,128): rnd_expr = pyrpn.random_expr(argc, sz) #print(repr(rnd_expr)) for tok in rnd_expr.split(' '): all_count += 1 if len(tok) == 0: continue try: itok = int(tok, 0) counters['vals'] += 1 continue except Exception: pass if tok[0] == 'A': counters['args'] += 1 else: if tok not in counters: counters[tok] = 0 counters[tok] += 1 all_ops = len(pyrpn.get_ops()) + 2 entropy = 1-sum([(n/all_count)**2 for _, n in counters.items()]) self.assertGreater(entropy, 1-(1/all_ops), "Low entropy !") if __name__ == '__main__': unittest.main()