diff --git a/.gitignore b/.gitignore index 343b974..0848d84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +/.coverage /.python-version +/htmlcov __javascript__ __pycache__ diff --git a/eos/base/tests.py b/eos/base/tests.py index f2b7f78..c8fab26 100644 --- a/eos/base/tests.py +++ b/eos/base/tests.py @@ -20,7 +20,7 @@ from eos.base.election import * from eos.base.workflow import * from eos.core.objects import * -class ElectionTestCase(TestCase): +class ElectionPyTestCase(TestCase): @classmethod def setUpClass(cls): client.drop_database('test') @@ -40,8 +40,11 @@ class ElectionTestCase(TestCase): # Check _instance self.assertEqual(election.workflow._instance, (election, 'workflow')) + # Check workflow behaviour self.assertEqual(election.workflow.get_task('eos.base.workflow.TaskConfigureElection').status, WorkflowTask.Status.READY) + self.assertEqual(election.workflow.get_task('does.not.exist'), None) + # Set election details election.name = 'Test Election' for i in range(3): @@ -59,12 +62,20 @@ class ElectionTestCase(TestCase): election.save() # Check that it saved - self.assertEqual(db[Election._name].find_one(), election.serialise()) + self.assertEqual(db[Election._name].find_one()['value'], election.serialise()) + self.assertEqual(EosObject.deserialise_and_unwrap(db[Election._name].find_one()).serialise(), election.serialise()) # Freeze election self.exit_task_assert(election, 'eos.base.workflow.TaskConfigureElection', 'eos.base.workflow.TaskOpenVoting') election.save() + # Try to freeze it again + try: + election.workflow.get_task('eos.base.workflow.TaskConfigureElection').exit() + self.fail() + except Exception: + pass + # Cast ballots VOTES = [[[0], [0]], [[0, 1], [1]], [[2], [0]]] diff --git a/eos/core/bitstring.py b/eos/core/bitstring.py new file mode 100644 index 0000000..ec85c94 --- /dev/null +++ b/eos/core/bitstring.py @@ -0,0 +1,17 @@ +# Eos - Verifiable elections +# Copyright © 2017 RunasSudo (Yingtong Li) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from eos.core.objects import * diff --git a/eos/core/objects/python.py b/eos/core/objects/python.py index 62ca1b5..c37c8b2 100644 --- a/eos/core/objects/python.py +++ b/eos/core/objects/python.py @@ -85,7 +85,7 @@ class UUIDField(Field): def serialise(self, value): return str(value) - def unserialise(self, value): + def deserialise(self, value): return uuid.UUID(value) # Objects @@ -169,6 +169,8 @@ class DocumentObjectType(EosObjectType): return cls class DocumentObject(EosObject, metaclass=DocumentObjectType): + _ver = StringField(default='0.1') + def __init__(self, *args, **kwargs): super().__init__() @@ -188,11 +190,12 @@ class DocumentObject(EosObject, metaclass=DocumentObjectType): @classmethod def deserialise(cls, value): - return cls(**value) # wew + return cls(**{attr: val.deserialise(value[attr]) for attr, val in cls._fields.items()}) class TopLevelObject(DocumentObject): def save(self): - res = db[self._name].replace_one({'_id': self.serialise()['_id']}, self.serialise(), upsert=True) + #res = db[self._name].replace_one({'_id': self.serialise()['_id']}, self.serialise(), upsert=True) + res = db[self._name].replace_one({'_id': self._fields['_id'].serialise(self._id)}, EosObject.serialise_and_wrap(self), upsert=True) class EmbeddedObject(DocumentObject): pass diff --git a/eos/core/tests.py b/eos/core/tests.py index 9bbde91..9a68707 100644 --- a/eos/core/tests.py +++ b/eos/core/tests.py @@ -16,9 +16,11 @@ from unittest import TestCase +from eos.core.bigint import * +from eos.core.bitstring import * from eos.core.objects import * -class PyTestCase(TestCase): +class ObjectPyTestCase(TestCase): @classmethod def setUpClass(cls): class Person(TopLevelObject): @@ -29,7 +31,7 @@ class PyTestCase(TestCase): cls.Person = Person - def test_basic_py(self): + def test_basic(self): person1 = self.Person(name='John', address='Address 1') person2 = self.Person(name='James', address='Address 2') @@ -38,10 +40,30 @@ class PyTestCase(TestCase): self.assertEqual(person1.say_hi(), 'Hello! My name is John') self.assertEqual(person2.say_hi(), 'Hello! My name is James') - def test_serialise_py(self): + def test_serialise(self): person1 = self.Person(name='John', address='Address 1') - expect1 = {'name': 'John', 'address': 'Address 1'} + expect1 = {'_ver': '0.1', 'name': 'John', 'address': 'Address 1'} + expect1a = {'type': 'eos.core.tests.ObjectPyTestCase.setUpClass..Person', 'value': expect1} self.assertEqual(person1.serialise(), expect1) self.assertEqual(EosObject.serialise_and_wrap(person1, self.Person), expect1) - self.assertEqual(EosObject.serialise_and_wrap(person1), {'type': 'eos.core.tests.PyTestCase.setUpClass..Person', 'value': expect1}) + self.assertEqual(EosObject.serialise_and_wrap(person1), expect1a) + + #self.assertEqual(EosObject.deserialise_and_unwrap(expect1a), person1) + self.assertEqual(EosObject.deserialise_and_unwrap(expect1a).serialise(), person1.serialise()) + +class BigIntPyTestCase(TestCase): + def test_basic(self): + bigint1 = BigInt(5) + bigint2 = BigInt('A', 16) + bigint3 = BigInt('15') + + self.assertEqual(bigint1, 5) + self.assertEqual(bigint2, 10) + self.assertEqual(bigint3, 15) + + self.assertEqual(bigint1 + bigint2, 15) + self.assertEqual(bigint3 - bigint2, bigint1) + self.assertEqual(pow(bigint1, bigint2), pow(5, 10)) + self.assertEqual(pow(bigint1, bigint2, bigint3), pow(5, 10, 15)) + self.assertEqual(pow(bigint1, 10, 15), pow(5, 10, 15)) diff --git a/test.sh b/test.sh index 4574fed..f3ef02c 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,3 @@ #!/bin/bash -ARGS=-vvv - -for test in eos.core.tests eos.base.tests; do - python -m unittest $test $ARGS || exit 1 -done +coverage run --source=eos --omit='*/js.py','*/tests.py' -m unittest discover . -vvv || exit 1 +coverage html