gecko/ids/id_test.go

219 lines
5.2 KiB
Go

// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package ids
import (
"bytes"
"reflect"
"testing"
)
func TestID(t *testing.T) {
hash := [32]byte{24}
id := NewID(hash)
if key := id.Key(); !bytes.Equal(hash[:], key[:]) {
t.Fatalf("ID.Key returned wrong bytes")
}
prefixed := id.Prefix(0)
if key := id.Key(); !bytes.Equal(hash[:], key[:]) {
t.Fatalf("ID.Prefix mutated the ID")
}
if nextPrefix := id.Prefix(0); !prefixed.Equals(nextPrefix) {
t.Fatalf("ID.Prefix not consistant")
}
if b := id.Bytes(); !bytes.Equal(hash[:], b) {
t.Fatalf("ID.Bytes returned wrong bytes")
}
}
func TestIDBit(t *testing.T) {
id0 := NewID([32]byte{1 << 0})
id1 := NewID([32]byte{1 << 1})
id2 := NewID([32]byte{1 << 2})
id3 := NewID([32]byte{1 << 3})
id4 := NewID([32]byte{1 << 4})
id5 := NewID([32]byte{1 << 5})
id6 := NewID([32]byte{1 << 6})
id7 := NewID([32]byte{1 << 7})
id8 := NewID([32]byte{0, 1 << 0})
if id0.Bit(0) != 1 {
t.Fatalf("Wrong bit")
} else if id1.Bit(1) != 1 {
t.Fatalf("Wrong bit")
} else if id2.Bit(2) != 1 {
t.Fatalf("Wrong bit")
} else if id3.Bit(3) != 1 {
t.Fatalf("Wrong bit")
} else if id4.Bit(4) != 1 {
t.Fatalf("Wrong bit")
} else if id5.Bit(5) != 1 {
t.Fatalf("Wrong bit")
} else if id6.Bit(6) != 1 {
t.Fatalf("Wrong bit")
} else if id7.Bit(7) != 1 {
t.Fatalf("Wrong bit")
} else if id8.Bit(8) != 1 {
t.Fatalf("Wrong bit")
}
}
func TestFromString(t *testing.T) {
key := [32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}
id := NewID(key)
idStr := id.String()
id2, err := FromString(idStr)
if err != nil {
t.Fatal(err)
}
if id.Key() != id2.Key() {
t.Fatal("Expected FromString to be inverse of String but it wasn't")
}
}
func TestIDFromStringError(t *testing.T) {
tests := []struct {
in string
}{
{""},
{"foo"},
{"foobar"},
}
for _, tt := range tests {
t.Run(tt.in, func(t *testing.T) {
_, err := FromString(tt.in)
if err == nil {
t.Error("Unexpected success")
}
})
}
}
func TestIDMarshalJSON(t *testing.T) {
tests := []struct {
label string
in ID
out []byte
err error
}{
{"ID{}", ID{}, []byte("null"), nil},
{"ID(\"ava labs\")",
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
[]byte("\"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7\""),
nil,
},
}
for _, tt := range tests {
t.Run(tt.label, func(t *testing.T) {
out, err := tt.in.MarshalJSON()
if err != tt.err {
t.Errorf("Expected err %s, got error %v", tt.err, err)
} else if !bytes.Equal(out, tt.out) {
t.Errorf("got %q, expected %q", out, tt.out)
}
})
}
}
func TestIDUnmarshalJSON(t *testing.T) {
tests := []struct {
label string
in []byte
out ID
err error
}{
{"ID{}", []byte("null"), ID{}, nil},
{"ID(\"ava labs\")",
[]byte("\"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7\""),
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
nil,
},
}
for _, tt := range tests {
t.Run(tt.label, func(t *testing.T) {
foo := ID{}
err := foo.UnmarshalJSON(tt.in)
if err != tt.err {
t.Errorf("Expected err %s, got error %v", tt.err, err)
} else if foo.ID != nil && foo.Key() != tt.out.Key() {
t.Errorf("got %q, expected %q", foo.Key(), tt.out.Key())
}
})
}
}
func TestIDHex(t *testing.T) {
id := NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'})
expected := "617661206c616273000000000000000000000000000000000000000000000000"
actual := id.Hex()
if actual != expected {
t.Fatalf("got %s, expected %s", actual, expected)
}
}
func TestIDString(t *testing.T) {
tests := []struct {
label string
id ID
expected string
}{
{"ID{}", ID{}, "nil"},
{"ID{[32]byte{24}}", NewID([32]byte{24}), "Ba3mm8Ra8JYYebeZ9p7zw1ayorDbeD1euwxhgzSLsncKqGoNt"},
}
for _, tt := range tests {
t.Run(tt.label, func(t *testing.T) {
result := tt.id.String()
if result != tt.expected {
t.Errorf("got %q, expected %q", result, tt.expected)
}
})
}
}
func TestSortIDs(t *testing.T) {
ids := []ID{
NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
NewID([32]byte{'W', 'a', 'l', 'l', 'e', ' ', 'l', 'a', 'b', 's'}),
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
}
SortIDs(ids)
expected := []ID{
NewID([32]byte{'W', 'a', 'l', 'l', 'e', ' ', 'l', 'a', 'b', 's'}),
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
}
if !reflect.DeepEqual(ids, expected) {
t.Fatal("[]ID was not sorted lexographically")
}
}
func TestIsSortedAndUnique(t *testing.T) {
unsorted := []ID{
NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
}
if IsSortedAndUniqueIDs(unsorted) {
t.Fatal("Wrongly accepted unsorted IDs")
}
duplicated := []ID{
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
}
if IsSortedAndUniqueIDs(duplicated) {
t.Fatal("Wrongly accepted duplicated IDs")
}
sorted := []ID{
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
}
if !IsSortedAndUniqueIDs(sorted) {
t.Fatal("Wrongly rejected sorted, unique IDs")
}
}