1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
package buildtags
import "testing"
func TestGoString(t *testing.T) {
cases := []struct {
Constraint Interface
Expect string
}{
{Term("amd64"), "// +build amd64\n"},
{Any(Opt(Term("linux"), Term("386")), Opt("darwin", Not("cgo"))), "// +build linux,386 darwin,!cgo\n"},
{And(Any(Term("linux"), Term("darwin")), Term("386")), "// +build linux darwin\n// +build 386\n"},
}
for _, c := range cases {
got := c.Constraint.ToConstraints().GoString()
if got != c.Expect {
t.Errorf("constraint %#v GoString() got %q; expected %q", c.Constraint, got, c.Expect)
}
}
}
func TestValidateOK(t *testing.T) {
cases := []Interface{
Term("name"),
Term("!name"),
}
for _, c := range cases {
if err := c.ToConstraints().Validate(); err != nil {
t.Errorf("unexpected validation error for %#v: %q", c, err)
}
}
}
func TestValidateErrors(t *testing.T) {
cases := []struct {
Constraint Interface
ExpectMessage string
}{
{Term(""), "empty tag name"},
{Term("!"), "empty tag name"},
{Term("!!"), "at most one '!' allowed"},
{Term("!abc!def"), "character '!' disallowed in tags"},
{
And(Any(Term("linux"), Term("my-os")), Term("386")).ToConstraints(),
"invalid term \"my-os\": character '-' disallowed in tags",
},
}
for _, c := range cases {
err := c.Constraint.Validate()
if err == nil {
t.Fatalf("expect validation error for constraint:\n%s", c.Constraint.GoString())
}
if err.Error() != c.ExpectMessage {
t.Fatalf("unexpected error message\n\tgot:\t%q\n\texpect:\t%q\n", err, c.ExpectMessage)
}
}
}
func TestParseConstraintRoundTrip(t *testing.T) {
exprs := []string{
"amd64",
"amd64,linux",
"!a",
"!a,b c,!d,e",
"linux,386 darwin,!cgo",
}
for _, expr := range exprs {
c := AssertParseConstraint(t, expr)
got := c.GoString()
expect := "// +build " + expr + "\n"
if got != expect {
t.Fatalf("roundtrip error\n\tgot\t%q\n\texpect\t%q\n", got, expect)
}
}
}
func TestParseConstraintError(t *testing.T) {
expr := "linux,386 my-os,!cgo"
_, err := ParseConstraint(expr)
if err == nil {
t.Fatalf("expected error parsing %q", expr)
}
}
func TestEvaluate(t *testing.T) {
cases := []struct {
Constraint Interface
Values map[string]bool
Expect bool
}{
{Term("a"), SetTags("a"), true},
{Term("!a"), SetTags("a"), false},
{Term("!a"), SetTags(), true},
{Term("inval-id"), SetTags("inval-id"), false},
{Opt(Term("a"), Term("b")), SetTags(), false},
{Opt(Term("a"), Term("b")), SetTags("a"), false},
{Opt(Term("a"), Term("b")), SetTags("b"), false},
{Opt(Term("a"), Term("b")), SetTags("a", "b"), true},
{Opt(Term("a"), Term("b-a-d")), SetTags("a", "b-a-d"), false},
{
Any(Opt(Term("linux"), Term("386")), Opt("darwin", Not("cgo"))),
SetTags("linux", "386"),
true,
},
{
Any(Opt(Term("linux"), Term("386")), Opt("darwin", Not("cgo"))),
SetTags("darwin"),
true,
},
{
Any(Opt(Term("linux"), Term("386")), Opt("darwin", Not("cgo"))),
SetTags("linux", "darwin", "cgo"),
false,
},
{
And(Any(Term("linux"), Term("darwin")), Term("386")),
SetTags("darwin", "386"),
true,
},
}
for _, c := range cases {
got := c.Constraint.Evaluate(c.Values)
if c.Constraint.Validate() != nil && got {
t.Fatal("invalid expressions must evaluate false")
}
if got != c.Expect {
t.Errorf("%#v evaluated with %#v got %v expect %v", c.Constraint, c.Values, got, c.Expect)
}
}
}
func AssertParseConstraint(t *testing.T, expr string) Constraint {
t.Helper()
c, err := ParseConstraint(expr)
if err != nil {
t.Fatalf("error parsing expression %q: %q", expr, err)
}
return c
}
|