123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- // go-qrcode
- // Copyright 2014 Tom Harwood
- package qrcode
- import (
- "fmt"
- "reflect"
- "testing"
- bitset "github.com/skip2/go-qrcode/bitset"
- )
- func TestClassifyDataMode(t *testing.T) {
- type Test struct {
- }
- tests := []struct {
- data []byte
- actual []segment
- }{
- {
- []byte{0x30},
- []segment{
- {
- dataModeNumeric,
- []byte{0x30},
- },
- },
- },
- {
- []byte{0x30, 0x41, 0x42, 0x43, 0x20, 0x00, 0xf0, 0xf1, 0xf2, 0x31},
- []segment{
- {
- dataModeNumeric,
- []byte{0x30},
- },
- {
- dataModeAlphanumeric,
- []byte{0x41, 0x42, 0x43, 0x20},
- },
- {
- dataModeByte,
- []byte{0x00, 0xf0, 0xf1, 0xf2},
- },
- {
- dataModeNumeric,
- []byte{0x31},
- },
- },
- },
- }
- for _, test := range tests {
- encoder := newDataEncoder(dataEncoderType1To9)
- encoder.encode(test.data)
- if !reflect.DeepEqual(test.actual, encoder.actual) {
- t.Errorf("Got %v, expected %v", encoder.actual, test.actual)
- }
- }
- }
- func TestByteModeLengthCalculations(t *testing.T) {
- tests := []struct {
- dataEncoderType dataEncoderType
- dataMode dataMode
- numSymbols int
- expectedLength int
- }{}
- for i, test := range tests {
- encoder := newDataEncoder(test.dataEncoderType)
- var resultLength int
- resultLength, err := encoder.encodedLength(test.dataMode, test.numSymbols)
- if test.expectedLength == -1 {
- if err == nil {
- t.Errorf("Test %d: got length %d, expected error", i, resultLength)
- }
- } else if resultLength != test.expectedLength {
- t.Errorf("Test %d: got length %d, expected length %d", i, resultLength,
- test.expectedLength)
- }
- }
- }
- func TestSingleModeEncodings(t *testing.T) {
- tests := []struct {
- dataEncoderType dataEncoderType
- dataMode dataMode
- data string
- expected *bitset.Bitset
- }{
- {
- dataEncoderType1To9,
- dataModeNumeric,
- "01234567",
- bitset.NewFromBase2String("0001 0000001000 0000001100 0101011001 1000011"),
- },
- {
- dataEncoderType1To9,
- dataModeAlphanumeric,
- "AC-42",
- bitset.NewFromBase2String("0010 000000101 00111001110 11100111001 000010"),
- },
- {
- dataEncoderType1To9,
- dataModeByte,
- "123",
- bitset.NewFromBase2String("0100 00000011 00110001 00110010 00110011"),
- },
- {
- dataEncoderType10To26,
- dataModeByte,
- "123",
- bitset.NewFromBase2String("0100 00000000 00000011 00110001 00110010 00110011"),
- },
- {
- dataEncoderType27To40,
- dataModeByte,
- "123",
- bitset.NewFromBase2String("0100 00000000 00000011 00110001 00110010 00110011"),
- },
- }
- for _, test := range tests {
- encoder := newDataEncoder(test.dataEncoderType)
- encoded := bitset.New()
- encoder.encodeDataRaw([]byte(test.data), test.dataMode, encoded)
- if !test.expected.Equals(encoded) {
- t.Errorf("For %s got %s, expected %s", test.data, encoded.String(),
- test.expected.String())
- }
- }
- }
- type testModeSegment struct {
- dataMode dataMode
- numChars int
- }
- func TestOptimiseEncoding(t *testing.T) {
- tests := []struct {
- dataEncoderType dataEncoderType
- actual []testModeSegment
- optimised []testModeSegment
- }{
- // Coalescing multiple segments.
- {
- dataEncoderType1To9,
- []testModeSegment{
- {dataModeAlphanumeric, 1}, // length = 4 + 9 + 6 = 19 bits
- {dataModeNumeric, 1}, // length = 4 + 10 + 4 = 18 bits
- {dataModeAlphanumeric, 1}, // 19 bits.
- {dataModeNumeric, 1}, // 18 bits.
- {dataModeAlphanumeric, 1}, // 19 bits.
- // total = 93 bits.
- },
- []testModeSegment{
- {dataModeAlphanumeric, 5}, // length = 4 + 9 + 22 + 6 = 41.
- },
- },
- // Coalesing not necessary.
- {
- dataEncoderType1To9,
- []testModeSegment{
- {dataModeAlphanumeric, 1},
- {dataModeNumeric, 20},
- },
- []testModeSegment{
- {dataModeAlphanumeric, 1},
- {dataModeNumeric, 20},
- },
- },
- // Switch to more general dataMode.
- {
- dataEncoderType1To9,
- []testModeSegment{
- {dataModeAlphanumeric, 1},
- {dataModeByte, 1},
- {dataModeNumeric, 1},
- },
- []testModeSegment{
- {dataModeAlphanumeric, 1},
- {dataModeByte, 2},
- },
- },
- // https://www.google.com/123
- // BBBBBAAABBBABBBBBBABBBANNN
- {
- dataEncoderType1To9,
- []testModeSegment{
- {dataModeByte, 5},
- {dataModeAlphanumeric, 3},
- {dataModeByte, 3},
- {dataModeAlphanumeric, 1},
- {dataModeByte, 6},
- {dataModeAlphanumeric, 1},
- {dataModeAlphanumeric, 4},
- {dataModeNumeric, 3},
- },
- []testModeSegment{
- {dataModeByte, 23},
- {dataModeNumeric, 3},
- },
- },
- // HTTPS://WWW.GOOGLE.COM/123
- // AAAAAAAAAAAAAAAAAAAAAAANNN
- {
- dataEncoderType1To9,
- []testModeSegment{
- {dataModeAlphanumeric, 23},
- {dataModeNumeric, 3},
- },
- []testModeSegment{
- {dataModeAlphanumeric, 26},
- },
- },
- {
- dataEncoderType27To40,
- []testModeSegment{
- {dataModeByte, 1},
- {dataModeNumeric, 1},
- {dataModeByte, 1},
- {dataModeNumeric, 1},
- {dataModeByte, 1},
- {dataModeNumeric, 1},
- {dataModeByte, 1},
- {dataModeNumeric, 1},
- },
- []testModeSegment{
- {dataModeByte, 8},
- },
- },
- }
- for _, test := range tests {
- numTotalChars := 0
- for _, v := range test.actual {
- numTotalChars += v.numChars
- }
- data := make([]byte, numTotalChars)
- i := 0
- for _, v := range test.actual {
- for j := 0; j < v.numChars; j++ {
- switch v.dataMode {
- case dataModeNumeric:
- data[i] = '1'
- case dataModeAlphanumeric:
- data[i] = 'A'
- case dataModeByte:
- data[i] = '#'
- default:
- t.Fatal("Unrecognised data mode")
- }
- i++
- }
- }
- encoder := newDataEncoder(test.dataEncoderType)
- _, err := encoder.encode(data)
- if err != nil {
- t.Errorf("Got %s, expected valid encoding", err.Error())
- } else {
- ok := true
- if len(encoder.optimised) != len(test.optimised) {
- ok = false
- } else {
- for i, s := range test.optimised {
- if encoder.optimised[i].dataMode != s.dataMode ||
- len(encoder.optimised[i].data) != s.numChars {
- ok = false
- break
- }
- }
- }
- if !ok {
- t.Errorf("got %s, expected %s", segmentsString(encoder.optimised),
- testModeSegmentsString(test.optimised))
- }
- }
- }
- }
- func testModeSegmentsString(segments []testModeSegment) string {
- result := "["
- for i, segment := range segments {
- if i > 0 {
- result += ", "
- }
- result += fmt.Sprintf("%d*%s", segment.numChars,
- dataModeString(segment.dataMode))
- }
- result += "]"
- return result
- }
- func segmentsString(segments []segment) string {
- result := "["
- for i, segment := range segments {
- if i > 0 {
- result += ", "
- }
- result += fmt.Sprintf("%d*%s", len(segment.data),
- dataModeString(segment.dataMode))
- }
- result += "]"
- return result
- }
|