# Path: bdec/encode/entry.py
# class MissingInstanceError(bdec.DecodeError):
#     """
#     Error raised during encoding when a parent object doesn't have a named child object.
#     """
#     def __init__(self, parent, child):
#         bdec.DecodeError.__init__(self, child)
#         self.parent = parent
#         self.child = child
# 
#     def __str__(self):
#         return "object '%s' doesn't have child object '%s'" % (self.parent, self.child.name)
# 
# Path: bdec/expression.py
# class ValueResult(ReferenceExpression):
#     """
#     Object returning the result of a entry when cast to an integer.
#     """
#     def param_name(self):
#         return self.name
# 
#     def __repr__(self):
#         return '${%s}' % self.name
# 
# Path: bdec/constraints.py
# class Equals(Constraint):
#     type = '!='
# 
#     def check(self, entry, value, context):
#         expected = self.limit.evaluate(context)
#         if isinstance(expected, int):
#             if int(value) !=  expected:
#                 raise ConstraintError(entry, int(value), '==', expected)
#         elif isinstance(expected, Data):
#             # We aren't checking the length here, only the value (for example,
#             # the expected value for a variable length binary field will have
#             # a different length than the actual). Only compare the bits that
#             # are valid.
#             length_diff = len(value) - len(expected)
#             if length_diff > 0:
#                 # The expected value is shorter than the actual, so grow it.
#                 expected = Data('\x00' * (length_diff / 8 + 1), 0, length_diff) + expected
#             elif length_diff < 0:
#                 # The expected value is longer than the actual, so shrink it.
#                 shorter = expected.copy()
#                 leading = shorter.pop(-length_diff)
#                 if not int(leading):
#                     # We can safely pop the leading bits.
#                     expected = shorter
#             if value !=  expected:
#                 raise ConstraintError(entry, value, '==', expected)
#         else:
#             if value !=  expected:
#                 raise ConstraintError(entry, value, '==', expected)
# 
#     def range(self):
#         limit = _limit(self.limit)
#         return Range(limit, limit)
# 
# class ConstraintError(DecodeError):
#     def __init__(self, entry, actual, comparison, limit):
#         DecodeError.__init__(self, entry)
#         self._comparision = comparison
#         self._expected = limit
#         self._actual = actual
# 
#     def __str__(self):
#         return 'Expected ${%s} %s %s; got %s' % (self.entry.name,
#                 self._comparision, self._expected, self._actual)


import operator
import unittest
import bdec.entry as ent
import bdec.choice as chc
import bdec.data as dt
import bdec.field as fld
import bdec.sequence as seq
import bdec.expression as expr
from bdec.encode.entry import MissingInstanceError
from bdec.expression import ValueResult
from bdec.constraints import Equals, ConstraintError
        self.assertEqual("cat", results[4][1].name)
        
    def test_data_of_reused_field(self):
        # Test the results of the data of a field that is referenced
        # multiple times in a choice
        cat = fld.Field("cat", 8)
        choice = chc.Choice("blah", [seq.Sequence("chicken", [cat, cat])])
        data = dt.Data.from_hex("0102")

        decoded = []
        for is_starting, name, entry, entry_data, value in choice.decode(data):
            if not is_starting and len(entry_data) > 0:
                decoded.append(entry_data)

        self.assertEqual(2, len(decoded))
        self.assertEqual(1, int(decoded[0]))
        self.assertEqual(2, int(decoded[1]))

    def test_encode(self):
        # Test encoding of a number that is encoded in different sizes (depending on the size of the data)
        byte_len = seq.Sequence("bob", [
            fld.Field("id:", 1, constraints=[Equals(dt.Data("\x00", 7, 8))]),
            fld.Field("dog", 8, format=fld.Field.INTEGER)])
        word_len = seq.Sequence("bob", [
            fld.Field("id:", 1, constraints=[Equals(dt.Data("\x01", 7, 8))]),
            fld.Field("dog", 16, format=fld.Field.INTEGER)])
        choice = chc.Choice("blah", [byte_len, word_len])

        # First try encoding a number that will only fit in the 16 bit storage
        struct = {"bob" : {"dog" : 10023}}

# Path: bdec/encode/entry.py
# class MissingInstanceError(bdec.DecodeError):
#     """
#     Error raised during encoding when a parent object doesn't have a named child object.
#     """
#     def __init__(self, parent, child):
#         bdec.DecodeError.__init__(self, child)
#         self.parent = parent
#         self.child = child
# 
#     def __str__(self):
#         return "object '%s' doesn't have child object '%s'" % (self.parent, self.child.name)
# 
# Path: bdec/expression.py
# class ValueResult(ReferenceExpression):
#     """
#     Object returning the result of a entry when cast to an integer.
#     """
#     def param_name(self):
#         return self.name
# 
#     def __repr__(self):
#         return '${%s}' % self.name
# 
# Path: bdec/constraints.py
# class Equals(Constraint):
#     type = '!='
# 
#     def check(self, entry, value, context):
#         expected = self.limit.evaluate(context)
#         if isinstance(expected, int):
#             if int(value) !=  expected:
#                 raise ConstraintError(entry, int(value), '==', expected)
#         elif isinstance(expected, Data):
#             # We aren't checking the length here, only the value (for example,
#             # the expected value for a variable length binary field will have
#             # a different length than the actual). Only compare the bits that
#             # are valid.
#             length_diff = len(value) - len(expected)
#             if length_diff > 0:
#                 # The expected value is shorter than the actual, so grow it.
#                 expected = Data('\x00' * (length_diff / 8 + 1), 0, length_diff) + expected
#             elif length_diff < 0:
#                 # The expected value is longer than the actual, so shrink it.
#                 shorter = expected.copy()
#                 leading = shorter.pop(-length_diff)
#                 if not int(leading):
#                     # We can safely pop the leading bits.
#                     expected = shorter
#             if value !=  expected:
#                 raise ConstraintError(entry, value, '==', expected)
#         else:
#             if value !=  expected:
#                 raise ConstraintError(entry, value, '==', expected)
# 
#     def range(self):
#         limit = _limit(self.limit)
#         return Range(limit, limit)
# 
# class ConstraintError(DecodeError):
#     def __init__(self, entry, actual, comparison, limit):
#         DecodeError.__init__(self, entry)
#         self._comparision = comparison
#         self._expected = limit
#         self._actual = actual
# 
#     def __str__(self):
#         return 'Expected ${%s} %s %s; got %s' % (self.entry.name,
#                 self._comparision, self._expected, self._actual)


# Path: bdec/test/testchoice.py
import operator
import unittest
import bdec.entry as ent
import bdec.choice as chc
import bdec.data as dt
import bdec.field as fld
import bdec.sequence as seq
import bdec.expression as expr
from bdec.encode.entry import MissingInstanceError
from bdec.expression import ValueResult
from bdec.constraints import Equals, ConstraintError

        self.assertEqual("cat", results[4][1].name)
        
    def test_data_of_reused_field(self):
        # Test the results of the data of a field that is referenced
        # multiple times in a choice
        cat = fld.Field("cat", 8)
        choice = chc.Choice("blah", [seq.Sequence("chicken", [cat, cat])])
        data = dt.Data.from_hex("0102")

        decoded = []
        for is_starting, name, entry, entry_data, value in choice.decode(data):
            if not is_starting and len(entry_data) > 0:
                decoded.append(entry_data)

        self.assertEqual(2, len(decoded))
        self.assertEqual(1, int(decoded[0]))
        self.assertEqual(2, int(decoded[1]))

    def test_encode(self):
        # Test encoding of a number that is encoded in different sizes (depending on the size of the data)
        byte_len = seq.Sequence("bob", [
            fld.Field("id:", 1, constraints=[Equals(dt.Data("\x00", 7, 8))]),
            fld.Field("dog", 8, format=fld.Field.INTEGER)])
        word_len = seq.Sequence("bob", [
            fld.Field("id:", 1, constraints=[Equals(dt.Data("\x01", 7, 8))]),
            fld.Field("dog", 16, format=fld.Field.INTEGER)])
        choice = chc.Choice("blah", [byte_len, word_len])

        # First try encoding a number that will only fit in the 16 bit storage
        struct = {"bob" : {"dog" : 10023}}

        data = reduce(lambda a,b:a+b, choice.encode(query, struct))