blob: 3dbab9388311d8c22516a7a0c7e8053ea0bb061a [file] [log] [blame]
Marcel van Lohuizenbc4d65d2018-12-10 15:40:02 +01001// Copyright 2018 The CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package load
16
17import (
18 "io"
19 "reflect"
20 "strings"
21 "testing"
22)
23
24func TestMatch(t *testing.T) {
25 c := &Config{}
26 what := "default"
27 matchFn := func(tag string, want map[string]bool) {
28 t.Helper()
29 m := make(map[string]bool)
30 if !doMatch(c, tag, m) {
31 t.Errorf("%s context should match %s, does not", what, tag)
32 }
33 if !reflect.DeepEqual(m, want) {
34 t.Errorf("%s tags = %v, want %v", tag, m, want)
35 }
36 }
37 noMatch := func(tag string, want map[string]bool) {
38 m := make(map[string]bool)
39 if doMatch(c, tag, m) {
40 t.Errorf("%s context should NOT match %s, does", what, tag)
41 }
42 if !reflect.DeepEqual(m, want) {
43 t.Errorf("%s tags = %v, want %v", tag, m, want)
44 }
45 }
46
47 c.BuildTags = []string{"foo"}
48 matchFn("foo", map[string]bool{"foo": true})
49 noMatch("!foo", map[string]bool{"foo": true})
50 matchFn("foo,!bar", map[string]bool{"foo": true, "bar": true})
51 noMatch("!", map[string]bool{})
52}
53
54func TestShouldBuild(t *testing.T) {
55 const file1 = "// +build tag1\n\n" +
56 "package main\n"
57 want1 := map[string]bool{"tag1": true}
58
59 const file2 = "// +build cgo\n\n" +
60 "// This package implements parsing of tags like\n" +
61 "// +build tag1\n" +
62 "package load"
63 want2 := map[string]bool{"cgo": true}
64
65 const file3 = "// Copyright The CUE Authors.\n\n" +
66 "package load\n\n" +
67 "// shouldBuild checks tags given by lines of the form\n" +
68 "// +build tag\n" +
69 "func shouldBuild(content []byte)\n"
70 want3 := map[string]bool{}
71
72 c := &Config{BuildTags: []string{"tag1"}}
73 m := map[string]bool{}
74 if !shouldBuild(c, []byte(file1), m) {
75 t.Errorf("shouldBuild(file1) = false, want true")
76 }
77 if !reflect.DeepEqual(m, want1) {
78 t.Errorf("shouldBuild(file1) tags = %v, want %v", m, want1)
79 }
80
81 m = map[string]bool{}
82 if shouldBuild(c, []byte(file2), m) {
83 t.Errorf("shouldBuild(file2) = true, want false")
84 }
85 if !reflect.DeepEqual(m, want2) {
86 t.Errorf("shouldBuild(file2) tags = %v, want %v", m, want2)
87 }
88
89 m = map[string]bool{}
90 c = &Config{BuildTags: nil}
91 if !shouldBuild(c, []byte(file3), m) {
92 t.Errorf("shouldBuild(file3) = false, want true")
93 }
94 if !reflect.DeepEqual(m, want3) {
95 t.Errorf("shouldBuild(file3) tags = %v, want %v", m, want3)
96 }
97}
98
99type readNopCloser struct {
100 io.Reader
101}
102
103func (r readNopCloser) Close() error {
104 return nil
105}
106
107var (
108 cfg = &Config{BuildTags: []string{"enable"}}
109 defCfg = &Config{}
110)
111
112var matchFileTests = []struct {
113 cfg *Config
114 name string
115 data string
116 match bool
117}{
118 {defCfg, "foo.cue", "", true},
119 {defCfg, "foo.cue", "// +build enable\n\npackage foo\n", false},
120 {defCfg, "foo.cue", "// +build !enable\n\npackage foo\n", true},
121 {defCfg, "foo1.cue", "// +build linux\n\npackage foo\n", false},
122 {defCfg, "foo.badsuffix", "", false},
123 {cfg, "foo.cue", "// +build enable\n\npackage foo\n", true},
124 {cfg, "foo.cue", "// +build !enable\n\npackage foo\n", false},
125}
126
127func TestMatchFile(t *testing.T) {
128 for _, tt := range matchFileTests {
129 ctxt := &tt.cfg.fileSystem
130 ctxt.OpenFile = func(path string) (r io.ReadCloser, err error) {
131 if path != "x+"+tt.name {
132 t.Fatalf("OpenFile asked for %q, expected %q", path, "x+"+tt.name)
133 }
134 return &readNopCloser{strings.NewReader(tt.data)}, nil
135 }
136 ctxt.JoinPath = func(elem ...string) string {
137 return strings.Join(elem, "+")
138 }
139 match, err := matchFileTest(tt.cfg, "x", tt.name)
140 if match != tt.match || err != nil {
141 t.Fatalf("MatchFile(%q) = %v, %v, want %v, nil", tt.name, match, err, tt.match)
142 }
143 }
144}