1 | // Copyright 2013 The Go Authors. All rights reserved. |
---|---|
2 | // Use of this source code is governed by a BSD-style |
3 | // license that can be found in the LICENSE file. |
4 | |
5 | package vcs |
6 | |
7 | import ( |
8 | "errors" |
9 | "io/ioutil" |
10 | "os" |
11 | "path" |
12 | "path/filepath" |
13 | "reflect" |
14 | "runtime" |
15 | "strings" |
16 | "testing" |
17 | ) |
18 | |
19 | // Test that RepoRootForImportPath creates the correct RepoRoot for a given importPath. |
20 | // TODO(cmang): Add tests for SVN and BZR. |
21 | func TestRepoRootForImportPath(t *testing.T) { |
22 | if runtime.GOOS == "android" { |
23 | t.Skipf("incomplete source tree on %s", runtime.GOOS) |
24 | } |
25 | |
26 | tests := []struct { |
27 | path string |
28 | want *RepoRoot |
29 | }{ |
30 | { |
31 | "github.com/golang/groupcache", |
32 | &RepoRoot{ |
33 | VCS: vcsGit, |
34 | Repo: "https://github.com/golang/groupcache", |
35 | }, |
36 | }, |
37 | // Unicode letters in directories (issue 18660). |
38 | { |
39 | "github.com/user/unicode/испытание", |
40 | &RepoRoot{ |
41 | VCS: vcsGit, |
42 | Repo: "https://github.com/user/unicode", |
43 | }, |
44 | }, |
45 | } |
46 | |
47 | for _, test := range tests { |
48 | got, err := RepoRootForImportPath(test.path, false) |
49 | if err != nil { |
50 | t.Errorf("RepoRootForImportPath(%q): %v", test.path, err) |
51 | continue |
52 | } |
53 | want := test.want |
54 | if got.VCS.Name != want.VCS.Name || got.Repo != want.Repo { |
55 | t.Errorf("RepoRootForImportPath(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.VCS, got.Repo, want.VCS, want.Repo) |
56 | } |
57 | } |
58 | } |
59 | |
60 | // Test that FromDir correctly inspects a given directory and returns the right VCS and root. |
61 | func TestFromDir(t *testing.T) { |
62 | tempDir, err := ioutil.TempDir("", "vcstest") |
63 | if err != nil { |
64 | t.Fatal(err) |
65 | } |
66 | defer os.RemoveAll(tempDir) |
67 | |
68 | for j, vcs := range vcsList { |
69 | dir := filepath.Join(tempDir, "example.com", vcs.Name, "."+vcs.Cmd) |
70 | if j&1 == 0 { |
71 | err := os.MkdirAll(dir, 0755) |
72 | if err != nil { |
73 | t.Fatal(err) |
74 | } |
75 | } else { |
76 | err := os.MkdirAll(filepath.Dir(dir), 0755) |
77 | if err != nil { |
78 | t.Fatal(err) |
79 | } |
80 | f, err := os.Create(dir) |
81 | if err != nil { |
82 | t.Fatal(err) |
83 | } |
84 | f.Close() |
85 | } |
86 | |
87 | want := RepoRoot{ |
88 | VCS: vcs, |
89 | Root: path.Join("example.com", vcs.Name), |
90 | } |
91 | var got RepoRoot |
92 | got.VCS, got.Root, err = FromDir(dir, tempDir) |
93 | if err != nil { |
94 | t.Errorf("FromDir(%q, %q): %v", dir, tempDir, err) |
95 | continue |
96 | } |
97 | if got.VCS.Name != want.VCS.Name || got.Root != want.Root { |
98 | t.Errorf("FromDir(%q, %q) = VCS(%s) Root(%s), want VCS(%s) Root(%s)", dir, tempDir, got.VCS, got.Root, want.VCS, want.Root) |
99 | } |
100 | } |
101 | } |
102 | |
103 | var parseMetaGoImportsTests = []struct { |
104 | in string |
105 | out []metaImport |
106 | }{ |
107 | { |
108 | `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`, |
109 | []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}}, |
110 | }, |
111 | { |
112 | `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar"> |
113 | <meta name="go-import" content="baz/quux git http://github.com/rsc/baz/quux">`, |
114 | []metaImport{ |
115 | {"foo/bar", "git", "https://github.com/rsc/foo/bar"}, |
116 | {"baz/quux", "git", "http://github.com/rsc/baz/quux"}, |
117 | }, |
118 | }, |
119 | { |
120 | `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar"> |
121 | <meta name="go-import" content="foo/bar mod http://github.com/rsc/baz/quux">`, |
122 | []metaImport{ |
123 | {"foo/bar", "git", "https://github.com/rsc/foo/bar"}, |
124 | }, |
125 | }, |
126 | { |
127 | `<meta name="go-import" content="foo/bar mod http://github.com/rsc/baz/quux"> |
128 | <meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`, |
129 | []metaImport{ |
130 | {"foo/bar", "git", "https://github.com/rsc/foo/bar"}, |
131 | }, |
132 | }, |
133 | { |
134 | `<head> |
135 | <meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar"> |
136 | </head>`, |
137 | []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}}, |
138 | }, |
139 | { |
140 | `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar"> |
141 | <body>`, |
142 | []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}}, |
143 | }, |
144 | { |
145 | `<!doctype html><meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`, |
146 | []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}}, |
147 | }, |
148 | { |
149 | // XML doesn't like <div style=position:relative>. |
150 | `<!doctype html><title>Page Not Found</title><meta name=go-import content="chitin.io/chitin git https://github.com/chitin-io/chitin"><div style=position:relative>DRAFT</div>`, |
151 | []metaImport{{"chitin.io/chitin", "git", "https://github.com/chitin-io/chitin"}}, |
152 | }, |
153 | { |
154 | `<meta name="go-import" content="myitcv.io git https://github.com/myitcv/x"> |
155 | <meta name="go-import" content="myitcv.io/blah2 mod https://raw.githubusercontent.com/myitcv/pubx/master"> |
156 | `, |
157 | []metaImport{{"myitcv.io", "git", "https://github.com/myitcv/x"}}, |
158 | }, |
159 | } |
160 | |
161 | func TestParseMetaGoImports(t *testing.T) { |
162 | for i, tt := range parseMetaGoImportsTests { |
163 | out, err := parseMetaGoImports(strings.NewReader(tt.in)) |
164 | if err != nil { |
165 | t.Errorf("test#%d: %v", i, err) |
166 | continue |
167 | } |
168 | if !reflect.DeepEqual(out, tt.out) { |
169 | t.Errorf("test#%d:\n\thave %q\n\twant %q", i, out, tt.out) |
170 | } |
171 | } |
172 | } |
173 | |
174 | func TestValidateRepoRoot(t *testing.T) { |
175 | tests := []struct { |
176 | root string |
177 | ok bool |
178 | }{ |
179 | { |
180 | root: "", |
181 | ok: false, |
182 | }, |
183 | { |
184 | root: "http://", |
185 | ok: true, |
186 | }, |
187 | { |
188 | root: "git+ssh://", |
189 | ok: true, |
190 | }, |
191 | { |
192 | root: "http#://", |
193 | ok: false, |
194 | }, |
195 | { |
196 | root: "-config", |
197 | ok: false, |
198 | }, |
199 | { |
200 | root: "-config://", |
201 | ok: false, |
202 | }, |
203 | } |
204 | |
205 | for _, test := range tests { |
206 | err := validateRepoRoot(test.root) |
207 | ok := err == nil |
208 | if ok != test.ok { |
209 | want := "error" |
210 | if test.ok { |
211 | want = "nil" |
212 | } |
213 | t.Errorf("validateRepoRoot(%q) = %q, want %s", test.root, err, want) |
214 | } |
215 | } |
216 | } |
217 | |
218 | func TestMatchGoImport(t *testing.T) { |
219 | tests := []struct { |
220 | imports []metaImport |
221 | path string |
222 | mi metaImport |
223 | err error |
224 | }{ |
225 | { |
226 | imports: []metaImport{ |
227 | {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
228 | }, |
229 | path: "example.com/user/foo", |
230 | mi: metaImport{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
231 | }, |
232 | { |
233 | imports: []metaImport{ |
234 | {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
235 | }, |
236 | path: "example.com/user/foo/", |
237 | mi: metaImport{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
238 | }, |
239 | { |
240 | imports: []metaImport{ |
241 | {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
242 | {Prefix: "example.com/user/fooa", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
243 | }, |
244 | path: "example.com/user/foo", |
245 | mi: metaImport{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
246 | }, |
247 | { |
248 | imports: []metaImport{ |
249 | {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
250 | {Prefix: "example.com/user/fooa", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
251 | }, |
252 | path: "example.com/user/fooa", |
253 | mi: metaImport{Prefix: "example.com/user/fooa", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
254 | }, |
255 | { |
256 | imports: []metaImport{ |
257 | {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
258 | {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
259 | }, |
260 | path: "example.com/user/foo/bar", |
261 | err: errors.New("should not be allowed to create nested repo"), |
262 | }, |
263 | { |
264 | imports: []metaImport{ |
265 | {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
266 | {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
267 | }, |
268 | path: "example.com/user/foo/bar/baz", |
269 | err: errors.New("should not be allowed to create nested repo"), |
270 | }, |
271 | { |
272 | imports: []metaImport{ |
273 | {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
274 | {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
275 | }, |
276 | path: "example.com/user/foo/bar/baz/qux", |
277 | err: errors.New("should not be allowed to create nested repo"), |
278 | }, |
279 | { |
280 | imports: []metaImport{ |
281 | {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
282 | {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
283 | }, |
284 | path: "example.com/user/foo/bar/baz/", |
285 | err: errors.New("should not be allowed to create nested repo"), |
286 | }, |
287 | { |
288 | imports: []metaImport{ |
289 | {Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
290 | {Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"}, |
291 | }, |
292 | path: "example.com", |
293 | err: errors.New("pathologically short path"), |
294 | }, |
295 | } |
296 | |
297 | for _, test := range tests { |
298 | mi, err := matchGoImport(test.imports, test.path) |
299 | if mi != test.mi { |
300 | t.Errorf("unexpected metaImport; got %v, want %v", mi, test.mi) |
301 | } |
302 | |
303 | got := err |
304 | want := test.err |
305 | if (got == nil) != (want == nil) { |
306 | t.Errorf("unexpected error; got %v, want %v", got, want) |
307 | } |
308 | } |
309 | } |
310 |
Members