highlevel_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package aztec
  2. import (
  3. "bytes"
  4. "strings"
  5. "testing"
  6. "github.com/boombuler/barcode/utils"
  7. )
  8. func bitStr(bl *utils.BitList) string {
  9. buf := new(bytes.Buffer)
  10. for i := 0; i < bl.Len(); i++ {
  11. if bl.GetBit(i) {
  12. buf.WriteRune('X')
  13. } else {
  14. buf.WriteRune('.')
  15. }
  16. }
  17. return buf.String()
  18. }
  19. func testHighLevelEncodeString(t *testing.T, s, expectedBits string) {
  20. bits := highlevelEncode([]byte(s))
  21. result := bitStr(bits)
  22. expectedBits = strings.Replace(expectedBits, " ", "", -1)
  23. if result != expectedBits {
  24. t.Errorf("invalid result for highlevelEncode(%q). Got:\n%s", s, result)
  25. }
  26. }
  27. func testHighLevelEncodeStringCnt(t *testing.T, s string, expectedBitCnt int) {
  28. bits := highlevelEncode([]byte(s))
  29. if bits.Len() != expectedBitCnt {
  30. t.Errorf("invalid result for highlevelEncode(%q). Got %d, expected %d bits", s, bits.Len(), expectedBitCnt)
  31. }
  32. }
  33. func Test_HighLevelEncode(t *testing.T) {
  34. testHighLevelEncodeString(t, "A. b.",
  35. // 'A' P/S '. ' L/L b D/L '.'
  36. "...X. ..... ...XX XXX.. ...XX XXXX. XX.X")
  37. testHighLevelEncodeString(t, "Lorem ipsum.",
  38. // 'L' L/L 'o' 'r' 'e' 'm' ' ' 'i' 'p' 's' 'u' 'm' D/L '.'
  39. ".XX.X XXX.. X.... X..XX ..XX. .XXX. ....X .X.X. X...X X.X.. X.XX. .XXX. XXXX. XX.X")
  40. testHighLevelEncodeString(t, "Lo. Test 123.",
  41. // 'L' L/L 'o' P/S '. ' U/S 'T' 'e' 's' 't' D/L ' ' '1' '2' '3' '.'
  42. ".XX.X XXX.. X.... ..... ...XX XXX.. X.X.X ..XX. X.X.. X.X.X XXXX. ...X ..XX .X.. .X.X XX.X")
  43. testHighLevelEncodeString(t, "Lo...x",
  44. // 'L' L/L 'o' D/L '.' '.' '.' U/L L/L 'x'
  45. ".XX.X XXX.. X.... XXXX. XX.X XX.X XX.X XXX. XXX.. XX..X")
  46. testHighLevelEncodeString(t, ". x://abc/.",
  47. //P/S '. ' L/L 'x' P/S ':' P/S '/' P/S '/' 'a' 'b' 'c' P/S '/' D/L '.'
  48. "..... ...XX XXX.. XX..X ..... X.X.X ..... X.X.. ..... X.X.. ...X. ...XX ..X.. ..... X.X.. XXXX. XX.X")
  49. // Uses Binary/Shift rather than Lower/Shift to save two bits.
  50. testHighLevelEncodeString(t, "ABCdEFG",
  51. //'A' 'B' 'C' B/S =1 'd' 'E' 'F' 'G'
  52. "...X. ...XX ..X.. XXXXX ....X .XX..X.. ..XX. ..XXX .X...")
  53. testHighLevelEncodeStringCnt(t,
  54. // Found on an airline boarding pass. Several stretches of Binary shift are
  55. // necessary to keep the bitcount so low.
  56. "09 UAG ^160MEUCIQC0sYS/HpKxnBELR1uB85R20OoqqwFGa0q2uEi"+
  57. "Ygh6utAIgLl1aBVM4EOTQtMQQYH9M2Z3Dp4qnA/fwWuQ+M8L3V8U=",
  58. 823)
  59. }
  60. func Test_HighLevelEncodeBinary(t *testing.T) {
  61. // binary short form single byte
  62. testHighLevelEncodeString(t, "N\u0000N",
  63. // 'N' B/S =1 '\0' N
  64. ".XXXX XXXXX ....X ........ .XXXX") // Encode "N" in UPPER
  65. testHighLevelEncodeString(t, "N\u0000n",
  66. // 'N' B/S =2 '\0' 'n'
  67. ".XXXX XXXXX ...X. ........ .XX.XXX.") // Encode "n" in BINARY
  68. // binary short form consecutive bytes
  69. testHighLevelEncodeString(t, "N\x00\x80 A",
  70. // 'N' B/S =2 '\0' \u0080 ' ' 'A'
  71. ".XXXX XXXXX ...X. ........ X....... ....X ...X.")
  72. // binary skipping over single character
  73. testHighLevelEncodeString(t, "\x00a\xFF\x80 A",
  74. // B/S =4 '\0' 'a' '\3ff' '\200' ' ' 'A'
  75. "XXXXX ..X.. ........ .XX....X XXXXXXXX X....... ....X ...X.")
  76. // getting into binary mode from digit mode
  77. testHighLevelEncodeString(t, "1234\u0000",
  78. //D/L '1' '2' '3' '4' U/L B/S =1 \0
  79. "XXXX. ..XX .X.. .X.X .XX. XXX. XXXXX ....X ........")
  80. // Create a string in which every character requires binary
  81. sb := new(bytes.Buffer)
  82. for i := 0; i <= 3000; i++ {
  83. sb.WriteByte(byte(128 + (i % 30)))
  84. }
  85. // Test the output generated by Binary/Switch, particularly near the
  86. // places where the encoding changes: 31, 62, and 2047+31=2078
  87. for _, i := range []int{1, 2, 3, 10, 29, 30, 31, 32, 33, 60, 61, 62, 63, 64, 2076, 2077, 2078, 2079, 2080, 2100} {
  88. // This is the expected length of a binary string of length "i"
  89. expectedLength := (8 * i)
  90. switch {
  91. case i <= 31:
  92. expectedLength += 10
  93. case i <= 62:
  94. expectedLength += 20
  95. case i <= 2078:
  96. expectedLength += 21
  97. default:
  98. expectedLength += 31
  99. }
  100. data := string(sb.Bytes()[:i])
  101. // Verify that we are correct about the length.
  102. testHighLevelEncodeStringCnt(t, data, expectedLength)
  103. if i != 1 && i != 32 && i != 2079 {
  104. // The addition of an 'a' at the beginning or end gets merged into the binary code
  105. // in those cases where adding another binary character only adds 8 or 9 bits to the result.
  106. // So we exclude the border cases i=1,32,2079
  107. // A lower case letter at the beginning will be merged into binary mode
  108. testHighLevelEncodeStringCnt(t, "a"+string(sb.Bytes()[:i-1]), expectedLength)
  109. // A lower case letter at the end will also be merged into binary mode
  110. testHighLevelEncodeStringCnt(t, string(sb.Bytes()[:i-1])+"a", expectedLength)
  111. }
  112. // A lower case letter at both ends will enough to latch us into LOWER.
  113. testHighLevelEncodeStringCnt(t, "a"+data+"b", expectedLength+15)
  114. }
  115. }