def testRepr(self):
        builder = MessageBuilder()
        OUTPUTS = builder.build_message_class("OUTPUTS",
                                              register_defs["OUTPUTS"])
        outputs = OUTPUTS.from_data("b11100000000000000000000000000000")

        self.assertEqual("<OUTPUTS: xe0000000>", repr(outputs))
class TestFieldValueIsValid(unittest.TestCase):
    def setUp(self):
        self.builder = MessageBuilder(definitions=msg_fmts)

    def testValidChars_Hex(self):
        self.assertEqual("".join(Field.get_valid_chars(Field.Format.Hex)), "0123456789abcdefABCDEF")

    def testValidChars_Dec(self):
        self.assertEqual("".join(Field.get_valid_chars(Field.Format.Dec)), "0123456789")

    def testValidChars_Oct(self):
        self.assertEqual("".join(Field.get_valid_chars(Field.Format.Oct)), "01234567")

    def testValidChars_Bin(self):
        self.assertEqual("".join(Field.get_valid_chars(Field.Format.Bin)), "01")

    def testNoFormatSpecifier(self):
        msg1 = self.builder.GET_ADDR(ptr="x00000054", addr="b10001101001")
        self.assertEqual(msg1.ptr.value_is_valid("00000054"), False)

    def testInvalidType(self):
        msg1 = self.builder.GET_ADDR(ptr="x00000054", addr="b10001101001")
        self.assertEqual(msg1.ptr.value_is_valid(False), False)

    def testInvalidValue(self):
        msg1 = self.builder.GET_ADDR(ptr="x00000054", addr="b10001101001")
        self.assertEqual(msg1.ptr.value_is_valid("xfjskjfjfj"), False)

    def testBlankValue(self):
        msg1 = self.builder.GET_ADDR(ptr="x00000054", addr="b10001101001")
        self.assertEqual(msg1.ptr.value_is_valid(""), False)
 def testConstructionFromData_Normal(self):
     builder = MessageBuilder()
     OUTPUTS = builder.build_message_class("OUTPUTS",
                                           register_defs["OUTPUTS"])
     outputs = OUTPUTS.from_data("b11100000000000000000000000000000")
     self.assertTrue(outputs.reset1 == "b1")
     self.assertTrue(outputs.reset2 == "b1")
     self.assertTrue(outputs.cautions == "x80")
     self.assertTrue(outputs.unused == "x0")
 def testMessageFieldNames(self):
     builder = MessageBuilder()
     OUTPUTS = builder.build_message_class("OUTPUTS",
                                           register_defs["OUTPUTS"])
     outputs = OUTPUTS.from_data("b11100000000000000000000000000000")
     self.assertEqual(outputs.reset1.name, "reset1")
     self.assertEqual(outputs.reset2.name, "reset2")
     self.assertEqual(outputs.cautions.name, "cautions")
     self.assertEqual(outputs.unused.name, "unused")
Ejemplo n.º 5
0
 def testMessageObjectLength(self):
     builder = MessageBuilder()
     OUTPUTS = builder.build_message_class("OUTPUTS", register_defs["OUTPUTS"])
     outputs = OUTPUTS(reset1="b1", reset2="b0", cautions="x00")
     self.assertTrue(len(outputs.reset1) == 1)
     self.assertTrue(len(outputs.reset2) == 1)
     self.assertTrue(len(outputs.cautions) == 8)
     self.assertTrue(len(outputs.unused) == 22)
     self.assertTrue(OUTPUTS.bit_length == 32)
Ejemplo n.º 6
0
 def setUp(self):
     builder = MessageBuilder()
     OUTPUTS = builder.build_message_class("OUTPUTS",
                                           register_defs["OUTPUTS"])
     INPUTS = builder.build_message_class("INPUTS", register_defs["INPUTS"])
     self.outputs_1 = OUTPUTS.from_data("b11100000000000000000000000000000")
     self.outputs_1_copy = OUTPUTS.from_data(
         "b11100000000000000000000000000000")
     self.outputs_2 = OUTPUTS.from_data("b11101000000000000000000000000000")
     self.inputs_1 = INPUTS.from_data("b11100000000000000000000000000000")
Ejemplo n.º 7
0
class TestMessageComparison(unittest.TestCase):
    def setUp(self):
        builder = MessageBuilder()
        OUTPUTS = builder.build_message_class("OUTPUTS",
                                              register_defs["OUTPUTS"])
        INPUTS = builder.build_message_class("INPUTS", register_defs["INPUTS"])
        self.outputs_1 = OUTPUTS.from_data("b11100000000000000000000000000000")
        self.outputs_1_copy = OUTPUTS.from_data(
            "b11100000000000000000000000000000")
        self.outputs_2 = OUTPUTS.from_data("b11101000000000000000000000000000")
        self.inputs_1 = INPUTS.from_data("b11100000000000000000000000000000")

    def testSelfEqual(self):
        self.assertTrue(self.outputs_1 == self.outputs_1)
        self.assertTrue(self.outputs_1 == self.outputs_1.render())

    def testCopyOfSelfEqual(self):
        self.assertTrue(self.outputs_1 == self.outputs_1_copy)
        self.assertTrue(self.outputs_1 == self.outputs_1_copy.render())

    def testDifferentStructureSameDataEqual(self):
        self.builder = MessageBuilder()
        self.builder.load_definitions(msg_fmts)
        self.builder.load_definitions(register_defs)
        self.builder.load_definitions(caution_codes)

        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST_V2
        OUTPUTS = self.builder.OUTPUTS
        RANDOM_MEANING = self.builder.RANDOM_MEANING
        CAUTION_CODES = self.builder.CAUTION_CODES

        msg1 = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        msg1.or_field.context = RANDOM_MEANING
        msg1.data.context = OUTPUTS
        msg1.data.cautions.context = CAUTION_CODES

        msg2 = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        msg1.data.context = OUTPUTS

        self.assertEqual(msg1, msg2)
        self.assertEqual(msg1, msg2.render())

    def testDifferentMessageSameDataNotEqual(self):
        self.assertNotEqual(self.outputs_1, self.inputs_1)
        self.assertEqual(self.outputs_1, self.inputs_1.render())

    def testNotEqual(self):
        self.assertTrue(self.outputs_1 != self.outputs_2)
        self.assertTrue(self.outputs_1 != self.outputs_2.render())
Ejemplo n.º 8
0
    def setUp(self):
        self.builder = MessageBuilder()
        self.builder.load_definitions(msg_fmts)
        self.builder.load_definitions(register_defs)
        self.builder.load_definitions(caution_codes)

        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST_V2
        OUTPUTS = self.builder.OUTPUTS
        RANDOM_MEANING = self.builder.RANDOM_MEANING
        CAUTION_CODES = self.builder.CAUTION_CODES

        self.msg = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        self.msg.or_field.context = RANDOM_MEANING
        self.msg.data.context = OUTPUTS
        self.msg.data.cautions.context = CAUTION_CODES
    def testAllMessageProductionMethods(self):
        builder = MessageBuilder(msg_fmts)

        data = "x001600089999999900000000"
        wrt_req_1 = builder.build_message(data)
        wrt_req_2 = builder.WRITE_REGISTER_REQUEST.from_data(data)
        wrt_req_3 = builder.WRITE_REGISTER_REQUEST(addr="x99999999",
                                                   data="x00000000")

        self.assertTrue(isinstance(wrt_req_1, builder.WRITE_REGISTER_REQUEST))
        self.assertTrue(isinstance(wrt_req_2, builder.WRITE_REGISTER_REQUEST))
        self.assertTrue(isinstance(wrt_req_3, builder.WRITE_REGISTER_REQUEST))

        self.assertEqual(wrt_req_1, wrt_req_2)
        self.assertEqual(wrt_req_2, wrt_req_3)
        self.assertEqual(wrt_req_3, wrt_req_1)
Ejemplo n.º 10
0
    def testAutoUpdateFields(self):
        msg1 = self.builder.GET_ADDR(ptr="x00000054", addr="b10001101001")
        self.assertEqual(msg1.length, "x0014")
        self.assertEqual(msg1.crc, "x0000")
        msg1.ptr = "x54000000"
        self.assertEqual(msg1.crc, "x5400")

        with self.assertRaises(CircularDependencyException):
            builder = MessageBuilder(circular_dep)
Ejemplo n.º 11
0
    def testDifferentStructureSameDataEqual(self):
        self.builder = MessageBuilder()
        self.builder.load_definitions(msg_fmts)
        self.builder.load_definitions(register_defs)
        self.builder.load_definitions(caution_codes)

        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST_V2
        OUTPUTS = self.builder.OUTPUTS
        RANDOM_MEANING = self.builder.RANDOM_MEANING
        CAUTION_CODES = self.builder.CAUTION_CODES

        msg1 = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        msg1.or_field.context = RANDOM_MEANING
        msg1.data.context = OUTPUTS
        msg1.data.cautions.context = CAUTION_CODES

        msg2 = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        msg1.data.context = OUTPUTS

        self.assertEqual(msg1, msg2)
        self.assertEqual(msg1, msg2.render())
 def testFieldEquals(self):
     builder = MessageBuilder(definitions=msg_fmts)
     msg1 = builder.GET_ADDR(ptr="x00000054", addr="b10001101001")
     self.assertTrue(msg1.id != "x4")
     self.assertTrue(msg1.id == "x14")
     self.assertTrue(msg1.id == "x014")
     self.assertTrue(msg1.id == "x0014")
     self.assertTrue(msg1.id == "x00014")
     self.assertTrue(msg1.id != "b0100")
     self.assertTrue(msg1.id == "b10100")
     self.assertTrue(msg1.id == "b010100")
     self.assertTrue(msg1.id != "o4")
     self.assertTrue(msg1.id == "o24")
     self.assertTrue(msg1.id == "o024")
     self.assertTrue(msg1.id == "o0024")
     self.assertTrue(msg1.id == "o00024")
     self.assertTrue(msg1.id != "d0")
     self.assertTrue(msg1.id == "d20")
     self.assertTrue(msg1.id == "d020")
     self.assertTrue(msg1.id == "d0020")
     self.assertTrue(msg1.id == "d00020")
Ejemplo n.º 13
0
class TestMessageBuilder(unittest.TestCase):
    def setUp(self):
        self.builder = MessageBuilder(msg_fmts)

    def testInstantiaion(self):
        pass  # instantiation is covered in the setup. Just want a simple pass here.

    def testDefinitionLoading(self):
        GET_ADDR = self.builder.GET_ADDR
        self.assertTrue(isinstance(GET_ADDR, type))

    def testInvalidDefinition(self):
        with self.assertRaises(InvalidFieldException):
            self.builder.build_message_class("INVALID_DEF",
                                             invalid_def["INVALID_DEF"])

    def testMessageProduction_Normal(self):
        wrt_req_1 = self.builder.build_message("x001600089999999900000000")

    def testMessageProduction_MultipleMatches(self):
        with self.assertRaises(MultipleMatchingMessageDefinitionsException):
            wrt_req_1 = self.builder.build_message("x00150004FFFFFFFF")
Ejemplo n.º 14
0
    def testNestedFields(self):
        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST
        builder = MessageBuilder(register_defs)
        OUTPUTS = builder.build_message_class("OUTPUTS",
                                              register_defs["OUTPUTS"])
        INPUTS = builder.build_message_class("INPUTS", register_defs["INPUTS"])

        def verify_msg_outputs(msg):
            self.assertEqual(msg.data.context, OUTPUTS)
            self.assertEqual(type(msg.data), OUTPUTS)
            self.assertEqual(msg.data.reset1, "b1")
            self.assertEqual(msg.data.reset2, "b0")
            self.assertEqual(msg.data.cautions, "x00")
            self.assertEqual(msg.data.unused, "x0")

        def verify_msg_inputs(msg):
            self.assertEqual(msg.data.context, INPUTS)
            self.assertEqual(type(msg.data), INPUTS)
            self.assertEqual(msg.data.service_req, "b1")
            self.assertEqual(msg.data.voltage_ready, "b0")
            self.assertEqual(msg.data.exit_code, "x0000")
            self.assertEqual(msg.data.last_command_mid, "x0")
            self.assertEqual(msg.data.unused, "x00")

        send_msg_1 = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        send_msg_1.data.context = OUTPUTS
        verify_msg_outputs(send_msg_1)
        send_msg_1.data.context = INPUTS
        verify_msg_inputs(send_msg_1)

        send_msg_2 = WRITE_REGISTER_REQUEST(addr="x60000001",
                                            data=OUTPUTS(reset1="b1",
                                                         reset2="b0",
                                                         cautions="x00"))
        verify_msg_outputs(send_msg_2)
        send_msg_2.data.context = INPUTS
        verify_msg_inputs(send_msg_2)
 def setUp(self):
     self.builder = MessageBuilder(definitions=msg_fmts)
Ejemplo n.º 16
0
 def setUp(self):
     self.builder = MessageBuilder(msg_fmts)
    def testInvalidMessageProduction(self):
        builder = MessageBuilder(msg_fmts)

        with self.assertRaises(InvalidDataFormatException):
            wrt_req_1 = builder.build_message("x0014000899999999000000001")
Ejemplo n.º 18
0
class TestFieldTypes(unittest.TestCase):
    def setUp(self):
        self.builder = MessageBuilder(definitions=msg_fmts)

    def testConstantFields(self):
        msg1 = self.builder.GET_ADDR(ptr="x00000054", addr="b10001101001")
        self.assertEqual(msg1.id, "x0014")
        self.assertEqual(msg1.pad, "b000")
        with self.assertRaises(AttributeError):
            msg1.id = "b1"

    def testWritableFields(self):
        msg1 = self.builder.GET_ADDR(ptr="x00000054", addr="b10001101001")
        with self.assertRaises(InvalidFieldDataException):
            msg1.ptr = "x1000000000000000000000000000000000000000"
        with self.assertRaises(InvalidFieldDataException):
            msg1.ptr.value = "x1000000000000000000000000000000000000000"

    def testAutoUpdateFields(self):
        msg1 = self.builder.GET_ADDR(ptr="x00000054", addr="b10001101001")
        self.assertEqual(msg1.length, "x0014")
        self.assertEqual(msg1.crc, "x0000")
        msg1.ptr = "x54000000"
        self.assertEqual(msg1.crc, "x5400")

        with self.assertRaises(CircularDependencyException):
            builder = MessageBuilder(circular_dep)

    def testNestedFields(self):
        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST
        builder = MessageBuilder(register_defs)
        OUTPUTS = builder.build_message_class("OUTPUTS",
                                              register_defs["OUTPUTS"])
        INPUTS = builder.build_message_class("INPUTS", register_defs["INPUTS"])

        def verify_msg_outputs(msg):
            self.assertEqual(msg.data.context, OUTPUTS)
            self.assertEqual(type(msg.data), OUTPUTS)
            self.assertEqual(msg.data.reset1, "b1")
            self.assertEqual(msg.data.reset2, "b0")
            self.assertEqual(msg.data.cautions, "x00")
            self.assertEqual(msg.data.unused, "x0")

        def verify_msg_inputs(msg):
            self.assertEqual(msg.data.context, INPUTS)
            self.assertEqual(type(msg.data), INPUTS)
            self.assertEqual(msg.data.service_req, "b1")
            self.assertEqual(msg.data.voltage_ready, "b0")
            self.assertEqual(msg.data.exit_code, "x0000")
            self.assertEqual(msg.data.last_command_mid, "x0")
            self.assertEqual(msg.data.unused, "x00")

        send_msg_1 = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        send_msg_1.data.context = OUTPUTS
        verify_msg_outputs(send_msg_1)
        send_msg_1.data.context = INPUTS
        verify_msg_inputs(send_msg_1)

        send_msg_2 = WRITE_REGISTER_REQUEST(addr="x60000001",
                                            data=OUTPUTS(reset1="b1",
                                                         reset2="b0",
                                                         cautions="x00"))
        verify_msg_outputs(send_msg_2)
        send_msg_2.data.context = INPUTS
        verify_msg_inputs(send_msg_2)
 def testConstructionFromDefinition_ReadOnlyField(self):
     builder = MessageBuilder()
     OUTPUTS = builder.build_message_class("OUTPUTS",
                                           register_defs["OUTPUTS"])
     with self.assertRaises(InvalidFieldException):
         OUTPUTS(reset1="b1", reset2="b0", cautions="x00", unused="x000")
 def testConstructionFromDefinition_MissingArg(self):
     builder = MessageBuilder()
     OUTPUTS = builder.build_message_class("OUTPUTS",
                                           register_defs["OUTPUTS"])
     with self.assertRaises(MissingFieldDataException):
         OUTPUTS(reset1="b1")
 def testConstructionFromData_Invalid(self):
     builder = MessageBuilder()
     OUTPUTS = builder.build_message_class("OUTPUTS",
                                           register_defs["OUTPUTS"])
     with self.assertRaises(InvalidDataFormatException):
         OUTPUTS.from_data("b11100000000000000000000000000000111")
Ejemplo n.º 22
0
    def testFormatFieldRepr(self):
        builder = MessageBuilder()
        OUTPUTS = builder.build_message_class("OUTPUTS", register_defs["OUTPUTS"])

        self.assertTrue("Byte" in repr(OUTPUTS.format["cautions"]))
Ejemplo n.º 23
0
 def setUp(self):
     self.builder = MessageBuilder()
     self.builder.load_definitions(msg_fmts)
     self.builder.load_definitions(register_defs)
     self.builder.load_definitions(caution_codes)
Ejemplo n.º 24
0
class TestNestedMessages(unittest.TestCase):
    def setUp(self):
        self.builder = MessageBuilder()
        self.builder.load_definitions(msg_fmts)
        self.builder.load_definitions(register_defs)
        self.builder.load_definitions(caution_codes)

    def testMultipleLevelContexts(self):
        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST
        OUTPUTS = self.builder.OUTPUTS
        CAUTION_CODES = self.builder.CAUTION_CODES

        msg = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        msg.data.context = OUTPUTS
        msg.data.cautions.context = CAUTION_CODES

        self.assertEqual(msg.context, WRITE_REGISTER_REQUEST)
        self.assertEqual(type(msg), WRITE_REGISTER_REQUEST)
        self.assertEqual(msg.data.context, OUTPUTS)
        self.assertEqual(type(msg.data), OUTPUTS)
        self.assertEqual(msg.data.cautions.context, CAUTION_CODES)
        self.assertEqual(type(msg.data.cautions), CAUTION_CODES)

    def testMultipleLevelValues(self):
        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST
        OUTPUTS = self.builder.OUTPUTS
        CAUTION_CODES = self.builder.CAUTION_CODES

        msg = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        msg.data.context = OUTPUTS
        msg.data.cautions.context = CAUTION_CODES

        self.assertEqual(msg.mid, "x0016")
        self.assertEqual(msg.length, "x0008")
        self.assertEqual(msg.addr, "x60000001")
        self.assertEqual(msg.data, "x80000000")
        self.assertEqual(msg.data.reset1, "b1")
        self.assertEqual(msg.data.reset2, "b0")
        self.assertEqual(msg.data.cautions, "x00")
        self.assertEqual(msg.data.cautions.addr, "b0000")
        self.assertEqual(msg.data.cautions.access, "b0000")
        self.assertEqual(msg.data.unused, "x0000000")

    def testMultipleLevelValueUpdates(self):
        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST_V2
        OUTPUTS = self.builder.OUTPUTS
        RANDOM_MEANING = self.builder.RANDOM_MEANING
        CAUTION_CODES = self.builder.CAUTION_CODES

        msg = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        msg.or_field.context = RANDOM_MEANING
        msg.data.context = OUTPUTS
        msg.data.cautions.context = CAUTION_CODES

        self.assertEqual(msg.data, "x80000000")
        self.assertEqual(msg.or_field, "xE0000001")
        self.assertEqual(msg.or_field.byte_1, "xE0")
        self.assertEqual(msg.or_field.byte_2, "x00")
        self.assertEqual(msg.or_field.byte_3, "x00")
        self.assertEqual(msg.or_field.byte_4, "x01")
        msg.data.cautions.addr = "x1"
        msg.data.cautions.access = "xF"
        self.assertEqual(msg.data, "x87C00000")
        self.assertEqual(msg.or_field, "xE7C00001")
        self.assertEqual(msg.or_field.byte_1, "xE7")
        self.assertEqual(msg.or_field.byte_2, "xC0")
        self.assertEqual(msg.or_field.byte_3, "x00")
        self.assertEqual(msg.or_field.byte_4, "x01")

    def testSetFieldAsMessage(self):
        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST_V2

        msg = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        self.assertEqual(msg.data, "x80000000")
        msg.data = self.builder.OUTPUTS.from_data("x8C000000")
        self.assertEqual(msg.data.reset1, "b1")
        self.assertEqual(msg.data.reset2, "b0")
        self.assertEqual(msg.data.cautions, "x30")
        self.assertEqual(msg.data.unused, "x00000")
        self.assertEqual(msg.data, "x8C000000")

    def testSetContextAsNone(self):
        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST_V2

        msg = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        msg.data.context = self.builder.OUTPUTS
        self.assertTrue("data.reset1" in msg.get_field_name_mapping(
            expand_nested=True))
        msg.data.context = None
        self.assertTrue("data.reset1" not in msg.get_field_name_mapping(
            expand_nested=True))

    def testSetIncompatibleContext(self):
        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST_V2

        msg = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000001")
        with self.assertRaises(ContextDataMismatchException):
            msg.data.context = self.builder.OUTPUTS
Ejemplo n.º 25
0
 def testMessageClassLength(self):
     builder = MessageBuilder()
     OUTPUTS = builder.build_message_class("OUTPUTS", register_defs["OUTPUTS"])
     self.assertTrue(len(OUTPUTS) == 32)
Ejemplo n.º 26
0
class TestMessageTables(unittest.TestCase):
    def setUp(self):
        self.builder = MessageBuilder()
        self.builder.load_definitions(msg_fmts)
        self.builder.load_definitions(register_defs)
        self.builder.load_definitions(caution_codes)

        WRITE_REGISTER_REQUEST = self.builder.WRITE_REGISTER_REQUEST_V2
        OUTPUTS = self.builder.OUTPUTS
        RANDOM_MEANING = self.builder.RANDOM_MEANING
        CAUTION_CODES = self.builder.CAUTION_CODES

        self.msg = WRITE_REGISTER_REQUEST(addr="x60000001", data="x80000000")
        self.msg.or_field.context = RANDOM_MEANING
        self.msg.data.context = OUTPUTS
        self.msg.data.cautions.context = CAUTION_CODES

    def testExpandedTableRendering(self):
        nested_all_fmts = self.msg.render_table(formats=[
            Field.Format.Hex, Field.Format.Dec, Field.Format.Oct,
            Field.Format.Bin
        ],
                                                expand_nested=True)
        self.assertEqual(
            remove_whitespace(nested_all_fmts),
            remove_whitespace("""
                    +WRITE_REGISTER_REQUEST_V2---------+-------------+--------------+-----------------------------------+
                    | Field Name           | Hex       | Dec         | Oct          | Bin                               |
                    +----------------------+-----------+-------------+--------------+-----------------------------------+
                    | mid                  | x0016     | d00022      | o000026      | b0000000000010110                 |
                    | or_field.byte_1      | xe0       | d224        | o340         | b11100000                         |
                    | or_field.byte_2      | x00       | d000        | o000         | b00000000                         |
                    | or_field.byte_3      | x00       | d000        | o000         | b00000000                         |
                    | or_field.byte_4      | x01       | d001        | o001         | b00000001                         |
                    | addr                 | x60000001 | d1610612737 | o14000000001 | b01100000000000000000000000000001 |
                    | data.reset1          | x1        | d1          | o1           | b1                                |
                    | data.reset2          | x0        | d0          | o0           | b0                                |
                    | data.cautions.addr   | x0        | d00         | o00          | b0000                             |
                    | data.cautions.access | x0        | d00         | o00          | b0000                             |
                    | data.unused          | x000000   | d0000000    | o00000000    | b0000000000000000000000           |
                    +----------------------+-----------+-------------+--------------+-----------------------------------+
                """),
        )

    def testCollapsedTableRendering(self):
        not_nested_default_fmt = self.msg.render_table(formats=None,
                                                       expand_nested=False)
        self.assertEqual(
            remove_whitespace(not_nested_default_fmt),
            remove_whitespace("""
                    +------------+-----------+
                    | Field Name | Value     |
                    +------------+-----------+
                    | mid        | x0016     |
                    | or_field   | xe0000001 |
                    | addr       | x60000001 |
                    | data       | x80000000 |
                    +------------+-----------+
                """),
        )

    def testCollapsedTableComparisonEqual(self):
        comp = self.msg.compare_tables(self.msg, expand_nested=False)[1]
        self.assertEqual(
            remove_whitespace(comp),
            remove_whitespace("""
                    +------------+-----------+      +------------+-----------+
                    | Field Name | Value     |      | Field Name | Value     |
                    +------------+-----------+      +------------+-----------+
                    | mid        | x0016     |  ==  | mid        | x0016     |
                    | or_field   | xe0000001 |  ==  | or_field   | xe0000001 |
                    | addr       | x60000001 |  ==  | addr       | x60000001 |
                    | data       | x80000000 |  ==  | data       | x80000000 |
                    +------------+-----------+      +------------+-----------+
                """),
        )

    def testCollapsedTableComparisonNotEqual(self):
        msg2 = copy.deepcopy(self.msg)
        msg2.data = "x83000000"
        comp = self.msg.compare_tables(msg2, expand_nested=False)[1]
        self.assertEqual(
            remove_whitespace(comp),
            remove_whitespace("""
                    +------------+-----------+      +------------+-----------+
                    | Field Name | Value     |      | Field Name | Value     |
                    +------------+-----------+      +------------+-----------+
                    | mid        | x0016     |  ==  | mid        | x0016     |
                    | or_field   | xe0000001 |  !=  | or_field   | xe3000001 |
                    | addr       | x60000001 |  ==  | addr       | x60000001 |
                    | data       | x80000000 |  !=  | data       | x83000000 |
                    +------------+-----------+      +------------+-----------+
                """),
        )

    def testExpandedTableComparisonEqual(self):
        comp = self.msg.compare_tables(self.msg,
                                       formats=None,
                                       expand_nested=True)[1]
        self.assertEqual(
            remove_whitespace(comp),
            remove_whitespace("""
                    +WRITE_REGISTER_REQUEST_V2---------+      +WRITE_REGISTER_REQUEST_V2---------+
                    | Field Name           | Value     |      | Field Name           | Value     |
                    +----------------------+-----------+      +----------------------+-----------+
                    | mid                  | x0016     |  ==  | mid                  | x0016     |
                    | or_field.byte_1      | xe0       |  ==  | or_field.byte_1      | xe0       |
                    | or_field.byte_2      | x00       |  ==  | or_field.byte_2      | x00       |
                    | or_field.byte_3      | x00       |  ==  | or_field.byte_3      | x00       |
                    | or_field.byte_4      | x01       |  ==  | or_field.byte_4      | x01       |
                    | addr                 | x60000001 |  ==  | addr                 | x60000001 |
                    | data.reset1          | b1        |  ==  | data.reset1          | b1        |
                    | data.reset2          | b0        |  ==  | data.reset2          | b0        |
                    | data.cautions.addr   | x0        |  ==  | data.cautions.addr   | x0        |
                    | data.cautions.access | x0        |  ==  | data.cautions.access | x0        |
                    | data.unused          | x000000   |  ==  | data.unused          | x000000   |
                    +----------------------+-----------+      +----------------------+-----------+
                """),
        )

    def testExpandedTableComparisonNotEqual(self):
        msg2 = copy.deepcopy(self.msg)
        msg2.data = "x83000000"
        comp = self.msg.compare_tables(msg2, formats=None,
                                       expand_nested=True)[1]
        self.assertEqual(
            remove_whitespace(comp),
            remove_whitespace("""
                    +WRITE_REGISTER_REQUEST_V2---------+      +WRITE_REGISTER_REQUEST_V2---------+
                    | Field Name           | Value     |      | Field Name           | Value     |
                    +----------------------+-----------+      +----------------------+-----------+
                    | mid                  | x0016     |  ==  | mid                  | x0016     |
                    | or_field.byte_1      | xe0       |  !=  | or_field.byte_1      | xe3       |
                    | or_field.byte_2      | x00       |  ==  | or_field.byte_2      | x00       |
                    | or_field.byte_3      | x00       |  ==  | or_field.byte_3      | x00       |
                    | or_field.byte_4      | x01       |  ==  | or_field.byte_4      | x01       |
                    | addr                 | x60000001 |  ==  | addr                 | x60000001 |
                    | data.reset1          | b1        |  ==  | data.reset1          | b1        |
                    | data.reset2          | b0        |  ==  | data.reset2          | b0        |
                    | data.cautions.addr   | x0        |  ==  | data.cautions.addr   | x0        |
                    | data.cautions.access | x0        |  !=  | data.cautions.access | xc        |
                    | data.unused          | x000000   |  ==  | data.unused          | x000000   |
                    +----------------------+-----------+      +----------------------+-----------+
                """),
        )

    def testExpandedTableComparisonConflictingContexts(self):
        msg2 = self.builder.WRITE_REGISTER_REQUEST(addr="x60000001",
                                                   data="x80000000")
        msg2.data.context = self.builder.OUTPUTS

        with self.assertRaises(ConflictingContextsException):
            self.msg.compare_tables(msg2, formats=None, expand_nested=True)

        msg3 = self.builder.WRITE_REGISTER_REQUEST_V2(addr="x60000001",
                                                      data="x80000000")
        msg3.data.context = self.builder.OUTPUTS

        with self.assertRaises(ConflictingContextsException):
            self.msg.compare_tables(msg3, formats=None, expand_nested=True)

    def testCollapsedTableComparisonConflictingContexts(self):
        msg2 = self.builder.WRITE_REGISTER_REQUEST(addr="x60000001",
                                                   data="x80000000")
        msg2.data.context = self.builder.OUTPUTS

        with self.assertRaises(ConflictingContextsException):
            self.msg.compare_tables(msg2, formats=None, expand_nested=False)

        msg3 = self.builder.WRITE_REGISTER_REQUEST_V2(addr="x60000001",
                                                      data="x80000000")
        msg3.data.context = self.builder.OUTPUTS

        comp = self.msg.compare_tables(msg3, formats=None,
                                       expand_nested=False)[1]
        self.assertEqual(
            remove_whitespace(comp),
            remove_whitespace("""
                    +------------+-----------+      +------------+-----------+
                    | Field Name | Value     |      | Field Name | Value     |
                    +------------+-----------+      +------------+-----------+
                    | mid        | x0016     |  ==  | mid        | x0016     |
                    | or_field   | xe0000001 |  ==  | or_field   | xe0000001 |
                    | addr       | x60000001 |  ==  | addr       | x60000001 |
                    | data       | x80000000 |  ==  | data       | x80000000 |
                    +------------+-----------+      +------------+-----------+
                """),
        )

    def testCollapsedTableComparisonSharingContexts(self):
        msg2 = self.builder.WRITE_REGISTER_REQUEST_V2(addr="x60000001",
                                                      data="x80000000")
        msg2.or_field.context = self.builder.RANDOM_MEANING

        comp = self.msg.compare_tables(msg2, formats=None,
                                       expand_nested=False)[1]
        self.assertEqual(
            remove_whitespace(comp),
            remove_whitespace("""
                    +------------+-----------+      +------------+-----------+
                    | Field Name | Value     |      | Field Name | Value     |
                    +------------+-----------+      +------------+-----------+
                    | mid        | x0016     |  ==  | mid        | x0016     |
                    | or_field   | xe0000001 |  ==  | or_field   | xe0000001 |
                    | addr       | x60000001 |  ==  | addr       | x60000001 |
                    | data       | x80000000 |  ==  | data       | x80000000 |
                    +------------+-----------+      +------------+-----------+
                """),
        )

    @unittest.expectedFailure
    def testExpandedTableComparisonSharingContexts(self):
        msg2 = self.builder.WRITE_REGISTER_REQUEST_V2(addr="x60000001",
                                                      data="x80000000")
        msg2.or_field.context = self.builder.RANDOM_MEANING

        comp = self.msg.compare_tables(msg2, formats=None,
                                       expand_nested=True)[1]