Coverage for hdl_registers/generator/html/test/test_register_html_generator.py: 100%

84 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-19 20:51 +0000

1# -------------------------------------------------------------------------------------------------- 

2# Copyright (c) Lukas Vik. All rights reserved. 

3# 

4# This file is part of the hdl-registers project, an HDL register generator fast enough to run 

5# in real time. 

6# https://hdl-registers.com 

7# https://github.com/hdl-registers/hdl-registers 

8# -------------------------------------------------------------------------------------------------- 

9 

10# Third party libraries 

11import pytest 

12from tsfpga.system_utils import read_file 

13 

14# First party libraries 

15from hdl_registers import HDL_REGISTERS_TESTS 

16from hdl_registers.generator.html.constant_table import HtmlConstantTableGenerator 

17from hdl_registers.generator.html.page import HtmlPageGenerator 

18from hdl_registers.generator.html.register_table import HtmlRegisterTableGenerator 

19from hdl_registers.parser.toml import from_toml 

20 

21 

22class HtmlTest: 

23 def __init__(self, tmp_path): 

24 self.tmp_path = tmp_path 

25 self.register_list = from_toml( 

26 name="caesar", toml_file=HDL_REGISTERS_TESTS / "regs_test.toml" 

27 ) 

28 

29 def create_html_page(self): 

30 html = read_file(HtmlPageGenerator(self.register_list, self.tmp_path).create()) 

31 return html 

32 

33 @staticmethod 

34 # pylint: disable=too-many-arguments 

35 def check_register(name, index, address, mode, default_value, description, html): 

36 expected = f""" 

37 <tr> 

38 <td><strong>{name}</strong></td> 

39 <td>{index}</td> 

40 <td>{address}</td> 

41 <td>{mode}</td> 

42 <td>{default_value}</td> 

43 <td>{description}</td> 

44 </tr> 

45""" 

46 assert expected in html, f"{expected}\n\n{html}" 

47 

48 @staticmethod 

49 def check_field(name, index, default_value, html, description=None): 

50 expected = f""" 

51 <tr> 

52 <td>&nbsp;&nbsp;<em>{name}</em></td> 

53 <td>&nbsp;&nbsp;{index}</td> 

54 <td></td> 

55 <td></td> 

56 <td>{default_value}</td> 

57""" 

58 if description: 

59 expected += f"""\ 

60 <td> 

61 {description} 

62 </td> 

63""" 

64 

65 assert expected in html, f"{expected}\n\n{html}" 

66 

67 @staticmethod 

68 def check_register_array(name, length, iterator_range, description, html): 

69 expected = f""" 

70 <tr> 

71 <td class="array_header" colspan=5> 

72 Register array <strong>{name}</strong>, repeated {length} times. 

73 Iterator <i>{iterator_range}.</i> 

74 </td> 

75 <td class="array_header">{description}</td> 

76 </tr> 

77""" 

78 assert expected in html, f"{expected}\n\n{html}" 

79 

80 @staticmethod 

81 def check_constant(name, value, html): 

82 expected = f""" 

83 <tr> 

84 <td><strong>{name}</strong></td> 

85 <td>{value}</td> 

86""" 

87 assert expected in html, f"{expected}\n\n{html}" 

88 

89 

90@pytest.fixture 

91def html_test(tmp_path): 

92 return HtmlTest(tmp_path=tmp_path) 

93 

94 

95# False positive for pytest fixtures 

96# pylint: disable=redefined-outer-name 

97 

98 

99def test_registers(html_test): 

100 """ 

101 Test that all registers show up in the HTML with correct attributes. 

102 """ 

103 html = html_test.create_html_page() 

104 

105 html_test.check_register( 

106 name="config", 

107 index=0, 

108 address="0x0000", 

109 mode="Read, Write", 

110 default_value="0x14846", 

111 description="A plain <strong>dummy</strong> register.", 

112 html=html, 

113 ) 

114 

115 html_test.check_register_array( 

116 name="dummies", 

117 length=3, 

118 iterator_range="i &isin; [0, 2]", 

119 description="An <strong>array</strong> with some dummy regs", 

120 html=html, 

121 ) 

122 

123 html_test.check_register( 

124 name="first", 

125 index="7 + i &times; 2", 

126 address="0x001C + i &times; 0x0008", 

127 mode="Read, Write", 

128 default_value="0x5880", 

129 description="The first register in the array.", 

130 html=html, 

131 ) 

132 

133 html_test.check_register( 

134 name="second", 

135 index="8 + i &times; 2", 

136 address="0x0020 + i &times; 0x0008", 

137 mode="Read", 

138 default_value="0xC7", 

139 description="The second register in the array.", 

140 html=html, 

141 ) 

142 

143 

144def test_register_fields(html_test): 

145 """ 

146 Test that all bits show up in the HTML with correct attributes. 

147 """ 

148 html = html_test.create_html_page() 

149 

150 # Fields in plain register 

151 html_test.check_field( 

152 name="plain_bit_a", 

153 index="0", 

154 default_value="0b0", 

155 description="Bit A", 

156 html=html, 

157 ) 

158 html_test.check_field( 

159 name="plain_bit_vector", 

160 index="4:1", 

161 default_value="0b0011", 

162 description="Bit <strong>vector</strong>", 

163 html=html, 

164 ) 

165 html_test.check_field( 

166 name="plain_integer", 

167 index="12:5", 

168 default_value="66", 

169 html=html, 

170 ) 

171 html_test.check_field( 

172 name="plain_enumeration", 

173 index="15:13", 

174 default_value="third", 

175 html=html, 

176 ) 

177 html_test.check_field( 

178 name="plain_bit_b", 

179 index="16", 

180 default_value="0b1", 

181 description="Bit B", 

182 html=html, 

183 ) 

184 

185 # Fields in register array 

186 html_test.check_field( 

187 name="array_bit_a", 

188 index="7", 

189 default_value="0b1", 

190 description="Array register bit A", 

191 html=html, 

192 ) 

193 html_test.check_field( 

194 name="array_bit_b", 

195 index="8", 

196 default_value="0b0", 

197 description="Array register bit B", 

198 html=html, 

199 ) 

200 html_test.check_field( 

201 name="array_bit_vector", 

202 index="13:9", 

203 default_value="0b01100", 

204 description="Array register bit vector", 

205 html=html, 

206 ) 

207 

208 

209def test_registers_and_constants(html_test): 

210 """ 

211 Test that all constant show up in the HTML with correct attributes. 

212 Should only appear if there are actually any constants set. 

213 """ 

214 constants_text = "The following constants are part of the register interface" 

215 

216 html = html_test.create_html_page() 

217 

218 # Check that registers are there 

219 assert "Registers" in html, html 

220 assert "dummies" in html, html 

221 

222 # Check that constants are there 

223 assert constants_text in html, html 

224 html_test.check_constant(name="data_width", value=24, html=html) 

225 html_test.check_constant(name="decrement", value=-8, html=html) 

226 html_test.check_constant(name="enabled", value="True", html=html) 

227 html_test.check_constant(name="disabled", value="False", html=html) 

228 html_test.check_constant(name="rate", value="3.5", html=html) 

229 html_test.check_constant(name="paragraph", value='"hello there :)"', html=html) 

230 

231 # Test again with no constants 

232 html_test.register_list.constants = [] 

233 html = html_test.create_html_page() 

234 

235 # Registers should still be there 

236 assert "Registers" in html, html 

237 assert "dummies" in html, html 

238 

239 # But no constants 

240 assert constants_text not in html, html 

241 

242 

243def test_constants_and_no_registers(html_test): 

244 html_test.register_list.register_objects = [] 

245 

246 html = html_test.create_html_page() 

247 

248 assert "This module does not have any registers" in html, html 

249 assert "dummies" not in html, html 

250 

251 assert "<h2>Constants</h2>" in html, html 

252 html_test.check_constant(name="data_width", value=24, html=html) 

253 html_test.check_constant(name="decrement", value=-8, html=html) 

254 

255 

256def test_register_table_is_empty_string_if_no_registers_are_available(html_test): 

257 html_test.register_list.register_objects = [] 

258 

259 html = read_file( 

260 HtmlRegisterTableGenerator(html_test.register_list, html_test.tmp_path).create() 

261 ) 

262 assert html == "", html 

263 

264 

265def test_constant_table_is_empty_string_if_no_constants_are_available(html_test): 

266 html_test.register_list.constants = [] 

267 

268 html = read_file( 

269 HtmlConstantTableGenerator(html_test.register_list, html_test.tmp_path).create() 

270 ) 

271 assert html == "", html