symbol_test.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. // go-qrcode
  2. // Copyright 2014 Tom Harwood
  3. package qrcode
  4. import "testing"
  5. func TestSymbolBasic(t *testing.T) {
  6. size := 10
  7. quietZoneSize := 4
  8. m := newSymbol(size, quietZoneSize)
  9. if m.size != size+quietZoneSize*2 {
  10. t.Errorf("Symbol size is %d, expected %d", m.size, size+quietZoneSize*2)
  11. }
  12. for i := 0; i < size; i++ {
  13. for j := 0; j < size; j++ {
  14. v := m.get(i, j)
  15. if v != false {
  16. t.Errorf("New symbol not empty")
  17. }
  18. if !m.empty(i, j) {
  19. t.Errorf("New symbol is not empty")
  20. }
  21. value := i*j%2 == 0
  22. m.set(i, j, value)
  23. v = m.get(i, j)
  24. if v != value {
  25. t.Errorf("Symbol ignores set bits")
  26. }
  27. if m.empty(i, j) {
  28. t.Errorf("Symbol ignores set bits")
  29. }
  30. }
  31. }
  32. }
  33. func TestSymbolPenalties(t *testing.T) {
  34. tests := []struct {
  35. pattern [][]bool
  36. expectedPenalty1 int
  37. expectedPenalty2 int
  38. expectedPenalty3 int
  39. expectedPenalty4 int
  40. }{
  41. {
  42. [][]bool{
  43. {b0, b1, b0, b1, b0, b1},
  44. {b1, b0, b1, b0, b1, b0},
  45. {b0, b1, b0, b1, b0, b1},
  46. {b1, b0, b1, b0, b1, b0},
  47. {b0, b1, b0, b1, b0, b1},
  48. {b1, b0, b1, b0, b1, b0},
  49. },
  50. 0, // No adjacent modules of same color.
  51. 0, // No 2x2+ sized blocks.
  52. 0, // No 1:1:3:1:1 pattern.
  53. -1,
  54. },
  55. {
  56. [][]bool{
  57. {b0, b0, b0, b1, b0, b1},
  58. {b1, b0, b1, b0, b1, b0},
  59. {b0, b1, b0, b1, b0, b1},
  60. {b1, b0, b1, b0, b1, b0},
  61. {b0, b1, b0, b1, b0, b1},
  62. {b1, b0, b1, b0, b1, b0},
  63. },
  64. 0, // 5 adjacent modules of same colour, score = 0.
  65. 0, // No 2x2+ sized blocks.
  66. 0, // No 1:1:3:1:1 pattern.
  67. -1,
  68. },
  69. {
  70. [][]bool{
  71. {b0, b0, b0, b0, b0, b0},
  72. {b1, b0, b1, b0, b1, b0},
  73. {b0, b1, b0, b1, b0, b1},
  74. {b1, b0, b1, b0, b1, b0},
  75. {b0, b1, b0, b1, b0, b1},
  76. {b1, b0, b1, b0, b1, b0},
  77. },
  78. 4, // 6 adjacent modules of same colour, score = 3 + (6-5)
  79. 0, // No 2x2+ sized blocks.
  80. 0, // No 1:1:3:1:1 pattern.
  81. -1,
  82. },
  83. {
  84. [][]bool{
  85. {b0, b0, b0, b0, b0, b0, b0},
  86. {b1, b0, b1, b0, b1, b0, b1},
  87. {b1, b0, b0, b0, b0, b0, b1},
  88. {b1, b0, b1, b0, b1, b0, b1},
  89. {b1, b0, b0, b0, b0, b0, b1},
  90. {b1, b0, b1, b0, b1, b0, b1},
  91. {b1, b0, b0, b0, b0, b0, b0},
  92. },
  93. 28, // 3+(7-5) + 3+(6-5) + 3+(6-5) + 3+(6-5) + 3+(7-5) + 3+(7-5) = 28
  94. 0, // No 2x2+ sized blocks.
  95. 0, // No 1:1:3:1:1 pattern.
  96. -1,
  97. },
  98. {
  99. [][]bool{
  100. {b0, b0, b0, b1, b0, b1},
  101. {b0, b0, b1, b0, b1, b0},
  102. {b0, b1, b0, b1, b0, b1},
  103. {b1, b0, b1, b1, b1, b0},
  104. {b0, b1, b1, b1, b0, b1},
  105. {b1, b0, b1, b0, b1, b0},
  106. },
  107. -1,
  108. 6, // 3*(2-1)*(2-1) + 3(2-1)*(2-1)
  109. 0, // No 1:1:3:1:1 pattern.
  110. -1,
  111. },
  112. {
  113. [][]bool{
  114. {b0, b0, b0, b0, b0, b1},
  115. {b0, b0, b0, b0, b0, b1},
  116. {b0, b0, b0, b0, b0, b1},
  117. {b0, b0, b0, b0, b0, b1},
  118. {b0, b0, b0, b0, b0, b1},
  119. {b0, b0, b0, b0, b0, b1},
  120. },
  121. -1,
  122. 60, // 3 * (5-1) * (6-1)
  123. 0, // No 1:1:3:1:1 pattern.
  124. -1,
  125. },
  126. {
  127. [][]bool{
  128. {b0, b0, b0, b0, b0, b1},
  129. {b0, b0, b0, b0, b0, b1},
  130. {b1, b1, b0, b1, b0, b1},
  131. {b1, b1, b0, b1, b0, b1},
  132. {b1, b1, b0, b1, b0, b1},
  133. {b1, b1, b0, b1, b0, b1},
  134. },
  135. -1,
  136. 21, // 3*(5-1)*(2-1) + 3*(2-1)*(4-1) = 3*4 + 3*3
  137. 0, // No 1:1:3:1:1 pattern.
  138. -1,
  139. },
  140. {
  141. [][]bool{
  142. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  143. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  144. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  145. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  146. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  147. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  148. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  149. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  150. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  151. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  152. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  153. {b0, b0, b0, b0, b1, b0, b1, b1, b1, b0, b1, b0},
  154. },
  155. -1,
  156. -1,
  157. 480, // 12* 1:1:3:1:1 patterns, 12 * 40.
  158. -1,
  159. },
  160. {
  161. [][]bool{
  162. {b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  163. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  164. {b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  165. {b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  166. {b1, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  167. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  168. {b1, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  169. {b0, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  170. {b0, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  171. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  172. {b0, b1, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  173. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  174. },
  175. -1,
  176. -1,
  177. 80, // 2* 1:1:3:1:1 patterns, 2 * 40.
  178. -1,
  179. },
  180. {
  181. [][]bool{
  182. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  183. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  184. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  185. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  186. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  187. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  188. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  189. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  190. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  191. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  192. },
  193. -1,
  194. -1,
  195. -1,
  196. 100, // 10 * (10 steps of 5% deviation from 50% black/white).
  197. },
  198. {
  199. [][]bool{
  200. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  201. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  202. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  203. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  204. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  205. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  206. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  207. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  208. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  209. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  210. },
  211. -1,
  212. -1,
  213. -1,
  214. 100, // 10 * (10 steps of 5% deviation from 50% black/white).
  215. },
  216. {
  217. [][]bool{
  218. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  219. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  220. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  221. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  222. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  223. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  224. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  225. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  226. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  227. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  228. },
  229. -1,
  230. -1,
  231. -1,
  232. 0, // Exactly 50%/50% black/white.
  233. },
  234. {
  235. [][]bool{
  236. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  237. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  238. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  239. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  240. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  241. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  242. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  243. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  244. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  245. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  246. },
  247. -1,
  248. -1,
  249. -1,
  250. 20, // 10 * (2 steps of 5% deviation towards white).
  251. },
  252. {
  253. [][]bool{
  254. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  255. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  256. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  257. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  258. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  259. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  260. {b0, b0, b0, b0, b0, b0, b1, b1, b1, b1},
  261. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  262. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  263. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  264. },
  265. -1,
  266. -1,
  267. -1,
  268. 30, // 10 * (3 steps of 5% deviation towards white).
  269. },
  270. {
  271. [][]bool{
  272. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  273. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  274. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  275. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  276. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  277. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b0},
  278. {b0, b0, b0, b0, b0, b0, b0, b0, b0, b1},
  279. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  280. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  281. {b1, b1, b1, b1, b1, b1, b1, b1, b1, b1},
  282. },
  283. -1,
  284. -1,
  285. -1,
  286. 30, // 10 * (3 steps of 5% deviation towards white).
  287. },
  288. }
  289. for i, test := range tests {
  290. s := newSymbol(len(test.pattern[0]), 4)
  291. s.set2dPattern(0, 0, test.pattern)
  292. penalty1 := s.penalty1()
  293. penalty2 := s.penalty2()
  294. penalty3 := s.penalty3()
  295. penalty4 := s.penalty4()
  296. ok := true
  297. if test.expectedPenalty1 != -1 && test.expectedPenalty1 != penalty1 {
  298. ok = false
  299. }
  300. if test.expectedPenalty2 != -1 && test.expectedPenalty2 != penalty2 {
  301. ok = false
  302. }
  303. if test.expectedPenalty3 != -1 && test.expectedPenalty3 != penalty3 {
  304. ok = false
  305. }
  306. if test.expectedPenalty4 != -1 && test.expectedPenalty4 != penalty4 {
  307. ok = false
  308. }
  309. if !ok {
  310. t.Fatalf("Penalty test #%d p1=%d, p2=%d, p3=%d, p4=%d (expected p1=%d, p2=%d, p3=%d, p4=%d)", i, penalty1, penalty2, penalty3, penalty4,
  311. test.expectedPenalty1, test.expectedPenalty2, test.expectedPenalty3,
  312. test.expectedPenalty4)
  313. }
  314. }
  315. }