123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- #!/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 copy
- import pickle
- import sys
-
- import unittest
-
-
- try:
- import pyrpn
- except (ImportError, NameError) as e:
- print("Error importing pyrpn. Try to run make.",
- file=sys.stderr)
- raise e
-
-
- ## TODO : move this function somewhere or implement it in C
- def decode_state(state):
- """ Return a dict containing rpn state dump fields
- """
- res = dict()
- res['real_sz'] = len(state)
- res['total_sz'] = int.from_bytes(state[0:8], byteorder="little")
- res['argc'] = int.from_bytes(state[8:16], byteorder="little")
- res['stack_sz_bytes'] = state[16:24]
- res['stack_sz'] = state[16]
- res['token_sz'] = int.from_bytes(state[24:32], byteorder="little", signed=True)
- res['stack'] = [int.from_bytes(state[i:i+8], byteorder="little")
- for i in range(32, 32 + (8*res['stack_sz']),8)]
- res['tokens_off'] = 32 + (8*res['stack_sz'])
- res['tokens_real_sz'] = res['real_sz'] - res['tokens_off']
- res['tokens'] = [state[i:i+24]
- for i in range(res['tokens_off'],
- res['tokens_off'] + (24*res['token_sz']),
- 24)]
- return res
-
-
-
- class TestRpnExprState(unittest.TestCase):
- """ Testing RPNExpr "state" related methods (__copy__, __get/setstate__)
- """
-
- def test_pickle_state(self):
- """ Testing pickling/unpickling """
- e = pyrpn.RPNExpr('0x42 + A0', 2)
- e2 = pickle.loads(pickle.dumps(e))
- ds_e = decode_state(e.__getstate__())
- ds_e2 = decode_state(e2.__getstate__())
- self.assertEqual(e.__getstate__(), e2.__getstate__(),
- msg="EXPR: %r != %r (%r != %r)" % (e, e2, ds_e, ds_e2))
- for i in range(100):
- e = pyrpn.RPNExpr(pyrpn.random_expr(0), 2)
- e.mutate(n_mutations=15);
-
- e2 = pickle.loads(pickle.dumps(e))
-
- self.assertEqual(e.__getstate__(), e2.__getstate__(),
- msg="EXPR#%d : %r != %r" % (i,e, e2))
-
- e3 = pickle.loads(pickle.dumps(e2))
-
- self.assertEqual(e.__getstate__(), e3.__getstate__(), msg=e)
- self.assertEqual(e2.__getstate__(), e3.__getstate__(), msg=e)
-
-
-
- def test_copy(self):
- """ Basic copy test based on pickling """
- e = pyrpn.RPNExpr('0x42 + A0', 2)
- e2 = copy.copy(e)
- ds_e = decode_state(e.__getstate__())
- ds_e2 = decode_state(e2.__getstate__())
- self.assertEqual(e.__getstate__(), e2.__getstate__(),
- msg="EXPR: %r != %r (%r != %r)" % (e, e2, ds_e, ds_e2))
- for i in range(100):
- e = pyrpn.RPNExpr(pyrpn.random_expr(0), 2)
-
- e2 = copy.copy(e)
-
- self.assertEqual(e.__getstate__(), e2.__getstate__(),
- msg="EXPR#%d : %r != %r" % (i,e, e2))
-
- e3 = pickle.loads(pickle.dumps(e2))
-
- self.assertEqual(e.__getstate__(), e3.__getstate__(), msg=e)
- self.assertEqual(e2.__getstate__(), e3.__getstate__(), msg=e)
-
-
- if __name__ == '__main__':
- unittest.main()
|