Coverage for hdl_registers/test/unit/test_register_html_generator.py: 100%
76 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-29 22:03 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-29 22:03 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the hdl_registers project, a HDL register generator fast enough to be run
5# in real time.
6# https://hdl-registers.com
7# https://gitlab.com/hdl_registers/hdl_registers
8# --------------------------------------------------------------------------------------------------
10# Standard libraries
11import unittest
13# Third party libraries
14import pytest
15from tsfpga.system_utils import read_file
17# First party libraries
18from hdl_registers import HDL_REGISTERS_TEST
19from hdl_registers.parser import from_toml
22@pytest.mark.usefixtures("fixture_tmp_path")
23class TestRegisterHtmlGenerator(unittest.TestCase):
24 tmp_path = None
26 def setUp(self):
27 toml_file = HDL_REGISTERS_TEST / "regs_test.toml"
28 self.registers = from_toml("test", toml_file)
30 def test_registers(self):
31 """
32 Test that all registers show up in the HTML with correct attributes.
33 """
34 html = self._create_html_page()
36 self._check_register(
37 name="plain_dummy_reg",
38 index=0,
39 address="0x0000",
40 mode="Read, Write",
41 default_value="0xE",
42 description="A plain <strong>dummy</strong> register.",
43 html=html,
44 )
46 self._check_register_array(
47 name="dummy_regs",
48 length=3,
49 iterator_range="i ∈ [0, 2]",
50 description="An <strong>array</strong> with some dummy regs",
51 html=html,
52 )
54 self._check_register(
55 name="array_dummy_reg",
56 index="5 + i × 2",
57 address="0x0014 + i × 0x0008",
58 mode="Read, Write",
59 default_value="0x31",
60 description="The first register in the array.",
61 html=html,
62 )
64 self._check_register(
65 name="second_array_dummy_reg",
66 index="6 + i × 2",
67 address="0x0018 + i × 0x0008",
68 mode="Read",
69 default_value="0x0",
70 description="The second register in the array.",
71 html=html,
72 )
74 def test_register_fields(self):
75 """
76 Test that all bits show up in the HTML with correct attributes.
77 """
78 html = self._create_html_page()
80 # Fields in plain register
81 self._check_field(
82 name="plain_bit_a",
83 index="0",
84 default_value="0b0",
85 description="Bit A",
86 html=html,
87 )
88 self._check_field(
89 name="plain_bit_b",
90 index="1",
91 default_value="0b1",
92 description="Bit B",
93 html=html,
94 )
95 self._check_field(
96 name="plain_bit_vector",
97 index="5:2",
98 default_value="0b0011",
99 description="Bit <strong>vector</strong>",
100 html=html,
101 )
103 # Fields in register array
104 self._check_field(
105 name="array_bit_a",
106 index="0",
107 default_value="0b1",
108 description="Array register bit A",
109 html=html,
110 )
111 self._check_field(
112 name="array_bit_b",
113 index="1",
114 default_value="0b0",
115 description="Array register bit B",
116 html=html,
117 )
118 self._check_field(
119 name="array_bit_vector",
120 index="6:2",
121 default_value="0b01100",
122 description="Array register bit vector",
123 html=html,
124 )
126 def test_registers_and_constants(self):
127 """
128 Test that all constant show up in the HTML with correct attributes.
129 Should only appear if there are actually any constants set.
130 """
131 constants_text = "The following constants are part of the register interface"
133 html = self._create_html_page()
135 # Check that registers are there
136 assert "Registers" in html, html
137 assert "dummy_regs" in html, html
139 # Check that constants are there
140 assert constants_text in html, html
141 self._check_constant(name="data_width", value=24, html=html)
142 self._check_constant(name="decrement", value=-8, html=html)
144 # Test again with no constants
145 self.registers.constants = []
146 html = self._create_html_page()
148 # Registers should still be there
149 assert "Registers" in html, html
150 assert "dummy_regs" in html, html
152 # But no constants
153 assert constants_text not in html, html
155 def test_constants_and_no_registers(self):
156 self.registers.register_objects = []
158 html = self._create_html_page()
160 assert "This module does not have any registers" in html, html
161 assert "dummy_regs" not in html, html
163 assert "<h2>Constants</h2>" in html, html
164 self._check_constant(name="data_width", value=24, html=html)
165 self._check_constant(name="decrement", value=-8, html=html)
167 def _create_html_page(self):
168 self.registers.create_html_page(self.tmp_path)
169 html = read_file(self.tmp_path / "test_regs.html")
170 return html
172 @staticmethod
173 # pylint: disable=too-many-arguments
174 def _check_register(name, index, address, mode, default_value, description, html):
175 expected = f"""
176 <tr>
177 <td><strong>{name}</strong></td>
178 <td>{index}</td>
179 <td>{address}</td>
180 <td>{mode}</td>
181 <td>{default_value}</td>
182 <td>{description}</td>
183 </tr>
184"""
185 assert expected in html, f"{expected}\n\n{html}"
187 @staticmethod
188 def _check_field(name, index, default_value, description, html):
189 expected = f"""
190 <tr>
191 <td> <em>{name}</em></td>
192 <td> {index}</td>
193 <td></td>
194 <td></td>
195 <td>{default_value}</td>
196 <td>{description}</td>
197"""
198 assert expected in html, f"{expected}\n\n{html}"
200 @staticmethod
201 def _check_register_array(name, length, iterator_range, description, html):
202 expected = f"""
203 <tr>
204 <td class="array_header" colspan=5>
205 Register array <strong>{name}</strong>, repeated {length} times.
206 Iterator <i>{iterator_range}.</i>
207 </td>
208 <td class="array_header">{description}</td>
209 </tr>
210"""
211 assert expected in html, f"{expected}\n\n{html}"
213 @staticmethod
214 def _check_constant(name, value, html):
215 expected = f"""
216 <tr>
217 <td><strong>{name}</strong></td>
218 <td>{value}</td>
219"""
220 assert expected in html, f"{expected}\n\n{html}"
222 def test_register_table_is_empty_string_if_no_registers_are_available(self):
223 self.registers.register_objects = []
225 self.registers.create_html_register_table(self.tmp_path)
226 html = read_file(self.tmp_path / "test_register_table.html")
227 assert html == "", html
229 def test_constant_table_is_empty_string_if_no_constants_are_available(self):
230 self.registers.constants = []
232 self.registers.create_html_constant_table(self.tmp_path)
233 html = read_file(self.tmp_path / "test_constant_table.html")
234 assert html == "", html