# Path: bdec/constraints.py
# 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)
# 
# 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)


import unittest
import bdec.data as dt
import bdec.entry as ent
import bdec.expression as expr
import bdec.field as fld
import bdec.sequence as seq
from bdec.constraints import ConstraintError, Equals
        self.assertEqual(0x7a, int(calls[1][1]))
        self.assertEqual(sequence, calls[2][0])

    def test_encode(self):
        embedded = [fld.Field("bob", 8, format=fld.Field.INTEGER), fld.Field("cat", 8, format=fld.Field.INTEGER)]
        sequence = seq.Sequence("blah", embedded)
        struct = {'blah':{"bob" : 0x01, "cat" : 0x7a}}
        query = lambda context, child, i, name: context[name]
        data = reduce(lambda a,b:a+b, sequence.encode(query, struct))
        self.assertEqual("\x01\x7a", data.bytes())

    def test_bad_length(self):
        embedded = [fld.Field("bob", 8, format=fld.Field.INTEGER), fld.Field("cat", 8, format=fld.Field.INTEGER)]
        sequence = seq.Sequence("blah", embedded, length=17)
        self.assertRaises(ent.DecodeLengthError, list, sequence.decode(dt.Data('abc')))
        sequence = seq.Sequence("blah", embedded, length=15)
        self.assertRaises(ent.EntryDataError, list, sequence.decode(dt.Data('abc')))

    def test_range(self):
        children = [fld.Field("bob", 8), fld.Field("cat", 8)]
        sequence = seq.Sequence("blah", children)
        self.assertEqual(16, sequence.range().min)
        self.assertEqual(16, sequence.range().max)

    def test_sequence_expected_value(self):
        a = seq.Sequence('a', [fld.Field('b', 8), fld.Field('c', 8)], value=expr.compile('${b} + ${c}'))
        a.constraints.append(Equals(7))
        list(a.decode(dt.Data('\x03\x04')))
        list(a.decode(dt.Data('\x06\x01')))
        self.assertRaises(ConstraintError, list, a.decode(dt.Data('\x05\x01')))

# Path: bdec/constraints.py
# 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)
# 
# 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)


# Path: bdec/test/testsequence.py
import unittest
import bdec.data as dt
import bdec.entry as ent
import bdec.expression as expr
import bdec.field as fld
import bdec.sequence as seq
from bdec.constraints import ConstraintError, Equals

        self.assertEqual(0x7a, int(calls[1][1]))
        self.assertEqual(sequence, calls[2][0])

    def test_encode(self):
        embedded = [fld.Field("bob", 8, format=fld.Field.INTEGER), fld.Field("cat", 8, format=fld.Field.INTEGER)]
        sequence = seq.Sequence("blah", embedded)
        struct = {'blah':{"bob" : 0x01, "cat" : 0x7a}}
        query = lambda context, child, i, name: context[name]
        data = reduce(lambda a,b:a+b, sequence.encode(query, struct))
        self.assertEqual("\x01\x7a", data.bytes())

    def test_bad_length(self):
        embedded = [fld.Field("bob", 8, format=fld.Field.INTEGER), fld.Field("cat", 8, format=fld.Field.INTEGER)]
        sequence = seq.Sequence("blah", embedded, length=17)
        self.assertRaises(ent.DecodeLengthError, list, sequence.decode(dt.Data('abc')))
        sequence = seq.Sequence("blah", embedded, length=15)
        self.assertRaises(ent.EntryDataError, list, sequence.decode(dt.Data('abc')))

    def test_range(self):
        children = [fld.Field("bob", 8), fld.Field("cat", 8)]
        sequence = seq.Sequence("blah", children)
        self.assertEqual(16, sequence.range().min)
        self.assertEqual(16, sequence.range().max)

    def test_sequence_expected_value(self):
        a = seq.Sequence('a', [fld.Field('b', 8), fld.Field('c', 8)], value=expr.compile('${b} + ${c}'))
        a.constraints.append(Equals(7))
        list(a.decode(dt.Data('\x03\x04')))
        list(a.decode(dt.Data('\x06\x01')))
        self.assertRaises(ConstraintError, list, a.decode(dt.Data('\x05\x01')))

        self.assertRaises(ConstraintError, list, a.decode(dt.Data('\x07\x01')))