transfer.sh/vendor/github.com/skip2/go-qrcode/encoder_test.go
2018-07-01 14:41:53 +02:00

328 lines
6.5 KiB
Go

// 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
}