예제 #1
0
    def testPatternGlobalCrafter(self):
        @pattern
        class Foo(object):
            folds = 'a=uint:8'
            pass

        assert hasattr(Foo, 'unfold')
        assert Foo in Crafter('global').patterns
예제 #2
0
 def testGlobalCrafter(self):
     assert Crafter().name == 'global'
     assert Crafter() is Crafter('global')
예제 #3
0
 def setUp(self):
     self.id = unique_id()
     self.crafter = Crafter(self.id)
예제 #4
0
class CrafterTests(unittest.TestCase):
    def setUp(self):
        self.id = unique_id()
        self.crafter = Crafter(self.id)

    def testGlobalCrafter(self):
        assert Crafter().name == 'global'
        assert Crafter() is Crafter('global')

    def testRepr(self):
        expected = "Crafter('{}')".format(self.id)
        assert repr(self.crafter) == expected

    def testLearnPattern(self):
        class Foo(object):
            pass
        cls = Foo
        unfold_func = lambda: None
        folds = 'a=uint:8'
        creases = {}

        self.crafter.learn_pattern(cls, unfold_func, folds, creases)
        assert cls in self.crafter.patterns

    def testLearnPatternEmptyClass(self):
        cls = None
        unfold_func = lambda: None
        folds = 'a=uint:8'
        creases = {}

        with pytest.raises(OrigamiException):
            self.crafter.learn_pattern(cls, unfold_func, folds, creases)

    def testLearnSamePatternTwice(self):
        class Foo(object):
            pass
        cls = Foo
        unfold_func = lambda: None
        folds = 'a=uint:8'
        creases = {}

        self.crafter.learn_pattern(cls, unfold_func, folds, creases)
        with pytest.raises(OrigamiException):
            self.crafter.learn_pattern(cls, unfold_func, folds, creases)

    def testLearnPatternInvalidFolds(self):
        class Foo(object):
            pass
        cls = Foo
        unfold_func = lambda: None
        folds = 'a=uint:NotANumber'
        creases = {}

        with pytest.raises(OrigamiException):
            self.crafter.learn_pattern(cls, unfold_func, folds, creases)

    def testFoldPattern(self):
        class Foo(object):
            pass
        cls = Foo
        unfold_func = lambda: None
        folds = 'a=uint:8'
        creases = {}
        self.crafter.learn_pattern(cls, unfold_func, folds, creases)

        foo = Foo()
        foo.a = 127
        data = bitstring.pack('uint:8', foo.a)
        assert self.crafter.fold(foo) == data

    def testFoldUnknownPattern(self):
        class Foo(object):
            pass
        foo = Foo()
        with pytest.raises(OrigamiException):
            self.crafter.fold(foo)

    def testFoldMissingAttribute(self):
        class Foo(object):
            pass
        cls = Foo
        unfold_func = lambda: None
        folds = 'a=uint:8'
        creases = {}
        self.crafter.learn_pattern(cls, unfold_func, folds, creases)

        with pytest.raises(OrigamiException):
            self.crafter.fold(Foo())

    def testFoldInvalidDataType(self):
        class Foo(object):
            pass
        cls = Foo
        unfold_func = lambda: None
        folds = 'a=uint:8'
        creases = {}
        self.crafter.learn_pattern(cls, unfold_func, folds, creases)
        foo = Foo()
        foo.a = 'NotANumber'
        with pytest.raises(OrigamiException):
            self.crafter.fold(foo)

    def testFoldOutOfRangeValue(self):
        class Foo(object):
            pass
        cls = Foo
        unfold_func = lambda: None
        folds = 'a=uint:8'
        creases = {}
        self.crafter.learn_pattern(cls, unfold_func, folds, creases)
        foo = Foo()
        foo.a = 1 << 20
        with pytest.raises(OrigamiException):
            self.crafter.fold(foo)

    def testUnfoldPattern(self):
        class Foo(object):
            pass
        cls = Foo

        def unfold_func(name, instance, **kw):
            instance = instance or Foo()
            instance.a = kw['a']
            return instance
        folds = 'a=uint:8'
        creases = {}
        self.crafter.learn_pattern(cls, unfold_func, folds, creases)

        value = 127
        data = bitstring.pack('uint:8', value)
        foo = self.crafter.unfold(data, Foo)
        assert foo.a == value

    def testUnfoldUnknownPattern(self):
        class Foo(object):
            pass
        with pytest.raises(OrigamiException):
            self.crafter.unfold(None, Foo)

    def testUnfoldMissingData(self):
        class Foo(object):
            pass
        cls = Foo

        def unfold_func(name, instance, **kw):
            instance = instance or Foo()
            instance.a = kw['a']
            instance.b = kw['b']
            return instance
        folds = 'a=uint:8, b=uint:8'
        creases = {}
        self.crafter.learn_pattern(cls, unfold_func, folds, creases)

        value = 127
        data = bitstring.pack('uint:8', value)
        with pytest.raises(OrigamiException):
            self.crafter.unfold(data, Foo)

    def testUnfoldInvalidDataType(self):
        class Foo(object):
            pass
        cls = Foo

        def unfold_func(name, instance, **kw):
            instance = instance or Foo()
            instance.a = kw['a']
            instance.b = kw['b']
            return instance
        folds = 'a=uint:8, b=uint:8'
        creases = {}
        self.crafter.learn_pattern(cls, unfold_func, folds, creases)

        a, b = 120, 1023
        data = bitstring.pack('uint:8, uint:10', a, b)
        foo = self.crafter.unfold(data, Foo)
        assert foo.a == a
        assert foo.b != b

    def testUnfoldConcatenatedValues(self):
        class Foo(object):
            pass
        cls = Foo

        def unfold_func(name, instance, **kw):
            instance = instance or Foo()
            instance.a = kw['a']
            instance.b = kw['b']
            return instance
        folds = 'a=uint:8, b=uint:8'
        creases = {}
        self.crafter.learn_pattern(cls, unfold_func, folds, creases)

        a, b = 120, 254
        other_a, other_b = 121, 255
        data = bitstring.pack('uint:8, uint:8', a, b)
        data += bitstring.pack('uint:8, uint:8', other_a, other_b)

        foo = self.crafter.unfold(data, Foo)
        other_foo = self.crafter.unfold(data, Foo)

        assert foo.a == a
        assert foo.b == b
        assert other_foo.a == other_a
        assert other_foo.b == other_b

    def testFoldsUnknownCrafter(self):
        class Foo(object):
            pass
        cls = Foo

        def unfold_func(name, instance, **kw):
            return instance

        folds = {"unknown crafter": 'a=uint:8, b=uint:1'}
        creases = {}
        with pytest.raises(OrigamiException):
            self.crafter.learn_pattern(cls, unfold_func, folds, creases)

    def testCreaseWithoutCustomFmt(self):
        counter, my_int_creases = count_creases(fold=int, unfold=str)

        class Foo(object):
            pass
        cls = Foo

        def unfold_func(name, instance, **kw):
            return instance

        creases = {
            'custom_crease': {
                'fold': int,
                'unfold': int
            }
        }

        folds = {self.id: 'a=custom_crease'}
        with pytest.raises(OrigamiException):
            self.crafter.learn_pattern(cls, unfold_func, folds, creases)

    def testCreaseMissingFold(self):
        class Foo(object):
            pass
        cls = Foo

        def unfold_func(name, instance, **kw):
            return instance

        folds = {self.id: 'a=uint:8'}
        creases = {
            "uint:8": {
                "unfold": int
            }
        }
        with pytest.raises(OrigamiException):
            self.crafter.learn_pattern(cls, unfold_func, folds, creases)

    def testCreaseMissingUnfold(self):
        class Foo(object):
            pass
        cls = Foo

        def unfold_func(name, instance, **kw):
            return instance

        folds = {self.id: 'a=uint:8'}
        creases = {
            "uint:8": {
                "fold": int
            }
        }
        with pytest.raises(OrigamiException):
            self.crafter.learn_pattern(cls, unfold_func, folds, creases)

    def testInvalidNameFmt(self):
        class Foo(object):
            pass
        cls = Foo

        def unfold_func(name, instance, **kw):
            return instance

        folds = {self.id: 'a=my_crease'}
        creases = {
            "my_crease": {
                "fmt": "invalid",
                "fold": int,
                "unfold": int
            }
        }
        with pytest.raises(OrigamiException):
            self.crafter.learn_pattern(cls, unfold_func, folds, creases)