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