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 astutil |
6 | |
7 | import ( |
8 | "bytes" |
9 | "go/ast" |
10 | "go/format" |
11 | "go/parser" |
12 | "go/token" |
13 | "reflect" |
14 | "strconv" |
15 | "testing" |
16 | ) |
17 | |
18 | var fset = token.NewFileSet() |
19 | |
20 | func parse(t *testing.T, name, in string) *ast.File { |
21 | file, err := parser.ParseFile(fset, name, in, parser.ParseComments) |
22 | if err != nil { |
23 | t.Fatalf("%s parse: %v", name, err) |
24 | } |
25 | return file |
26 | } |
27 | |
28 | func print(t *testing.T, name string, f *ast.File) string { |
29 | var buf bytes.Buffer |
30 | if err := format.Node(&buf, fset, f); err != nil { |
31 | t.Fatalf("%s gofmt: %v", name, err) |
32 | } |
33 | return buf.String() |
34 | } |
35 | |
36 | type test struct { |
37 | name string |
38 | renamedPkg string |
39 | pkg string |
40 | in string |
41 | out string |
42 | unchanged bool // Expect added/deleted return value to be false. |
43 | } |
44 | |
45 | var addTests = []test{ |
46 | { |
47 | name: "leave os alone", |
48 | pkg: "os", |
49 | in: `package main |
50 | |
51 | import ( |
52 | "os" |
53 | ) |
54 | `, |
55 | out: `package main |
56 | |
57 | import ( |
58 | "os" |
59 | ) |
60 | `, |
61 | unchanged: true, |
62 | }, |
63 | { |
64 | name: "import.1", |
65 | pkg: "os", |
66 | in: `package main |
67 | `, |
68 | out: `package main |
69 | |
70 | import "os" |
71 | `, |
72 | }, |
73 | { |
74 | name: "import.2", |
75 | pkg: "os", |
76 | in: `package main |
77 | |
78 | // Comment |
79 | import "C" |
80 | `, |
81 | out: `package main |
82 | |
83 | // Comment |
84 | import "C" |
85 | import "os" |
86 | `, |
87 | }, |
88 | { |
89 | name: "import.3", |
90 | pkg: "os", |
91 | in: `package main |
92 | |
93 | // Comment |
94 | import "C" |
95 | |
96 | import ( |
97 | "io" |
98 | "utf8" |
99 | ) |
100 | `, |
101 | out: `package main |
102 | |
103 | // Comment |
104 | import "C" |
105 | |
106 | import ( |
107 | "io" |
108 | "os" |
109 | "utf8" |
110 | ) |
111 | `, |
112 | }, |
113 | { |
114 | name: "import.17", |
115 | pkg: "x/y/z", |
116 | in: `package main |
117 | |
118 | // Comment |
119 | import "C" |
120 | |
121 | import ( |
122 | "a" |
123 | "b" |
124 | |
125 | "x/w" |
126 | |
127 | "d/f" |
128 | ) |
129 | `, |
130 | out: `package main |
131 | |
132 | // Comment |
133 | import "C" |
134 | |
135 | import ( |
136 | "a" |
137 | "b" |
138 | |
139 | "x/w" |
140 | "x/y/z" |
141 | |
142 | "d/f" |
143 | ) |
144 | `, |
145 | }, |
146 | { |
147 | name: "issue #19190", |
148 | pkg: "x.org/y/z", |
149 | in: `package main |
150 | |
151 | // Comment |
152 | import "C" |
153 | |
154 | import ( |
155 | "bytes" |
156 | "os" |
157 | |
158 | "d.com/f" |
159 | ) |
160 | `, |
161 | out: `package main |
162 | |
163 | // Comment |
164 | import "C" |
165 | |
166 | import ( |
167 | "bytes" |
168 | "os" |
169 | |
170 | "d.com/f" |
171 | "x.org/y/z" |
172 | ) |
173 | `, |
174 | }, |
175 | { |
176 | name: "issue #19190 with existing grouped import packages", |
177 | pkg: "x.org/y/z", |
178 | in: `package main |
179 | |
180 | // Comment |
181 | import "C" |
182 | |
183 | import ( |
184 | "bytes" |
185 | "os" |
186 | |
187 | "c.com/f" |
188 | "d.com/f" |
189 | |
190 | "y.com/a" |
191 | "y.com/b" |
192 | "y.com/c" |
193 | ) |
194 | `, |
195 | out: `package main |
196 | |
197 | // Comment |
198 | import "C" |
199 | |
200 | import ( |
201 | "bytes" |
202 | "os" |
203 | |
204 | "c.com/f" |
205 | "d.com/f" |
206 | "x.org/y/z" |
207 | |
208 | "y.com/a" |
209 | "y.com/b" |
210 | "y.com/c" |
211 | ) |
212 | `, |
213 | }, |
214 | { |
215 | name: "issue #19190 - match score is still respected", |
216 | pkg: "y.org/c", |
217 | in: `package main |
218 | |
219 | import ( |
220 | "x.org/a" |
221 | |
222 | "y.org/b" |
223 | ) |
224 | `, |
225 | out: `package main |
226 | |
227 | import ( |
228 | "x.org/a" |
229 | |
230 | "y.org/b" |
231 | "y.org/c" |
232 | ) |
233 | `, |
234 | }, |
235 | { |
236 | name: "import into singular group", |
237 | pkg: "bytes", |
238 | in: `package main |
239 | |
240 | import "os" |
241 | |
242 | `, |
243 | out: `package main |
244 | |
245 | import ( |
246 | "bytes" |
247 | "os" |
248 | ) |
249 | `, |
250 | }, |
251 | { |
252 | name: "import into singular group with comment", |
253 | pkg: "bytes", |
254 | in: `package main |
255 | |
256 | import /* why */ /* comment here? */ "os" |
257 | |
258 | `, |
259 | out: `package main |
260 | |
261 | import /* why */ /* comment here? */ ( |
262 | "bytes" |
263 | "os" |
264 | ) |
265 | `, |
266 | }, |
267 | { |
268 | name: "import into group with leading comment", |
269 | pkg: "strings", |
270 | in: `package main |
271 | |
272 | import ( |
273 | // comment before bytes |
274 | "bytes" |
275 | "os" |
276 | ) |
277 | |
278 | `, |
279 | out: `package main |
280 | |
281 | import ( |
282 | // comment before bytes |
283 | "bytes" |
284 | "os" |
285 | "strings" |
286 | ) |
287 | `, |
288 | }, |
289 | { |
290 | name: "", |
291 | renamedPkg: "fmtpkg", |
292 | pkg: "fmt", |
293 | in: `package main |
294 | |
295 | import "os" |
296 | |
297 | `, |
298 | out: `package main |
299 | |
300 | import ( |
301 | fmtpkg "fmt" |
302 | "os" |
303 | ) |
304 | `, |
305 | }, |
306 | { |
307 | name: "struct comment", |
308 | pkg: "time", |
309 | in: `package main |
310 | |
311 | // This is a comment before a struct. |
312 | type T struct { |
313 | t time.Time |
314 | } |
315 | `, |
316 | out: `package main |
317 | |
318 | import "time" |
319 | |
320 | // This is a comment before a struct. |
321 | type T struct { |
322 | t time.Time |
323 | } |
324 | `, |
325 | }, |
326 | { |
327 | name: "issue 8729 import C", |
328 | pkg: "time", |
329 | in: `package main |
330 | |
331 | import "C" |
332 | |
333 | // comment |
334 | type T time.Time |
335 | `, |
336 | out: `package main |
337 | |
338 | import "C" |
339 | import "time" |
340 | |
341 | // comment |
342 | type T time.Time |
343 | `, |
344 | }, |
345 | { |
346 | name: "issue 8729 empty import", |
347 | pkg: "time", |
348 | in: `package main |
349 | |
350 | import () |
351 | |
352 | // comment |
353 | type T time.Time |
354 | `, |
355 | out: `package main |
356 | |
357 | import "time" |
358 | |
359 | // comment |
360 | type T time.Time |
361 | `, |
362 | }, |
363 | { |
364 | name: "issue 8729 comment on package line", |
365 | pkg: "time", |
366 | in: `package main // comment |
367 | |
368 | type T time.Time |
369 | `, |
370 | out: `package main // comment |
371 | |
372 | import "time" |
373 | |
374 | type T time.Time |
375 | `, |
376 | }, |
377 | { |
378 | name: "issue 8729 comment after package", |
379 | pkg: "time", |
380 | in: `package main |
381 | // comment |
382 | |
383 | type T time.Time |
384 | `, |
385 | out: `package main |
386 | |
387 | import "time" |
388 | |
389 | // comment |
390 | |
391 | type T time.Time |
392 | `, |
393 | }, |
394 | { |
395 | name: "issue 8729 comment before and on package line", |
396 | pkg: "time", |
397 | in: `// comment before |
398 | package main // comment on |
399 | |
400 | type T time.Time |
401 | `, |
402 | out: `// comment before |
403 | package main // comment on |
404 | |
405 | import "time" |
406 | |
407 | type T time.Time |
408 | `, |
409 | }, |
410 | |
411 | // Issue 9961: Match prefixes using path segments rather than bytes |
412 | { |
413 | name: "issue 9961", |
414 | pkg: "regexp", |
415 | in: `package main |
416 | |
417 | import ( |
418 | "flag" |
419 | "testing" |
420 | |
421 | "rsc.io/p" |
422 | ) |
423 | `, |
424 | out: `package main |
425 | |
426 | import ( |
427 | "flag" |
428 | "regexp" |
429 | "testing" |
430 | |
431 | "rsc.io/p" |
432 | ) |
433 | `, |
434 | }, |
435 | // Issue 10337: Preserve comment position |
436 | { |
437 | name: "issue 10337", |
438 | pkg: "fmt", |
439 | in: `package main |
440 | |
441 | import ( |
442 | "bytes" // a |
443 | "log" // c |
444 | ) |
445 | `, |
446 | out: `package main |
447 | |
448 | import ( |
449 | "bytes" // a |
450 | "fmt" |
451 | "log" // c |
452 | ) |
453 | `, |
454 | }, |
455 | { |
456 | name: "issue 10337 new import at the start", |
457 | pkg: "bytes", |
458 | in: `package main |
459 | |
460 | import ( |
461 | "fmt" // b |
462 | "log" // c |
463 | ) |
464 | `, |
465 | out: `package main |
466 | |
467 | import ( |
468 | "bytes" |
469 | "fmt" // b |
470 | "log" // c |
471 | ) |
472 | `, |
473 | }, |
474 | { |
475 | name: "issue 10337 new import at the end", |
476 | pkg: "log", |
477 | in: `package main |
478 | |
479 | import ( |
480 | "bytes" // a |
481 | "fmt" // b |
482 | ) |
483 | `, |
484 | out: `package main |
485 | |
486 | import ( |
487 | "bytes" // a |
488 | "fmt" // b |
489 | "log" |
490 | ) |
491 | `, |
492 | }, |
493 | // Issue 14075: Merge import declarations |
494 | { |
495 | name: "issue 14075", |
496 | pkg: "bufio", |
497 | in: `package main |
498 | |
499 | import "bytes" |
500 | import "fmt" |
501 | `, |
502 | out: `package main |
503 | |
504 | import ( |
505 | "bufio" |
506 | "bytes" |
507 | "fmt" |
508 | ) |
509 | `, |
510 | }, |
511 | { |
512 | name: "issue 14075 update position", |
513 | pkg: "bufio", |
514 | in: `package main |
515 | |
516 | import "bytes" |
517 | import ( |
518 | "fmt" |
519 | ) |
520 | `, |
521 | out: `package main |
522 | |
523 | import ( |
524 | "bufio" |
525 | "bytes" |
526 | "fmt" |
527 | ) |
528 | `, |
529 | }, |
530 | { |
531 | name: `issue 14075 ignore import "C"`, |
532 | pkg: "bufio", |
533 | in: `package main |
534 | |
535 | // Comment |
536 | import "C" |
537 | |
538 | import "bytes" |
539 | import "fmt" |
540 | `, |
541 | out: `package main |
542 | |
543 | // Comment |
544 | import "C" |
545 | |
546 | import ( |
547 | "bufio" |
548 | "bytes" |
549 | "fmt" |
550 | ) |
551 | `, |
552 | }, |
553 | { |
554 | name: `issue 14075 ignore adjacent import "C"`, |
555 | pkg: "bufio", |
556 | in: `package main |
557 | |
558 | // Comment |
559 | import "C" |
560 | import "fmt" |
561 | `, |
562 | out: `package main |
563 | |
564 | // Comment |
565 | import "C" |
566 | import ( |
567 | "bufio" |
568 | "fmt" |
569 | ) |
570 | `, |
571 | }, |
572 | { |
573 | name: `issue 14075 ignore adjacent import "C" (without factored import)`, |
574 | pkg: "bufio", |
575 | in: `package main |
576 | |
577 | // Comment |
578 | import "C" |
579 | import "fmt" |
580 | `, |
581 | out: `package main |
582 | |
583 | // Comment |
584 | import "C" |
585 | import ( |
586 | "bufio" |
587 | "fmt" |
588 | ) |
589 | `, |
590 | }, |
591 | { |
592 | name: `issue 14075 ignore single import "C"`, |
593 | pkg: "bufio", |
594 | in: `package main |
595 | |
596 | // Comment |
597 | import "C" |
598 | `, |
599 | out: `package main |
600 | |
601 | // Comment |
602 | import "C" |
603 | import "bufio" |
604 | `, |
605 | }, |
606 | { |
607 | name: `issue 17212 several single-import lines with shared prefix ending in a slash`, |
608 | pkg: "net/http", |
609 | in: `package main |
610 | |
611 | import "bufio" |
612 | import "net/url" |
613 | `, |
614 | out: `package main |
615 | |
616 | import ( |
617 | "bufio" |
618 | "net/http" |
619 | "net/url" |
620 | ) |
621 | `, |
622 | }, |
623 | { |
624 | name: `issue 17212 block imports lines with shared prefix ending in a slash`, |
625 | pkg: "net/http", |
626 | in: `package main |
627 | |
628 | import ( |
629 | "bufio" |
630 | "net/url" |
631 | ) |
632 | `, |
633 | out: `package main |
634 | |
635 | import ( |
636 | "bufio" |
637 | "net/http" |
638 | "net/url" |
639 | ) |
640 | `, |
641 | }, |
642 | { |
643 | name: `issue 17213 many single-import lines`, |
644 | pkg: "fmt", |
645 | in: `package main |
646 | |
647 | import "bufio" |
648 | import "bytes" |
649 | import "errors" |
650 | `, |
651 | out: `package main |
652 | |
653 | import ( |
654 | "bufio" |
655 | "bytes" |
656 | "errors" |
657 | "fmt" |
658 | ) |
659 | `, |
660 | }, |
661 | |
662 | // Issue 28605: Add specified import, even if that import path is imported under another name |
663 | { |
664 | name: "issue 28605 add unnamed path", |
665 | renamedPkg: "", |
666 | pkg: "path", |
667 | in: `package main |
668 | |
669 | import ( |
670 | . "path" |
671 | _ "path" |
672 | pathpkg "path" |
673 | ) |
674 | `, |
675 | out: `package main |
676 | |
677 | import ( |
678 | "path" |
679 | . "path" |
680 | _ "path" |
681 | pathpkg "path" |
682 | ) |
683 | `, |
684 | }, |
685 | { |
686 | name: "issue 28605 add pathpkg-renamed path", |
687 | renamedPkg: "pathpkg", |
688 | pkg: "path", |
689 | in: `package main |
690 | |
691 | import ( |
692 | "path" |
693 | . "path" |
694 | _ "path" |
695 | ) |
696 | `, |
697 | out: `package main |
698 | |
699 | import ( |
700 | "path" |
701 | . "path" |
702 | _ "path" |
703 | pathpkg "path" |
704 | ) |
705 | `, |
706 | }, |
707 | { |
708 | name: "issue 28605 add blank identifier path", |
709 | renamedPkg: "_", |
710 | pkg: "path", |
711 | in: `package main |
712 | |
713 | import ( |
714 | "path" |
715 | . "path" |
716 | pathpkg "path" |
717 | ) |
718 | `, |
719 | out: `package main |
720 | |
721 | import ( |
722 | "path" |
723 | . "path" |
724 | _ "path" |
725 | pathpkg "path" |
726 | ) |
727 | `, |
728 | }, |
729 | { |
730 | name: "issue 28605 add dot import path", |
731 | renamedPkg: ".", |
732 | pkg: "path", |
733 | in: `package main |
734 | |
735 | import ( |
736 | "path" |
737 | _ "path" |
738 | pathpkg "path" |
739 | ) |
740 | `, |
741 | out: `package main |
742 | |
743 | import ( |
744 | "path" |
745 | . "path" |
746 | _ "path" |
747 | pathpkg "path" |
748 | ) |
749 | `, |
750 | }, |
751 | |
752 | { |
753 | name: "duplicate import declarations, add existing one", |
754 | renamedPkg: "f", |
755 | pkg: "fmt", |
756 | in: `package main |
757 | |
758 | import "fmt" |
759 | import "fmt" |
760 | import f "fmt" |
761 | import f "fmt" |
762 | `, |
763 | out: `package main |
764 | |
765 | import "fmt" |
766 | import "fmt" |
767 | import f "fmt" |
768 | import f "fmt" |
769 | `, |
770 | unchanged: true, |
771 | }, |
772 | } |
773 | |
774 | func TestAddImport(t *testing.T) { |
775 | for _, test := range addTests { |
776 | file := parse(t, test.name, test.in) |
777 | var before bytes.Buffer |
778 | ast.Fprint(&before, fset, file, nil) |
779 | added := AddNamedImport(fset, file, test.renamedPkg, test.pkg) |
780 | if got := print(t, test.name, file); got != test.out { |
781 | t.Errorf("first run: %s:\ngot: %s\nwant: %s", test.name, got, test.out) |
782 | var after bytes.Buffer |
783 | ast.Fprint(&after, fset, file, nil) |
784 | t.Logf("AST before:\n%s\nAST after:\n%s\n", before.String(), after.String()) |
785 | } |
786 | if got, want := added, !test.unchanged; got != want { |
787 | t.Errorf("first run: %s: added = %v, want %v", test.name, got, want) |
788 | } |
789 | |
790 | // AddNamedImport should be idempotent. Verify that by calling it again, |
791 | // expecting no change to the AST, and the returned added value to always be false. |
792 | added = AddNamedImport(fset, file, test.renamedPkg, test.pkg) |
793 | if got := print(t, test.name, file); got != test.out { |
794 | t.Errorf("second run: %s:\ngot: %s\nwant: %s", test.name, got, test.out) |
795 | } |
796 | if got, want := added, false; got != want { |
797 | t.Errorf("second run: %s: added = %v, want %v", test.name, got, want) |
798 | } |
799 | } |
800 | } |
801 | |
802 | func TestDoubleAddImport(t *testing.T) { |
803 | file := parse(t, "doubleimport", "package main\n") |
804 | AddImport(fset, file, "os") |
805 | AddImport(fset, file, "bytes") |
806 | want := `package main |
807 | |
808 | import ( |
809 | "bytes" |
810 | "os" |
811 | ) |
812 | ` |
813 | if got := print(t, "doubleimport", file); got != want { |
814 | t.Errorf("got: %s\nwant: %s", got, want) |
815 | } |
816 | } |
817 | |
818 | func TestDoubleAddNamedImport(t *testing.T) { |
819 | file := parse(t, "doublenamedimport", "package main\n") |
820 | AddNamedImport(fset, file, "o", "os") |
821 | AddNamedImport(fset, file, "i", "io") |
822 | want := `package main |
823 | |
824 | import ( |
825 | i "io" |
826 | o "os" |
827 | ) |
828 | ` |
829 | if got := print(t, "doublenamedimport", file); got != want { |
830 | t.Errorf("got: %s\nwant: %s", got, want) |
831 | } |
832 | } |
833 | |
834 | // Part of issue 8729. |
835 | func TestDoubleAddImportWithDeclComment(t *testing.T) { |
836 | file := parse(t, "doubleimport", `package main |
837 | |
838 | import ( |
839 | ) |
840 | |
841 | // comment |
842 | type I int |
843 | `) |
844 | // The AddImport order here matters. |
845 | AddImport(fset, file, "golang.org/x/tools/go/ast/astutil") |
846 | AddImport(fset, file, "os") |
847 | want := `package main |
848 | |
849 | import ( |
850 | "golang.org/x/tools/go/ast/astutil" |
851 | "os" |
852 | ) |
853 | |
854 | // comment |
855 | type I int |
856 | ` |
857 | if got := print(t, "doubleimport_with_decl_comment", file); got != want { |
858 | t.Errorf("got: %s\nwant: %s", got, want) |
859 | } |
860 | } |
861 | |
862 | var deleteTests = []test{ |
863 | { |
864 | name: "import.4", |
865 | pkg: "os", |
866 | in: `package main |
867 | |
868 | import ( |
869 | "os" |
870 | ) |
871 | `, |
872 | out: `package main |
873 | `, |
874 | }, |
875 | { |
876 | name: "import.5", |
877 | pkg: "os", |
878 | in: `package main |
879 | |
880 | // Comment |
881 | import "C" |
882 | import "os" |
883 | `, |
884 | out: `package main |
885 | |
886 | // Comment |
887 | import "C" |
888 | `, |
889 | }, |
890 | { |
891 | name: "import.6", |
892 | pkg: "os", |
893 | in: `package main |
894 | |
895 | // Comment |
896 | import "C" |
897 | |
898 | import ( |
899 | "io" |
900 | "os" |
901 | "utf8" |
902 | ) |
903 | `, |
904 | out: `package main |
905 | |
906 | // Comment |
907 | import "C" |
908 | |
909 | import ( |
910 | "io" |
911 | "utf8" |
912 | ) |
913 | `, |
914 | }, |
915 | { |
916 | name: "import.7", |
917 | pkg: "io", |
918 | in: `package main |
919 | |
920 | import ( |
921 | "io" // a |
922 | "os" // b |
923 | "utf8" // c |
924 | ) |
925 | `, |
926 | out: `package main |
927 | |
928 | import ( |
929 | // a |
930 | "os" // b |
931 | "utf8" // c |
932 | ) |
933 | `, |
934 | }, |
935 | { |
936 | name: "import.8", |
937 | pkg: "os", |
938 | in: `package main |
939 | |
940 | import ( |
941 | "io" // a |
942 | "os" // b |
943 | "utf8" // c |
944 | ) |
945 | `, |
946 | out: `package main |
947 | |
948 | import ( |
949 | "io" // a |
950 | // b |
951 | "utf8" // c |
952 | ) |
953 | `, |
954 | }, |
955 | { |
956 | name: "import.9", |
957 | pkg: "utf8", |
958 | in: `package main |
959 | |
960 | import ( |
961 | "io" // a |
962 | "os" // b |
963 | "utf8" // c |
964 | ) |
965 | `, |
966 | out: `package main |
967 | |
968 | import ( |
969 | "io" // a |
970 | "os" // b |
971 | // c |
972 | ) |
973 | `, |
974 | }, |
975 | { |
976 | name: "import.10", |
977 | pkg: "io", |
978 | in: `package main |
979 | |
980 | import ( |
981 | "io" |
982 | "os" |
983 | "utf8" |
984 | ) |
985 | `, |
986 | out: `package main |
987 | |
988 | import ( |
989 | "os" |
990 | "utf8" |
991 | ) |
992 | `, |
993 | }, |
994 | { |
995 | name: "import.11", |
996 | pkg: "os", |
997 | in: `package main |
998 | |
999 | import ( |
1000 | "io" |
1001 | "os" |
1002 | "utf8" |
1003 | ) |
1004 | `, |
1005 | out: `package main |
1006 | |
1007 | import ( |
1008 | "io" |
1009 | "utf8" |
1010 | ) |
1011 | `, |
1012 | }, |
1013 | { |
1014 | name: "import.12", |
1015 | pkg: "utf8", |
1016 | in: `package main |
1017 | |
1018 | import ( |
1019 | "io" |
1020 | "os" |
1021 | "utf8" |
1022 | ) |
1023 | `, |
1024 | out: `package main |
1025 | |
1026 | import ( |
1027 | "io" |
1028 | "os" |
1029 | ) |
1030 | `, |
1031 | }, |
1032 | { |
1033 | name: "handle.raw.quote.imports", |
1034 | pkg: "os", |
1035 | in: "package main\n\nimport `os`", |
1036 | out: `package main |
1037 | `, |
1038 | }, |
1039 | { |
1040 | name: "import.13", |
1041 | pkg: "io", |
1042 | in: `package main |
1043 | |
1044 | import ( |
1045 | "fmt" |
1046 | |
1047 | "io" |
1048 | "os" |
1049 | "utf8" |
1050 | |
1051 | "go/format" |
1052 | ) |
1053 | `, |
1054 | out: `package main |
1055 | |
1056 | import ( |
1057 | "fmt" |
1058 | |
1059 | "os" |
1060 | "utf8" |
1061 | |
1062 | "go/format" |
1063 | ) |
1064 | `, |
1065 | }, |
1066 | { |
1067 | name: "import.14", |
1068 | pkg: "io", |
1069 | in: `package main |
1070 | |
1071 | import ( |
1072 | "fmt" // a |
1073 | |
1074 | "io" // b |
1075 | "os" // c |
1076 | "utf8" // d |
1077 | |
1078 | "go/format" // e |
1079 | ) |
1080 | `, |
1081 | out: `package main |
1082 | |
1083 | import ( |
1084 | "fmt" // a |
1085 | |
1086 | // b |
1087 | "os" // c |
1088 | "utf8" // d |
1089 | |
1090 | "go/format" // e |
1091 | ) |
1092 | `, |
1093 | }, |
1094 | { |
1095 | name: "import.15", |
1096 | pkg: "double", |
1097 | in: `package main |
1098 | |
1099 | import ( |
1100 | "double" |
1101 | "double" |
1102 | ) |
1103 | `, |
1104 | out: `package main |
1105 | `, |
1106 | }, |
1107 | { |
1108 | name: "import.16", |
1109 | pkg: "bubble", |
1110 | in: `package main |
1111 | |
1112 | import ( |
1113 | "toil" |
1114 | "bubble" |
1115 | "bubble" |
1116 | "trouble" |
1117 | ) |
1118 | `, |
1119 | out: `package main |
1120 | |
1121 | import ( |
1122 | "toil" |
1123 | "trouble" |
1124 | ) |
1125 | `, |
1126 | }, |
1127 | { |
1128 | name: "import.17", |
1129 | pkg: "quad", |
1130 | in: `package main |
1131 | |
1132 | import ( |
1133 | "quad" |
1134 | "quad" |
1135 | ) |
1136 | |
1137 | import ( |
1138 | "quad" |
1139 | "quad" |
1140 | ) |
1141 | `, |
1142 | out: `package main |
1143 | `, |
1144 | }, |
1145 | { |
1146 | name: "import.18", |
1147 | renamedPkg: "x", |
1148 | pkg: "fmt", |
1149 | in: `package main |
1150 | |
1151 | import ( |
1152 | "fmt" |
1153 | x "fmt" |
1154 | ) |
1155 | `, |
1156 | out: `package main |
1157 | |
1158 | import ( |
1159 | "fmt" |
1160 | ) |
1161 | `, |
1162 | }, |
1163 | { |
1164 | name: "import.18", |
1165 | renamedPkg: "x", |
1166 | pkg: "fmt", |
1167 | in: `package main |
1168 | |
1169 | import x "fmt" |
1170 | import y "fmt" |
1171 | `, |
1172 | out: `package main |
1173 | |
1174 | import y "fmt" |
1175 | `, |
1176 | }, |
1177 | // Issue #15432, #18051 |
1178 | { |
1179 | name: "import.19", |
1180 | pkg: "fmt", |
1181 | in: `package main |
1182 | |
1183 | import ( |
1184 | "fmt" |
1185 | |
1186 | // Some comment. |
1187 | "io" |
1188 | )`, |
1189 | out: `package main |
1190 | |
1191 | import ( |
1192 | // Some comment. |
1193 | "io" |
1194 | ) |
1195 | `, |
1196 | }, |
1197 | { |
1198 | name: "import.20", |
1199 | pkg: "fmt", |
1200 | in: `package main |
1201 | |
1202 | import ( |
1203 | "fmt" |
1204 | |
1205 | // Some |
1206 | // comment. |
1207 | "io" |
1208 | )`, |
1209 | out: `package main |
1210 | |
1211 | import ( |
1212 | // Some |
1213 | // comment. |
1214 | "io" |
1215 | ) |
1216 | `, |
1217 | }, |
1218 | { |
1219 | name: "import.21", |
1220 | pkg: "fmt", |
1221 | in: `package main |
1222 | |
1223 | import ( |
1224 | "fmt" |
1225 | |
1226 | /* |
1227 | Some |
1228 | comment. |
1229 | */ |
1230 | "io" |
1231 | )`, |
1232 | out: `package main |
1233 | |
1234 | import ( |
1235 | /* |
1236 | Some |
1237 | comment. |
1238 | */ |
1239 | "io" |
1240 | ) |
1241 | `, |
1242 | }, |
1243 | { |
1244 | name: "import.22", |
1245 | pkg: "fmt", |
1246 | in: `package main |
1247 | |
1248 | import ( |
1249 | /* Some */ |
1250 | // comment. |
1251 | "io" |
1252 | "fmt" |
1253 | )`, |
1254 | out: `package main |
1255 | |
1256 | import ( |
1257 | /* Some */ |
1258 | // comment. |
1259 | "io" |
1260 | ) |
1261 | `, |
1262 | }, |
1263 | { |
1264 | name: "import.23", |
1265 | pkg: "fmt", |
1266 | in: `package main |
1267 | |
1268 | import ( |
1269 | // comment 1 |
1270 | "fmt" |
1271 | // comment 2 |
1272 | "io" |
1273 | )`, |
1274 | out: `package main |
1275 | |
1276 | import ( |
1277 | // comment 2 |
1278 | "io" |
1279 | ) |
1280 | `, |
1281 | }, |
1282 | { |
1283 | name: "import.24", |
1284 | pkg: "fmt", |
1285 | in: `package main |
1286 | |
1287 | import ( |
1288 | "fmt" // comment 1 |
1289 | "io" // comment 2 |
1290 | )`, |
1291 | out: `package main |
1292 | |
1293 | import ( |
1294 | "io" // comment 2 |
1295 | ) |
1296 | `, |
1297 | }, |
1298 | { |
1299 | name: "import.25", |
1300 | pkg: "fmt", |
1301 | in: `package main |
1302 | |
1303 | import ( |
1304 | "fmt" |
1305 | /* comment */ "io" |
1306 | )`, |
1307 | out: `package main |
1308 | |
1309 | import ( |
1310 | /* comment */ "io" |
1311 | ) |
1312 | `, |
1313 | }, |
1314 | { |
1315 | name: "import.26", |
1316 | pkg: "fmt", |
1317 | in: `package main |
1318 | |
1319 | import ( |
1320 | "fmt" |
1321 | "io" /* comment */ |
1322 | )`, |
1323 | out: `package main |
1324 | |
1325 | import ( |
1326 | "io" /* comment */ |
1327 | ) |
1328 | `, |
1329 | }, |
1330 | { |
1331 | name: "import.27", |
1332 | pkg: "fmt", |
1333 | in: `package main |
1334 | |
1335 | import ( |
1336 | "fmt" /* comment */ |
1337 | "io" |
1338 | )`, |
1339 | out: `package main |
1340 | |
1341 | import ( |
1342 | "io" |
1343 | ) |
1344 | `, |
1345 | }, |
1346 | { |
1347 | name: "import.28", |
1348 | pkg: "fmt", |
1349 | in: `package main |
1350 | |
1351 | import ( |
1352 | /* comment */ "fmt" |
1353 | "io" |
1354 | )`, |
1355 | out: `package main |
1356 | |
1357 | import ( |
1358 | "io" |
1359 | ) |
1360 | `, |
1361 | }, |
1362 | { |
1363 | name: "import.29", |
1364 | pkg: "fmt", |
1365 | in: `package main |
1366 | |
1367 | // comment 1 |
1368 | import ( |
1369 | "fmt" |
1370 | "io" // comment 2 |
1371 | )`, |
1372 | out: `package main |
1373 | |
1374 | // comment 1 |
1375 | import ( |
1376 | "io" // comment 2 |
1377 | ) |
1378 | `, |
1379 | }, |
1380 | { |
1381 | name: "import.30", |
1382 | pkg: "fmt", |
1383 | in: `package main |
1384 | |
1385 | // comment 1 |
1386 | import ( |
1387 | "fmt" // comment 2 |
1388 | "io" |
1389 | )`, |
1390 | out: `package main |
1391 | |
1392 | // comment 1 |
1393 | import ( |
1394 | "io" |
1395 | ) |
1396 | `, |
1397 | }, |
1398 | { |
1399 | name: "import.31", |
1400 | pkg: "fmt", |
1401 | in: `package main |
1402 | |
1403 | // comment 1 |
1404 | import ( |
1405 | "fmt" |
1406 | /* comment 2 */ "io" |
1407 | )`, |
1408 | out: `package main |
1409 | |
1410 | // comment 1 |
1411 | import ( |
1412 | /* comment 2 */ "io" |
1413 | ) |
1414 | `, |
1415 | }, |
1416 | { |
1417 | name: "import.32", |
1418 | pkg: "fmt", |
1419 | renamedPkg: "f", |
1420 | in: `package main |
1421 | |
1422 | // comment 1 |
1423 | import ( |
1424 | f "fmt" |
1425 | /* comment 2 */ i "io" |
1426 | )`, |
1427 | out: `package main |
1428 | |
1429 | // comment 1 |
1430 | import ( |
1431 | /* comment 2 */ i "io" |
1432 | ) |
1433 | `, |
1434 | }, |
1435 | { |
1436 | name: "import.33", |
1437 | pkg: "fmt", |
1438 | renamedPkg: "f", |
1439 | in: `package main |
1440 | |
1441 | // comment 1 |
1442 | import ( |
1443 | /* comment 2 */ f "fmt" |
1444 | i "io" |
1445 | )`, |
1446 | out: `package main |
1447 | |
1448 | // comment 1 |
1449 | import ( |
1450 | i "io" |
1451 | ) |
1452 | `, |
1453 | }, |
1454 | { |
1455 | name: "import.34", |
1456 | pkg: "fmt", |
1457 | renamedPkg: "f", |
1458 | in: `package main |
1459 | |
1460 | // comment 1 |
1461 | import ( |
1462 | f "fmt" /* comment 2 */ |
1463 | i "io" |
1464 | )`, |
1465 | out: `package main |
1466 | |
1467 | // comment 1 |
1468 | import ( |
1469 | i "io" |
1470 | ) |
1471 | `, |
1472 | }, |
1473 | { |
1474 | name: "import.35", |
1475 | pkg: "fmt", |
1476 | in: `package main |
1477 | |
1478 | // comment 1 |
1479 | import ( |
1480 | "fmt" |
1481 | // comment 2 |
1482 | "io" |
1483 | )`, |
1484 | out: `package main |
1485 | |
1486 | // comment 1 |
1487 | import ( |
1488 | // comment 2 |
1489 | "io" |
1490 | ) |
1491 | `, |
1492 | }, |
1493 | { |
1494 | name: "import.36", |
1495 | pkg: "fmt", |
1496 | in: `package main |
1497 | |
1498 | /* comment 1 */ |
1499 | import ( |
1500 | "fmt" |
1501 | /* comment 2 */ |
1502 | "io" |
1503 | )`, |
1504 | out: `package main |
1505 | |
1506 | /* comment 1 */ |
1507 | import ( |
1508 | /* comment 2 */ |
1509 | "io" |
1510 | ) |
1511 | `, |
1512 | }, |
1513 | |
1514 | // Issue 20229: MergeLine panic on weird input |
1515 | { |
1516 | name: "import.37", |
1517 | pkg: "io", |
1518 | in: `package main |
1519 | import("_" |
1520 | "io")`, |
1521 | out: `package main |
1522 | |
1523 | import ( |
1524 | "_" |
1525 | ) |
1526 | `, |
1527 | }, |
1528 | |
1529 | // Issue 28605: Delete specified import, even if that import path is imported under another name |
1530 | { |
1531 | name: "import.38", |
1532 | renamedPkg: "", |
1533 | pkg: "path", |
1534 | in: `package main |
1535 | |
1536 | import ( |
1537 | "path" |
1538 | . "path" |
1539 | _ "path" |
1540 | pathpkg "path" |
1541 | ) |
1542 | `, |
1543 | out: `package main |
1544 | |
1545 | import ( |
1546 | . "path" |
1547 | _ "path" |
1548 | pathpkg "path" |
1549 | ) |
1550 | `, |
1551 | }, |
1552 | { |
1553 | name: "import.39", |
1554 | renamedPkg: "pathpkg", |
1555 | pkg: "path", |
1556 | in: `package main |
1557 | |
1558 | import ( |
1559 | "path" |
1560 | . "path" |
1561 | _ "path" |
1562 | pathpkg "path" |
1563 | ) |
1564 | `, |
1565 | out: `package main |
1566 | |
1567 | import ( |
1568 | "path" |
1569 | . "path" |
1570 | _ "path" |
1571 | ) |
1572 | `, |
1573 | }, |
1574 | { |
1575 | name: "import.40", |
1576 | renamedPkg: "_", |
1577 | pkg: "path", |
1578 | in: `package main |
1579 | |
1580 | import ( |
1581 | "path" |
1582 | . "path" |
1583 | _ "path" |
1584 | pathpkg "path" |
1585 | ) |
1586 | `, |
1587 | out: `package main |
1588 | |
1589 | import ( |
1590 | "path" |
1591 | . "path" |
1592 | pathpkg "path" |
1593 | ) |
1594 | `, |
1595 | }, |
1596 | { |
1597 | name: "import.41", |
1598 | renamedPkg: ".", |
1599 | pkg: "path", |
1600 | in: `package main |
1601 | |
1602 | import ( |
1603 | "path" |
1604 | . "path" |
1605 | _ "path" |
1606 | pathpkg "path" |
1607 | ) |
1608 | `, |
1609 | out: `package main |
1610 | |
1611 | import ( |
1612 | "path" |
1613 | _ "path" |
1614 | pathpkg "path" |
1615 | ) |
1616 | `, |
1617 | }, |
1618 | |
1619 | // Duplicate import declarations, all matching ones are deleted. |
1620 | { |
1621 | name: "import.42", |
1622 | renamedPkg: "f", |
1623 | pkg: "fmt", |
1624 | in: `package main |
1625 | |
1626 | import "fmt" |
1627 | import "fmt" |
1628 | import f "fmt" |
1629 | import f "fmt" |
1630 | `, |
1631 | out: `package main |
1632 | |
1633 | import "fmt" |
1634 | import "fmt" |
1635 | `, |
1636 | }, |
1637 | { |
1638 | name: "import.43", |
1639 | renamedPkg: "x", |
1640 | pkg: "fmt", |
1641 | in: `package main |
1642 | |
1643 | import "fmt" |
1644 | import "fmt" |
1645 | import f "fmt" |
1646 | import f "fmt" |
1647 | `, |
1648 | out: `package main |
1649 | |
1650 | import "fmt" |
1651 | import "fmt" |
1652 | import f "fmt" |
1653 | import f "fmt" |
1654 | `, |
1655 | unchanged: true, |
1656 | }, |
1657 | // this test panics without PositionFor in DeleteNamedImport |
1658 | { |
1659 | name: "import.44", |
1660 | pkg: "foo.com/other/v3", |
1661 | renamedPkg: "", |
1662 | in: `package main |
1663 | //line mah.go:600 |
1664 | |
1665 | import ( |
1666 | "foo.com/a.thing" |
1667 | "foo.com/surprise" |
1668 | "foo.com/v1" |
1669 | "foo.com/other/v2" |
1670 | "foo.com/other/v3" |
1671 | ) |
1672 | `, |
1673 | out: `package main |
1674 | |
1675 | //line mah.go:600 |
1676 | |
1677 | import ( |
1678 | "foo.com/a.thing" |
1679 | "foo.com/other/v2" |
1680 | "foo.com/surprise" |
1681 | "foo.com/v1" |
1682 | ) |
1683 | `, |
1684 | }, |
1685 | } |
1686 | |
1687 | func TestDeleteImport(t *testing.T) { |
1688 | for _, test := range deleteTests { |
1689 | file := parse(t, test.name, test.in) |
1690 | var before bytes.Buffer |
1691 | ast.Fprint(&before, fset, file, nil) |
1692 | deleted := DeleteNamedImport(fset, file, test.renamedPkg, test.pkg) |
1693 | if got := print(t, test.name, file); got != test.out { |
1694 | t.Errorf("first run: %s:\ngot: %s\nwant: %s", test.name, got, test.out) |
1695 | var after bytes.Buffer |
1696 | ast.Fprint(&after, fset, file, nil) |
1697 | t.Logf("AST before:\n%s\nAST after:\n%s\n", before.String(), after.String()) |
1698 | } |
1699 | if got, want := deleted, !test.unchanged; got != want { |
1700 | t.Errorf("first run: %s: deleted = %v, want %v", test.name, got, want) |
1701 | } |
1702 | |
1703 | // DeleteNamedImport should be idempotent. Verify that by calling it again, |
1704 | // expecting no change to the AST, and the returned deleted value to always be false. |
1705 | deleted = DeleteNamedImport(fset, file, test.renamedPkg, test.pkg) |
1706 | if got := print(t, test.name, file); got != test.out { |
1707 | t.Errorf("second run: %s:\ngot: %s\nwant: %s", test.name, got, test.out) |
1708 | } |
1709 | if got, want := deleted, false; got != want { |
1710 | t.Errorf("second run: %s: deleted = %v, want %v", test.name, got, want) |
1711 | } |
1712 | } |
1713 | } |
1714 | |
1715 | func TestDeleteImportAfterAddImport(t *testing.T) { |
1716 | file := parse(t, "test", `package main |
1717 | |
1718 | import "os" |
1719 | `) |
1720 | if got, want := AddImport(fset, file, "fmt"), true; got != want { |
1721 | t.Errorf("AddImport: got: %v, want: %v", got, want) |
1722 | } |
1723 | if got, want := DeleteImport(fset, file, "fmt"), true; got != want { |
1724 | t.Errorf("DeleteImport: got: %v, want: %v", got, want) |
1725 | } |
1726 | } |
1727 | |
1728 | type rewriteTest struct { |
1729 | name string |
1730 | srcPkg string |
1731 | dstPkg string |
1732 | in string |
1733 | out string |
1734 | } |
1735 | |
1736 | var rewriteTests = []rewriteTest{ |
1737 | { |
1738 | name: "import.13", |
1739 | srcPkg: "utf8", |
1740 | dstPkg: "encoding/utf8", |
1741 | in: `package main |
1742 | |
1743 | import ( |
1744 | "io" |
1745 | "os" |
1746 | "utf8" // thanks ken |
1747 | ) |
1748 | `, |
1749 | out: `package main |
1750 | |
1751 | import ( |
1752 | "encoding/utf8" // thanks ken |
1753 | "io" |
1754 | "os" |
1755 | ) |
1756 | `, |
1757 | }, |
1758 | { |
1759 | name: "import.14", |
1760 | srcPkg: "asn1", |
1761 | dstPkg: "encoding/asn1", |
1762 | in: `package main |
1763 | |
1764 | import ( |
1765 | "asn1" |
1766 | "crypto" |
1767 | "crypto/rsa" |
1768 | _ "crypto/sha1" |
1769 | "crypto/x509" |
1770 | "crypto/x509/pkix" |
1771 | "time" |
1772 | ) |
1773 | |
1774 | var x = 1 |
1775 | `, |
1776 | out: `package main |
1777 | |
1778 | import ( |
1779 | "crypto" |
1780 | "crypto/rsa" |
1781 | _ "crypto/sha1" |
1782 | "crypto/x509" |
1783 | "crypto/x509/pkix" |
1784 | "encoding/asn1" |
1785 | "time" |
1786 | ) |
1787 | |
1788 | var x = 1 |
1789 | `, |
1790 | }, |
1791 | { |
1792 | name: "import.15", |
1793 | srcPkg: "url", |
1794 | dstPkg: "net/url", |
1795 | in: `package main |
1796 | |
1797 | import ( |
1798 | "bufio" |
1799 | "net" |
1800 | "path" |
1801 | "url" |
1802 | ) |
1803 | |
1804 | var x = 1 // comment on x, not on url |
1805 | `, |
1806 | out: `package main |
1807 | |
1808 | import ( |
1809 | "bufio" |
1810 | "net" |
1811 | "net/url" |
1812 | "path" |
1813 | ) |
1814 | |
1815 | var x = 1 // comment on x, not on url |
1816 | `, |
1817 | }, |
1818 | { |
1819 | name: "import.16", |
1820 | srcPkg: "http", |
1821 | dstPkg: "net/http", |
1822 | in: `package main |
1823 | |
1824 | import ( |
1825 | "flag" |
1826 | "http" |
1827 | "log" |
1828 | "text/template" |
1829 | ) |
1830 | |
1831 | var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18 |
1832 | `, |
1833 | out: `package main |
1834 | |
1835 | import ( |
1836 | "flag" |
1837 | "log" |
1838 | "net/http" |
1839 | "text/template" |
1840 | ) |
1841 | |
1842 | var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18 |
1843 | `, |
1844 | }, |
1845 | } |
1846 | |
1847 | func TestRewriteImport(t *testing.T) { |
1848 | for _, test := range rewriteTests { |
1849 | file := parse(t, test.name, test.in) |
1850 | RewriteImport(fset, file, test.srcPkg, test.dstPkg) |
1851 | if got := print(t, test.name, file); got != test.out { |
1852 | t.Errorf("%s:\ngot: %s\nwant: %s", test.name, got, test.out) |
1853 | } |
1854 | } |
1855 | } |
1856 | |
1857 | var importsTests = []struct { |
1858 | name string |
1859 | in string |
1860 | want [][]string |
1861 | }{ |
1862 | { |
1863 | name: "no packages", |
1864 | in: `package foo |
1865 | `, |
1866 | want: nil, |
1867 | }, |
1868 | { |
1869 | name: "one group", |
1870 | in: `package foo |
1871 | |
1872 | import ( |
1873 | "fmt" |
1874 | "testing" |
1875 | ) |
1876 | `, |
1877 | want: [][]string{{"fmt", "testing"}}, |
1878 | }, |
1879 | { |
1880 | name: "four groups", |
1881 | in: `package foo |
1882 | |
1883 | import "C" |
1884 | import ( |
1885 | "fmt" |
1886 | "testing" |
1887 | |
1888 | "appengine" |
1889 | |
1890 | "myproject/mylib1" |
1891 | "myproject/mylib2" |
1892 | ) |
1893 | `, |
1894 | want: [][]string{ |
1895 | {"C"}, |
1896 | {"fmt", "testing"}, |
1897 | {"appengine"}, |
1898 | {"myproject/mylib1", "myproject/mylib2"}, |
1899 | }, |
1900 | }, |
1901 | { |
1902 | name: "multiple factored groups", |
1903 | in: `package foo |
1904 | |
1905 | import ( |
1906 | "fmt" |
1907 | "testing" |
1908 | |
1909 | "appengine" |
1910 | ) |
1911 | import ( |
1912 | "reflect" |
1913 | |
1914 | "bytes" |
1915 | ) |
1916 | `, |
1917 | want: [][]string{ |
1918 | {"fmt", "testing"}, |
1919 | {"appengine"}, |
1920 | {"reflect"}, |
1921 | {"bytes"}, |
1922 | }, |
1923 | }, |
1924 | } |
1925 | |
1926 | func unquote(s string) string { |
1927 | res, err := strconv.Unquote(s) |
1928 | if err != nil { |
1929 | return "could_not_unquote" |
1930 | } |
1931 | return res |
1932 | } |
1933 | |
1934 | func TestImports(t *testing.T) { |
1935 | fset := token.NewFileSet() |
1936 | for _, test := range importsTests { |
1937 | f, err := parser.ParseFile(fset, "test.go", test.in, 0) |
1938 | if err != nil { |
1939 | t.Errorf("%s: %v", test.name, err) |
1940 | continue |
1941 | } |
1942 | var got [][]string |
1943 | for _, group := range Imports(fset, f) { |
1944 | var b []string |
1945 | for _, spec := range group { |
1946 | b = append(b, unquote(spec.Path.Value)) |
1947 | } |
1948 | got = append(got, b) |
1949 | } |
1950 | if !reflect.DeepEqual(got, test.want) { |
1951 | t.Errorf("Imports(%s)=%v, want %v", test.name, got, test.want) |
1952 | } |
1953 | } |
1954 | } |
1955 | |
1956 | var usesImportTests = []struct { |
1957 | name string |
1958 | path string |
1959 | in string |
1960 | want bool |
1961 | }{ |
1962 | { |
1963 | name: "no packages", |
1964 | path: "io", |
1965 | in: `package foo |
1966 | `, |
1967 | want: false, |
1968 | }, |
1969 | { |
1970 | name: "import.1", |
1971 | path: "io", |
1972 | in: `package foo |
1973 | |
1974 | import "io" |
1975 | |
1976 | var _ io.Writer |
1977 | `, |
1978 | want: true, |
1979 | }, |
1980 | { |
1981 | name: "import.2", |
1982 | path: "io", |
1983 | in: `package foo |
1984 | |
1985 | import "io" |
1986 | `, |
1987 | want: false, |
1988 | }, |
1989 | { |
1990 | name: "import.3", |
1991 | path: "io", |
1992 | in: `package foo |
1993 | |
1994 | import "io" |
1995 | |
1996 | var io = 42 |
1997 | `, |
1998 | want: false, |
1999 | }, |
2000 | { |
2001 | name: "import.4", |
2002 | path: "io", |
2003 | in: `package foo |
2004 | |
2005 | import i "io" |
2006 | |
2007 | var _ i.Writer |
2008 | `, |
2009 | want: true, |
2010 | }, |
2011 | { |
2012 | name: "import.5", |
2013 | path: "io", |
2014 | in: `package foo |
2015 | |
2016 | import i "io" |
2017 | `, |
2018 | want: false, |
2019 | }, |
2020 | { |
2021 | name: "import.6", |
2022 | path: "io", |
2023 | in: `package foo |
2024 | |
2025 | import i "io" |
2026 | |
2027 | var i = 42 |
2028 | var io = 42 |
2029 | `, |
2030 | want: false, |
2031 | }, |
2032 | { |
2033 | name: "import.7", |
2034 | path: "encoding/json", |
2035 | in: `package foo |
2036 | |
2037 | import "encoding/json" |
2038 | |
2039 | var _ json.Encoder |
2040 | `, |
2041 | want: true, |
2042 | }, |
2043 | { |
2044 | name: "import.8", |
2045 | path: "encoding/json", |
2046 | in: `package foo |
2047 | |
2048 | import "encoding/json" |
2049 | `, |
2050 | want: false, |
2051 | }, |
2052 | { |
2053 | name: "import.9", |
2054 | path: "encoding/json", |
2055 | in: `package foo |
2056 | |
2057 | import "encoding/json" |
2058 | |
2059 | var json = 42 |
2060 | `, |
2061 | want: false, |
2062 | }, |
2063 | { |
2064 | name: "import.10", |
2065 | path: "encoding/json", |
2066 | in: `package foo |
2067 | |
2068 | import j "encoding/json" |
2069 | |
2070 | var _ j.Encoder |
2071 | `, |
2072 | want: true, |
2073 | }, |
2074 | { |
2075 | name: "import.11", |
2076 | path: "encoding/json", |
2077 | in: `package foo |
2078 | |
2079 | import j "encoding/json" |
2080 | `, |
2081 | want: false, |
2082 | }, |
2083 | { |
2084 | name: "import.12", |
2085 | path: "encoding/json", |
2086 | in: `package foo |
2087 | |
2088 | import j "encoding/json" |
2089 | |
2090 | var j = 42 |
2091 | var json = 42 |
2092 | `, |
2093 | want: false, |
2094 | }, |
2095 | { |
2096 | name: "import.13", |
2097 | path: "io", |
2098 | in: `package foo |
2099 | |
2100 | import _ "io" |
2101 | `, |
2102 | want: true, |
2103 | }, |
2104 | { |
2105 | name: "import.14", |
2106 | path: "io", |
2107 | in: `package foo |
2108 | |
2109 | import . "io" |
2110 | `, |
2111 | want: true, |
2112 | }, |
2113 | } |
2114 | |
2115 | func TestUsesImport(t *testing.T) { |
2116 | fset := token.NewFileSet() |
2117 | for _, test := range usesImportTests { |
2118 | f, err := parser.ParseFile(fset, "test.go", test.in, 0) |
2119 | if err != nil { |
2120 | t.Errorf("%s: %v", test.name, err) |
2121 | continue |
2122 | } |
2123 | got := UsesImport(f, test.path) |
2124 | if got != test.want { |
2125 | t.Errorf("UsesImport(%s)=%v, want %v", test.name, got, test.want) |
2126 | } |
2127 | } |
2128 | } |
2129 |
Members