# 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/encode/entry.py
# class DataLengthError(bdec.DecodeError):
#     """Encoded data has the wrong length."""
#     def __init__(self, entry, expected, actual):
#         bdec.DecodeError.__init__(self, entry)
#         self.expected = expected
#         self.actual = actual
# 
#     def __str__(self):
#         # We report the error using Constant to get the nicer 'whole byte'
#         # reporting.
#         return "%s expected length %s, got length %s" % (self.entry, self.expected, Constant(self.actual))
# 
# 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


import operator
import unittest
import bdec.entry as ent
import bdec.data as dt
import bdec.field as fld
from bdec.constraints import Equals, ConstraintError
from bdec.encode.entry import DataLengthError
from bdec.expression import ValueResult

    def test_big_endian(self):
        actual = self._get_decode_value("0008", 16, fld.Field.INTEGER, fld.Field.BIG_ENDIAN)
        self.assertEqual(8, actual)

    def test_bad_expected_data(self):
        field = fld.Field("bob", 8, constraints=[Equals(0xf8)])
        data = dt.Data.from_hex("f7")
        self.assertRaises(ConstraintError, lambda: list(field.decode(data)))

    def test_good_expected_data(self):
        field = fld.Field("bob", 8, constraints=[Equals(0xfe)])
        data = dt.Data.from_hex("fe")
        result = list(field.decode(data))
        self.assertEqual(2, len(result))
        self.assertEqual("fe", result[1][3].get_hex())

    def test_encode(self):
        field = fld.Field("bob", 8, format=fld.Field.INTEGER)
        result = field.encode(query, 0x3f)
        self.assertEqual(0x3f, int(result.next()))

    def test_encoded_size_matches_expected_size(self):
        # When we specify a size for a field, what we actually encode should match it.
        text = fld.Field("bob", 48, format=fld.Field.TEXT)
        self.assertEqual("rabbit", text.encode(query, "rabbit").next().bytes())
        self.assertRaises(DataLengthError, list, text.encode(query, "boxfish"))

        binary = fld.Field("bob", 8, format=fld.Field.BINARY)
        self.assertEqual("\x39", binary.encode(query, "00111001").next().bytes())

# 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/encode/entry.py
# class DataLengthError(bdec.DecodeError):
#     """Encoded data has the wrong length."""
#     def __init__(self, entry, expected, actual):
#         bdec.DecodeError.__init__(self, entry)
#         self.expected = expected
#         self.actual = actual
# 
#     def __str__(self):
#         # We report the error using Constant to get the nicer 'whole byte'
#         # reporting.
#         return "%s expected length %s, got length %s" % (self.entry, self.expected, Constant(self.actual))
# 
# 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/test/testfield.py
import operator
import unittest
import bdec.entry as ent
import bdec.data as dt
import bdec.field as fld
from bdec.constraints import Equals, ConstraintError
from bdec.encode.entry import DataLengthError
from bdec.expression import ValueResult


    def test_big_endian(self):
        actual = self._get_decode_value("0008", 16, fld.Field.INTEGER, fld.Field.BIG_ENDIAN)
        self.assertEqual(8, actual)

    def test_bad_expected_data(self):
        field = fld.Field("bob", 8, constraints=[Equals(0xf8)])
        data = dt.Data.from_hex("f7")
        self.assertRaises(ConstraintError, lambda: list(field.decode(data)))

    def test_good_expected_data(self):
        field = fld.Field("bob", 8, constraints=[Equals(0xfe)])
        data = dt.Data.from_hex("fe")
        result = list(field.decode(data))
        self.assertEqual(2, len(result))
        self.assertEqual("fe", result[1][3].get_hex())

    def test_encode(self):
        field = fld.Field("bob", 8, format=fld.Field.INTEGER)
        result = field.encode(query, 0x3f)
        self.assertEqual(0x3f, int(result.next()))

    def test_encoded_size_matches_expected_size(self):
        # When we specify a size for a field, what we actually encode should match it.
        text = fld.Field("bob", 48, format=fld.Field.TEXT)
        self.assertEqual("rabbit", text.encode(query, "rabbit").next().bytes())
        self.assertRaises(DataLengthError, list, text.encode(query, "boxfish"))

        binary = fld.Field("bob", 8, format=fld.Field.BINARY)
        self.assertEqual("\x39", binary.encode(query, "00111001").next().bytes())

        self.assertRaises(DataLengthError, list, binary.encode(query, "1011"))