Files
multibase/spec_test.go
Jorropo 0bd72a8c32 submodule: spec/
The spec submodule was on a 2 year old commit and the tests structure 
changed, this bring it to the latest master at this time.
2022-06-09 15:18:49 +10:00

148 lines
3.3 KiB
Go

package multibase
import (
"encoding/csv"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"unicode/utf8"
)
func TestSpec(t *testing.T) {
file, err := os.Open("spec/multibase.csv")
if err != nil {
t.Fatal(err)
}
defer file.Close()
reader := csv.NewReader(file)
reader.LazyQuotes = false
reader.FieldsPerRecord = 4
reader.TrimLeadingSpace = true
values, err := reader.ReadAll()
if err != nil {
t.Error(err)
}
expectedEncodings := make(map[Encoding]string, len(values)-1)
for _, v := range values[1:] {
encoding := v[0]
codeStr := v[1]
var code Encoding
if strings.HasPrefix(codeStr, "0x") {
i, err := strconv.ParseUint(codeStr[2:], 16, 64)
if err != nil {
t.Errorf("invalid multibase byte %q", codeStr)
continue
}
code = Encoding(i)
} else {
codeRune, length := utf8.DecodeRuneInString(codeStr)
if code == utf8.RuneError {
t.Errorf("multibase %q wasn't valid utf8", codeStr)
continue
}
if length != len(codeStr) {
t.Errorf("multibase %q wasn't a single character", codeStr)
continue
}
code = Encoding(codeRune)
}
expectedEncodings[code] = encoding
}
for name, enc := range Encodings {
expectedName, ok := expectedEncodings[enc]
if !ok {
t.Errorf("encoding %q (%c) not defined in the spec", name, enc)
continue
}
if expectedName != name {
t.Errorf("encoding %q (%c) has unexpected name %q", expectedName, enc, name)
}
}
}
func TestSpecVectors(t *testing.T) {
files, err := filepath.Glob("spec/tests/*.csv")
if err != nil {
t.Fatal(err)
}
for _, fname := range files {
t.Run(fname, func(t *testing.T) {
file, err := os.Open(fname)
if err != nil {
t.Error(err)
return
}
defer file.Close()
reader := csv.NewReader(file)
reader.LazyQuotes = false
reader.FieldsPerRecord = 2
reader.TrimLeadingSpace = true
values, err := reader.ReadAll()
if err != nil {
t.Error(err)
}
if len(values) == 0 {
t.Error("no test values")
return
}
header := values[0]
var decodeOnly bool
switch header[0] {
case "encoding":
case "non-canonical encoding":
decodeOnly = true
default:
t.Errorf("invalid test spec %q", fname)
return
}
testValue, err := strconv.Unquote("\"" + header[1] + "\"")
if err != nil {
t.Error("failed to unquote testcase:", err)
return
}
for _, testCase := range values[1:] {
encodingName := testCase[0]
expected := testCase[1]
t.Run(encodingName, func(t *testing.T) {
encoder, err := EncoderByName(encodingName)
if err != nil {
t.Skipf("skipping %s: not supported", encodingName)
return
}
if !decodeOnly {
t.Logf("encoding %q with %s", testValue, encodingName)
actual := encoder.Encode([]byte(testValue))
if expected != actual {
t.Errorf("expected %q, got %q", expected, actual)
}
}
t.Logf("decoding %q", expected)
encoding, decoded, err := Decode(expected)
if err != nil {
t.Error("failed to decode:", err)
return
}
expectedEncoding := Encodings[encodingName]
if encoding != expectedEncoding {
t.Errorf("expected encoding to be %c, got %c", expectedEncoding, encoding)
}
if string(decoded) != testValue {
t.Errorf("failed to decode %q to %q, got %q", expected, testValue, string(decoded))
}
})
}
})
}
}