Coverage for test_generate_gs1_datamatrix.py: 75%

54 statements  

« prev     ^ index     » next       coverage.py v6.4.1, created at 2022-07-12 15:55 +1000

1from pathlib import Path 

2import time 

3from typing import Callable 

4import pytest 

5import io 

6 

7 

8from gs1_barcode_enginer_wrapper import generate_gs1_datamatrix, Gs1GeneratorError 

9 

10# Barcode generation. 

11# Accepts input text which will be ASCII encoded then 

12# expressed as a barcode. 

13# Output is PNG encoded data as `bytes` 

14BarcodeGenerator = Callable[[str], bytes] 

15 

16 

17def save_to_file(filename, data: bytes): 

18 with open(filename, "wb") as f: 

19 f.write(data) 

20 

21 

22# takes about 0.38ms on mac, 0.76ms on pi 

23def gs1_bartcode_engine_wrapper_generator(barcode_text: str) -> bytes: 

24 # use wrapper around https://github.com/gs1/gs1-barcode-engine 

25 # cloned to gs1-barcode-engine 

26 

27 module_x_dim_mm = 0.7 

28 

29 module_x_dim_inches = module_x_dim_mm * 0.0393701 

30 dpi = 157.35 

31 

32 bmp_data = generate_gs1_datamatrix( 

33 barcode_text, 

34 dm_rows=22, 

35 dm_cols=22, 

36 x_undercut=0, 

37 y_undercut=0, 

38 scaling={"resolution": dpi, "target_x_dim": module_x_dim_inches}, 

39 ) 

40 

41 save_to_file("output/gs1_barcode_enginer_wrapper.bmp", bmp_data) 

42 

43 return bmp_data 

44 

45 

46@pytest.fixture 

47def good_barcode_text() -> str: 

48 return "(01)94210325403182(30)2(3922)0460(93)TQ" 

49 

50 

51@pytest.fixture( 

52 params=[ 

53 pytest.param( 

54 { 

55 "test_string": "(01)94210325403182(30)2(3922asdasd)0460(93)TQ", 

56 "expect_string_in_exception": "Unrecognised AI", 

57 }, 

58 id="Nonsense in middle of valid barcode text", 

59 ), 

60 pytest.param( 

61 {"test_string": "", "expect_string_in_exception": "Missing FNC1"}, 

62 id="Empty string", 

63 ), 

64 pytest.param( 

65 { 

66 "test_string": "This is nonsense", 

67 "expect_string_in_exception": "Failed to parse AI data", 

68 }, 

69 id="This is complete nonsense", 

70 ), 

71 ], 

72) 

73def bad_barcode_text(request) -> dict: 

74 return request.param 

75 

76 

77module_x_dim_mm = 0.7 

78module_x_dim_inches = module_x_dim_mm * 0.0393701 

79dpi = 157.35 

80 

81 

82@pytest.fixture( 

83 params=[ 

84 pytest.param( 

85 { 

86 "test_params": { 

87 "dm_rows": 2000, 

88 "dm_cols": 22, 

89 "x_undercut": 0, 

90 "y_undercut": 0, 

91 "scaling": {"resolution": dpi, "target_x_dim": module_x_dim_inches}, 

92 }, 

93 "expect_string_in_exception": "Valid number of Data Matrix rows range is", 

94 }, 

95 id="Huge number of rows", 

96 ), 

97 pytest.param( 

98 { 

99 "test_params": { 

100 "dm_rows": 22, 

101 "dm_cols": 24000, 

102 "x_undercut": 0, 

103 "y_undercut": 0, 

104 "scaling": {"resolution": dpi, "target_x_dim": module_x_dim_inches}, 

105 }, 

106 "expect_string_in_exception": "Valid number of Data Matrix columns range is", 

107 }, 

108 id="Huge number of columns", 

109 ), 

110 pytest.param( 

111 { 

112 "test_params": { 

113 "dm_rows": 22, 

114 "dm_cols": 22, 

115 "x_undercut": 900, 

116 "y_undercut": 0, 

117 "scaling": {"resolution": dpi, "target_x_dim": module_x_dim_inches}, 

118 }, 

119 "expect_string_in_exception": "Valid X undercut range is", 

120 }, 

121 id="Huge X undercut", 

122 ), 

123 pytest.param( 

124 { 

125 "test_params": { 

126 "dm_rows": 22, 

127 "dm_cols": 22, 

128 "x_undercut": 0, 

129 "y_undercut": 900, 

130 "scaling": {"resolution": dpi, "target_x_dim": module_x_dim_inches}, 

131 }, 

132 "expect_string_in_exception": "Valid Y undercut range is", 

133 }, 

134 id="Huge Y undercut", 

135 ), 

136 pytest.param( 

137 { 

138 "test_params": { 

139 "dm_rows": 22, 

140 "dm_cols": 22, 

141 "x_undercut": 0, 

142 "y_undercut": 0, 

143 "scaling": { 

144 "resolution": dpi, 

145 "target_x_dim": module_x_dim_inches, 

146 "min_x_dim": module_x_dim_inches, 

147 "max_x_dim": module_x_dim_inches, 

148 }, 

149 }, 

150 "expect_string_in_exception": "Impossible to plot X-dimension of", 

151 }, 

152 id="Unreasonable/impossible dot scaling constraints", 

153 ), 

154 pytest.param( 

155 { 

156 "test_params": { 

157 "dm_rows": 22, 

158 "dm_cols": 22, 

159 "x_undercut": 0, 

160 "y_undercut": 0, 

161 "scaling": { 

162 "pix_mult": 5000000, 

163 }, 

164 }, 

165 "expect_string_in_exception": "Valid X-dimension range is 1 to 100", 

166 }, 

167 id="Unreasonable/impossible pixel scaling constraints", 

168 ), 

169 pytest.param( 

170 { 

171 "test_params": { 

172 "dm_rows": 22, 

173 "dm_cols": 22, 

174 "x_undercut": 0, 

175 "y_undercut": 0, 

176 "scaling": { 

177 "resolution": 999999999, 

178 "target_x_dim": module_x_dim_inches, 

179 "min_x_dim": module_x_dim_inches, 

180 "max_x_dim": module_x_dim_inches, 

181 }, 

182 }, 

183 "expect_string_in_exception": "Valid X-dimension range is 1 to 100", 

184 }, 

185 id="Dot scaling: resolution probably out of range", 

186 ), 

187 ], 

188) 

189def bad_generation_params(request) -> dict: 

190 return request.param 

191 

192 

193@pytest.fixture 

194def output_dir() -> Path: 

195 DIR = "output" 

196 path = Path(DIR) 

197 for f in path.glob("*.*"): 197 ↛ 200line 197 didn't jump to line 200, because the loop on line 197 didn't complete

198 f.unlink() 

199 

200 assert path.is_dir 

201 assert len(list(path.glob("*.*"))) == 0 

202 

203 yield path 

204 

205 assert len(list(path.glob("*.*"))) == 1 

206 

207 

208@pytest.fixture( 

209 params=[ 

210 pytest.param( 

211 { 

212 "dm_rows": 22, 

213 "dm_cols": 22, 

214 "x_undercut": 0, 

215 "y_undercut": 0, 

216 "scaling": {"resolution": dpi, "target_x_dim": module_x_dim_inches}, 

217 }, 

218 id="Standard", 

219 ), 

220 pytest.param( 

221 {}, 

222 id="No params", 

223 ), 

224 pytest.param( 

225 { 

226 "dm_rows": 22, 

227 }, 

228 id="dm_rows only", 

229 ), 

230 pytest.param( 

231 { 

232 "dm_cols": 22, 

233 }, 

234 id="dm_cols only", 

235 ), 

236 pytest.param( 

237 { 

238 "x_undercut": 1, 

239 "scaling": {"pix_mult": 50}, 

240 }, 

241 id="x undercut only (default scaling overwritten to make this possible)", 

242 ), 

243 pytest.param( 

244 { 

245 "y_undercut": 1, 

246 "scaling": {"pix_mult": 50}, 

247 }, 

248 id="y undercut only (default scaling overwritten to make this possible)", 

249 ), 

250 pytest.param( 

251 { 

252 "x_undercut": 1, 

253 "y_undercut": 1, 

254 "scaling": {"pix_mult": 50}, 

255 }, 

256 id="Both x and y undercut (default scaling overwritten to make this possible)", 

257 ), 

258 pytest.param( 

259 { 

260 "scaling": {"resolution": dpi, "target_x_dim": module_x_dim_inches}, 

261 }, 

262 id="Device dot (i.e. physical dimensions e.g. inches) scaling, only target_x_dim defined", 

263 ), 

264 pytest.param( 

265 { 

266 "scaling": { 

267 "resolution": 300, 

268 "min_x_dim": 0.02, 

269 "target_x_dim": 0.03, 

270 "max_x_dim": 0.04, 

271 }, 

272 }, 

273 id="Device dot (i.e. physical dimensions e.g. inches) scaling, only target_x_dim defined", 

274 ), 

275 pytest.param( 

276 { 

277 "scaling": {"pix_mult": 50}, 

278 }, 

279 id="Pixel-based (i.e. pixels only, not physical dimensions) scaling scaling only", 

280 ), 

281 ], 

282) 

283def good_generation_params(request) -> dict: 

284 return request.param 

285 

286 

287def test_good_params(good_barcode_text, good_generation_params: dict, output_dir: Path): 

288 bmp_data = generate_gs1_datamatrix(good_barcode_text, **good_generation_params) 

289 save_to_file(output_dir / "gs1_barcode_enginer_wrapper.bmp", bmp_data) 

290 

291 

292def test_bad_input(bad_barcode_text: dict): 

293 with pytest.raises(Gs1GeneratorError) as exc: 

294 barcode_bytes = gs1_bartcode_engine_wrapper_generator( 

295 bad_barcode_text["test_string"] 

296 ) 

297 

298 assert bad_barcode_text["expect_string_in_exception"] in str(exc) 

299 

300 

301def test_bad_generation_params(good_barcode_text, bad_generation_params: dict): 

302 test_params = bad_generation_params["test_params"] 

303 with pytest.raises(Gs1GeneratorError) as exc: 

304 bmp_data = generate_gs1_datamatrix(good_barcode_text, **test_params) 

305 

306 assert bad_generation_params["expect_string_in_exception"] in str(exc)