blob: a2b58185b7529de400d2f7ef1932f6b1490a7e30 [file] [log] [blame]
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package label_test
import (
"bytes"
"fmt"
"runtime"
"testing"
"unsafe"
"golang.org/x/tools/internal/event/keys"
"golang.org/x/tools/internal/event/label"
)
var (
AKey = keys.NewString("A", "")
BKey = keys.NewString("B", "")
CKey = keys.NewString("C", "")
A = AKey.Of("a")
B = BKey.Of("b")
C = CKey.Of("c")
all = []label.Label{A, B, C}
)
func TestList(t *testing.T) {
for _, test := range []struct {
name string
labels []label.Label
expect string
}{{
name: "empty",
}, {
name: "single",
labels: []label.Label{A},
expect: `A="a"`,
}, {
name: "invalid",
labels: []label.Label{{}},
expect: ``,
}, {
name: "two",
labels: []label.Label{A, B},
expect: `A="a", B="b"`,
}, {
name: "three",
labels: []label.Label{A, B, C},
expect: `A="a", B="b", C="c"`,
}, {
name: "missing A",
labels: []label.Label{{}, B, C},
expect: `B="b", C="c"`,
}, {
name: "missing B",
labels: []label.Label{A, {}, C},
expect: `A="a", C="c"`,
}, {
name: "missing C",
labels: []label.Label{A, B, {}},
expect: `A="a", B="b"`,
}, {
name: "missing AB",
labels: []label.Label{{}, {}, C},
expect: `C="c"`,
}, {
name: "missing AC",
labels: []label.Label{{}, B, {}},
expect: `B="b"`,
}, {
name: "missing BC",
labels: []label.Label{A, {}, {}},
expect: `A="a"`,
}} {
t.Run(test.name, func(t *testing.T) {
got := printList(label.NewList(test.labels...))
if got != test.expect {
t.Errorf("got %q want %q", got, test.expect)
}
})
}
}
func TestFilter(t *testing.T) {
for _, test := range []struct {
name string
labels []label.Label
filters []label.Key
expect string
}{{
name: "no filters",
labels: all,
expect: `A="a", B="b", C="c"`,
}, {
name: "no labels",
filters: []label.Key{AKey},
expect: ``,
}, {
name: "filter A",
labels: all,
filters: []label.Key{AKey},
expect: `B="b", C="c"`,
}, {
name: "filter B",
labels: all,
filters: []label.Key{BKey},
expect: `A="a", C="c"`,
}, {
name: "filter C",
labels: all,
filters: []label.Key{CKey},
expect: `A="a", B="b"`,
}, {
name: "filter AC",
labels: all,
filters: []label.Key{AKey, CKey},
expect: `B="b"`,
}} {
t.Run(test.name, func(t *testing.T) {
labels := label.NewList(test.labels...)
got := printList(label.Filter(labels, test.filters...))
if got != test.expect {
t.Errorf("got %q want %q", got, test.expect)
}
})
}
}
func TestMap(t *testing.T) {
for _, test := range []struct {
name string
labels []label.Label
keys []label.Key
expect string
}{{
name: "no labels",
keys: []label.Key{AKey},
expect: `nil`,
}, {
name: "match A",
labels: all,
keys: []label.Key{AKey},
expect: `A="a"`,
}, {
name: "match B",
labels: all,
keys: []label.Key{BKey},
expect: `B="b"`,
}, {
name: "match C",
labels: all,
keys: []label.Key{CKey},
expect: `C="c"`,
}, {
name: "match ABC",
labels: all,
keys: []label.Key{AKey, BKey, CKey},
expect: `A="a", B="b", C="c"`,
}, {
name: "missing A",
labels: []label.Label{{}, B, C},
keys: []label.Key{AKey, BKey, CKey},
expect: `nil, B="b", C="c"`,
}, {
name: "missing B",
labels: []label.Label{A, {}, C},
keys: []label.Key{AKey, BKey, CKey},
expect: `A="a", nil, C="c"`,
}, {
name: "missing C",
labels: []label.Label{A, B, {}},
keys: []label.Key{AKey, BKey, CKey},
expect: `A="a", B="b", nil`,
}} {
t.Run(test.name, func(t *testing.T) {
lm := label.NewMap(test.labels...)
got := printMap(lm, test.keys)
if got != test.expect {
t.Errorf("got %q want %q", got, test.expect)
}
})
}
}
func TestMapMerge(t *testing.T) {
for _, test := range []struct {
name string
maps []label.Map
keys []label.Key
expect string
}{{
name: "no maps",
keys: []label.Key{AKey},
expect: `nil`,
}, {
name: "one map",
maps: []label.Map{label.NewMap(all...)},
keys: []label.Key{AKey},
expect: `A="a"`,
}, {
name: "invalid map",
maps: []label.Map{label.NewMap()},
keys: []label.Key{AKey},
expect: `nil`,
}, {
name: "two maps",
maps: []label.Map{label.NewMap(B, C), label.NewMap(A)},
keys: []label.Key{AKey, BKey, CKey},
expect: `A="a", B="b", C="c"`,
}, {
name: "invalid start map",
maps: []label.Map{label.NewMap(), label.NewMap(B, C)},
keys: []label.Key{AKey, BKey, CKey},
expect: `nil, B="b", C="c"`,
}, {
name: "invalid mid map",
maps: []label.Map{label.NewMap(A), label.NewMap(), label.NewMap(C)},
keys: []label.Key{AKey, BKey, CKey},
expect: `A="a", nil, C="c"`,
}, {
name: "invalid end map",
maps: []label.Map{label.NewMap(A, B), label.NewMap()},
keys: []label.Key{AKey, BKey, CKey},
expect: `A="a", B="b", nil`,
}, {
name: "three maps one nil",
maps: []label.Map{label.NewMap(A), label.NewMap(B), nil},
keys: []label.Key{AKey, BKey, CKey},
expect: `A="a", B="b", nil`,
}, {
name: "two maps one nil",
maps: []label.Map{label.NewMap(A, B), nil},
keys: []label.Key{AKey, BKey, CKey},
expect: `A="a", B="b", nil`,
}} {
t.Run(test.name, func(t *testing.T) {
tagMap := label.MergeMaps(test.maps...)
got := printMap(tagMap, test.keys)
if got != test.expect {
t.Errorf("got %q want %q", got, test.expect)
}
})
}
}
func printList(list label.List) string {
buf := &bytes.Buffer{}
for index := 0; list.Valid(index); index++ {
l := list.Label(index)
if !l.Valid() {
continue
}
if buf.Len() > 0 {
buf.WriteString(", ")
}
fmt.Fprint(buf, l)
}
return buf.String()
}
func printMap(lm label.Map, keys []label.Key) string {
buf := &bytes.Buffer{}
for _, key := range keys {
if buf.Len() > 0 {
buf.WriteString(", ")
}
fmt.Fprint(buf, lm.Find(key))
}
return buf.String()
}
func TestAttemptedStringCorruption(t *testing.T) {
defer func() {
r := recover()
if _, ok := r.(*runtime.TypeAssertionError); !ok {
t.Fatalf("wanted to recover TypeAssertionError, got %T", r)
}
}()
var x uint64 = 12390
p := unsafe.Pointer(&x)
l := label.OfValue(AKey, p)
_ = l.UnpackString()
}