Skip to content

Commit 071c369

Browse files
authoredDec 30, 2020
Adds 'outline' command to print the outline of specs/containers in a file (#754)
* Adds 'outline' command to print the outline of specs/containers in a file Implements feature request in #753 * outline: Add support for nodot and alias import of the ginkgo package * outline: During a post-order traversal of an AST Node, do not derive its ginkgo metadata The post-order traversal needs to check whether the AST Node is a ginkgo node. That can be done by comparing the positions of the AST Node and the last visited ginkgo node. Deriving the ginkgo metadata is not necessary. * outline: Add backpropagation of unfocus, propagation of inherited focus/pending properties * outline: Add instructions and script for creating/updating sample test results To make it easier to maintain the outline tests. * outline: Use script to re-create result samples for all tests The content has not changed; only the JSON formatting and the filenames have changed. * outline: Factor the back/propagation code to helper functions The top-level function needed to be shorter. * outline: Refactor deriving ginkgo identifier from call expression Again, the top-level function needed to be shorter. * outline: Move the exported outline code into its own file Keep the unexprted ginkgoNode code in a separate file. * outline: Instead of aliasing ginkgoNode with outline, embed ginkgoNode in outline An advantage of embedding is that it does not require casting. The outline receivers does not change. * outline: (fix) Derive the "text" of the By ginkgo call The "text" was being ignored by mistake. * outline: Test an outline of a "suite_test.go" file The test and its result samples were already present, but the test was not run. * outline: Add "indent" format This is really just for fun. Here's an example: ``shell ginkgo outline -format=indent outline/_testdata/normal_test.go ``` ```shell Name,Text,Start,End,Spec,Focused,Pending Describe,NormalFixture,116,605,false,false,false Describe,normal,152,244,false,false,false It,normal,182,240,true,false,false By,step 1,207,219,false,false,false By,step 2,223,235,false,false,false Context,normal,247,307,false,false,false It,normal,276,303,true,false,false When,normal,310,367,false,false,false It,normal,336,363,true,false,false It,normal,370,396,true,false,false Specify,normal,399,430,true,false,false Measure,normal,433,480,true,false,false ``` It also happens to look nice piped through `column`: ```shell ginkgo outline -format=indent outline/_testdata/normal_test.go | column --table -s="," ``` ``` Name Text Start End Spec Focused Pending Describe NormalFixture 116 605 false false false Describe normal 152 244 false false false It normal 182 240 true false false By step 1 207 219 false false false By step 2 223 235 false false false Context normal 247 307 false false false It normal 276 303 true false false When normal 310 367 false false false It normal 336 363 true false false It normal 370 396 true false false Specify normal 399 430 true false false Measure normal 433 480 true false false ```
1 parent f9457b0 commit 071c369

34 files changed

+1013
-8
lines changed
 

‎ginkgo/main.go

+6
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ will output an executable file named `package.test`. This can be run directly o
111111
112112
ginkgo <path-to-package.test>
113113
114+
115+
To print an outline of Ginkgo specs and containers in a file:
116+
117+
gingko outline <filename>
118+
114119
To print out Ginkgo's version:
115120
116121
ginkgo version
@@ -172,6 +177,7 @@ func init() {
172177
Commands = append(Commands, BuildUnfocusCommand())
173178
Commands = append(Commands, BuildVersionCommand())
174179
Commands = append(Commands, BuildHelpCommand())
180+
Commands = append(Commands, BuildOutlineCommand())
175181
}
176182

177183
func main() {
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package example_test
2+
3+
import (
4+
fooginkgo "github.com/onsi/ginkgo"
5+
)
6+
7+
var _ = fooginkgo.Describe("NodotFixture", func() {
8+
fooginkgo.Describe("normal", func() {
9+
fooginkgo.It("normal", func() {
10+
fooginkgo.By("normal")
11+
fooginkgo.By("normal")
12+
13+
})
14+
})
15+
16+
fooginkgo.Context("normal", func() {
17+
fooginkgo.It("normal", func() {
18+
19+
})
20+
})
21+
22+
fooginkgo.When("normal", func() {
23+
fooginkgo.It("normal", func() {
24+
25+
})
26+
})
27+
28+
fooginkgo.It("normal", func() {
29+
30+
})
31+
32+
fooginkgo.Specify("normal", func() {
33+
34+
})
35+
36+
fooginkgo.Measure("normal", func(b Benchmarker) {
37+
38+
}, 2)
39+
40+
fooginkgo.DescribeTable("normal",
41+
func() {},
42+
fooginkgo.Entry("normal"),
43+
)
44+
45+
fooginkgo.DescribeTable("normal",
46+
func() {},
47+
fooginkgo.Entry("normal"),
48+
)
49+
})
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Name,Text,Start,End,Spec,Focused,Pending
2+
Describe,NodotFixture,79,728,false,false,false
3+
Describe,normal,124,257,false,false,false
4+
It,normal,164,253,true,false,false
5+
By,normal,199,221,false,false,false
6+
By,normal,225,247,false,false,false
7+
Context,normal,260,340,false,false,false
8+
It,normal,299,336,true,false,false
9+
When,normal,343,420,false,false,false
10+
It,normal,379,416,true,false,false
11+
It,normal,423,459,true,false,false
12+
Specify,normal,462,503,true,false,false
13+
Measure,normal,506,563,true,false,false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"name":"Describe","text":"NodotFixture","start":79,"end":728,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"Describe","text":"normal","start":124,"end":257,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"normal","start":164,"end":253,"spec":true,"focused":false,"pending":false,"nodes":[{"name":"By","text":"normal","start":199,"end":221,"spec":false,"focused":false,"pending":false},{"name":"By","text":"normal","start":225,"end":247,"spec":false,"focused":false,"pending":false}]}]},{"name":"Context","text":"normal","start":260,"end":340,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"normal","start":299,"end":336,"spec":true,"focused":false,"pending":false}]},{"name":"When","text":"normal","start":343,"end":420,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"normal","start":379,"end":416,"spec":true,"focused":false,"pending":false}]},{"name":"It","text":"normal","start":423,"end":459,"spec":true,"focused":false,"pending":false},{"name":"Specify","text":"normal","start":462,"end":503,"spec":true,"focused":false,"pending":false},{"name":"Measure","text":"normal","start":506,"end":563,"spec":true,"focused":false,"pending":false}]}]
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
set -o errexit
3+
set -o nounset
4+
5+
GINKGO=${GINKGO:-ginkgo}
6+
7+
input=${1:-""}
8+
for format in "csv" "json"; do
9+
set -o xtrace
10+
output="$(dirname $input)/$(basename $input).$format"
11+
tmp=$(mktemp ginkgo-outline-test.XXX)
12+
if "$GINKGO" outline --format="$format" "$input" 1>"$tmp"
13+
then mv "$tmp" "$output"
14+
else rm "$tmp"
15+
set +o xtrace
16+
fi
17+
done
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package example_test
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
. "github.com/onsi/ginkgo/extensions/table"
6+
)
7+
8+
var _ = Describe("unfocused", func() {
9+
FDescribe("focused", func() {
10+
It("focused", func() {
11+
By("focused")
12+
By("focused")
13+
})
14+
})
15+
16+
FContext("focused", func() {
17+
It("focused", func() {
18+
19+
})
20+
})
21+
22+
FWhen("focused", func() {
23+
It("focused", func() {
24+
25+
})
26+
})
27+
28+
FIt("focused", func() {
29+
30+
})
31+
32+
FSpecify("focused", func() {
33+
34+
})
35+
36+
FMeasure("focused", func(b Benchmarker) {
37+
38+
}, 2)
39+
40+
FDescribeTable("focused",
41+
func() {},
42+
Entry("focused"),
43+
)
44+
45+
DescribeTable("focused",
46+
func() {},
47+
FEntry("focused"),
48+
)
49+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Name,Text,Start,End,Spec,Focused,Pending
2+
Describe,unfocused,116,624,false,false,false
3+
FDescribe,focused,148,245,false,true,false
4+
It,focused,180,241,true,true,false
5+
By,focused,206,219,false,true,false
6+
By,focused,223,236,false,true,false
7+
FContext,focused,248,311,false,true,false
8+
It,focused,279,307,true,true,false
9+
FWhen,focused,314,374,false,true,false
10+
It,focused,342,370,true,true,false
11+
FIt,focused,377,405,true,true,false
12+
FSpecify,focused,408,441,true,true,false
13+
FMeasure,focused,444,493,true,true,false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"name":"Describe","text":"unfocused","start":116,"end":624,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"FDescribe","text":"focused","start":148,"end":245,"spec":false,"focused":true,"pending":false,"nodes":[{"name":"It","text":"focused","start":180,"end":241,"spec":true,"focused":true,"pending":false,"nodes":[{"name":"By","text":"focused","start":206,"end":219,"spec":false,"focused":true,"pending":false},{"name":"By","text":"focused","start":223,"end":236,"spec":false,"focused":true,"pending":false}]}]},{"name":"FContext","text":"focused","start":248,"end":311,"spec":false,"focused":true,"pending":false,"nodes":[{"name":"It","text":"focused","start":279,"end":307,"spec":true,"focused":true,"pending":false}]},{"name":"FWhen","text":"focused","start":314,"end":374,"spec":false,"focused":true,"pending":false,"nodes":[{"name":"It","text":"focused","start":342,"end":370,"spec":true,"focused":true,"pending":false}]},{"name":"FIt","text":"focused","start":377,"end":405,"spec":true,"focused":true,"pending":false},{"name":"FSpecify","text":"focused","start":408,"end":441,"spec":true,"focused":true,"pending":false},{"name":"FMeasure","text":"focused","start":444,"end":493,"spec":true,"focused":true,"pending":false}]}]
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package example_test
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
)
6+
7+
var _ = FDescribe("unfocused", func() {
8+
FContext("unfocused", func() {
9+
It("unfocused", func() {
10+
11+
})
12+
FIt("focused", func() {
13+
14+
})
15+
})
16+
17+
Context("unfocused", func() {
18+
FIt("focused", func() {
19+
20+
})
21+
It("unfocused", func() {
22+
23+
})
24+
})
25+
26+
FContext("focused", func() {
27+
It("focused", func() {
28+
29+
})
30+
It("focused", func() {
31+
32+
})
33+
})
34+
35+
PContext("unfocused", func() {
36+
FIt("unfocused", func() {
37+
By("unfocused")
38+
By("unfocused")
39+
})
40+
It("unfocused", func() {
41+
By("unfocused")
42+
By("unfocused")
43+
})
44+
})
45+
})
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Name,Text,Start,End,Spec,Focused,Pending
2+
FDescribe,unfocused,71,582,false,false,false
3+
FContext,unfocused,104,203,false,false,false
4+
It,unfocused,137,167,true,false,false
5+
FIt,focused,170,199,true,true,false
6+
Context,unfocused,206,304,false,false,false
7+
FIt,focused,238,267,true,true,false
8+
It,unfocused,270,300,true,false,false
9+
FContext,focused,307,401,false,true,false
10+
It,focused,338,366,true,true,false
11+
It,focused,369,397,true,true,false
12+
PContext,unfocused,404,579,false,false,true
13+
FIt,unfocused,437,505,true,false,true
14+
By,unfocused,466,481,false,false,true
15+
By,unfocused,485,500,false,false,true
16+
It,unfocused,508,575,true,false,true
17+
By,unfocused,536,551,false,false,true
18+
By,unfocused,555,570,false,false,true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"name":"FDescribe","text":"unfocused","start":71,"end":582,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"FContext","text":"unfocused","start":104,"end":203,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"unfocused","start":137,"end":167,"spec":true,"focused":false,"pending":false},{"name":"FIt","text":"focused","start":170,"end":199,"spec":true,"focused":true,"pending":false}]},{"name":"Context","text":"unfocused","start":206,"end":304,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"FIt","text":"focused","start":238,"end":267,"spec":true,"focused":true,"pending":false},{"name":"It","text":"unfocused","start":270,"end":300,"spec":true,"focused":false,"pending":false}]},{"name":"FContext","text":"focused","start":307,"end":401,"spec":false,"focused":true,"pending":false,"nodes":[{"name":"It","text":"focused","start":338,"end":366,"spec":true,"focused":true,"pending":false},{"name":"It","text":"focused","start":369,"end":397,"spec":true,"focused":true,"pending":false}]},{"name":"PContext","text":"unfocused","start":404,"end":579,"spec":false,"focused":false,"pending":true,"nodes":[{"name":"FIt","text":"unfocused","start":437,"end":505,"spec":true,"focused":false,"pending":true,"nodes":[{"name":"By","text":"unfocused","start":466,"end":481,"spec":false,"focused":false,"pending":true},{"name":"By","text":"unfocused","start":485,"end":500,"spec":false,"focused":false,"pending":true}]},{"name":"It","text":"unfocused","start":508,"end":575,"spec":true,"focused":false,"pending":true,"nodes":[{"name":"By","text":"unfocused","start":536,"end":551,"spec":false,"focused":false,"pending":true},{"name":"By","text":"unfocused","start":555,"end":570,"spec":false,"focused":false,"pending":true}]}]}]}]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package example_test
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
)
6+
7+
var _ = FDescribe("unfocused", func() {
8+
FContext("unfocused", func() {
9+
It("unfocused", func() {
10+
By("unfocused")
11+
By("unfocused")
12+
})
13+
FIt("focused", func() {
14+
By("focused")
15+
By("focused")
16+
})
17+
})
18+
19+
Context("unfocused", func() {
20+
FIt("focused", func() {
21+
22+
})
23+
It("unfocused", func() {
24+
25+
})
26+
})
27+
28+
FContext("focused", func() {
29+
It("focused", func() {
30+
31+
})
32+
It("focused", func() {
33+
34+
})
35+
})
36+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Name,Text,Start,End,Spec,Focused,Pending
2+
FDescribe,unfocused,71,474,false,false,false
3+
FContext,unfocused,104,273,false,false,false
4+
It,unfocused,137,204,true,false,false
5+
By,unfocused,165,180,false,false,false
6+
By,unfocused,184,199,false,false,false
7+
FIt,focused,207,269,true,true,false
8+
By,focused,234,247,false,true,false
9+
By,focused,251,264,false,true,false
10+
Context,unfocused,276,374,false,false,false
11+
FIt,focused,308,337,true,true,false
12+
It,unfocused,340,370,true,false,false
13+
FContext,focused,377,471,false,true,false
14+
It,focused,408,436,true,true,false
15+
It,focused,439,467,true,true,false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"name":"FDescribe","text":"unfocused","start":71,"end":474,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"FContext","text":"unfocused","start":104,"end":273,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"unfocused","start":137,"end":204,"spec":true,"focused":false,"pending":false,"nodes":[{"name":"By","text":"unfocused","start":165,"end":180,"spec":false,"focused":false,"pending":false},{"name":"By","text":"unfocused","start":184,"end":199,"spec":false,"focused":false,"pending":false}]},{"name":"FIt","text":"focused","start":207,"end":269,"spec":true,"focused":true,"pending":false,"nodes":[{"name":"By","text":"focused","start":234,"end":247,"spec":false,"focused":true,"pending":false},{"name":"By","text":"focused","start":251,"end":264,"spec":false,"focused":true,"pending":false}]}]},{"name":"Context","text":"unfocused","start":276,"end":374,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"FIt","text":"focused","start":308,"end":337,"spec":true,"focused":true,"pending":false},{"name":"It","text":"unfocused","start":340,"end":370,"spec":true,"focused":false,"pending":false}]},{"name":"FContext","text":"focused","start":377,"end":471,"spec":false,"focused":true,"pending":false,"nodes":[{"name":"It","text":"focused","start":408,"end":436,"spec":true,"focused":true,"pending":false},{"name":"It","text":"focused","start":439,"end":467,"spec":true,"focused":true,"pending":false}]}]}]
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package example_test
2+
3+
import (
4+
"github.com/onsi/ginkgo"
5+
)
6+
7+
var _ = ginkgo.Describe("NodotFixture", func() {
8+
ginkgo.Describe("normal", func() {
9+
ginkgo.It("normal", func() {
10+
ginkgo.By("normal")
11+
ginkgo.By("normal")
12+
})
13+
})
14+
15+
ginkgo.Context("normal", func() {
16+
ginkgo.It("normal", func() {
17+
18+
})
19+
})
20+
21+
ginkgo.When("normal", func() {
22+
ginkgo.It("normal", func() {
23+
24+
})
25+
})
26+
27+
ginkgo.It("normal", func() {
28+
29+
})
30+
31+
ginkgo.Specify("normal", func() {
32+
33+
})
34+
35+
ginkgo.Measure("normal", func(b Benchmarker) {
36+
37+
}, 2)
38+
39+
ginkgo.DescribeTable("normal",
40+
func() {},
41+
ginkgo.Entry("normal"),
42+
)
43+
44+
ginkgo.DescribeTable("normal",
45+
func() {},
46+
ginkgo.Entry("normal"),
47+
)
48+
})
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Name,Text,Start,End,Spec,Focused,Pending
2+
Describe,NodotFixture,69,669,false,false,false
3+
Describe,normal,111,231,false,false,false
4+
It,normal,148,227,true,false,false
5+
By,normal,180,199,false,false,false
6+
By,normal,203,222,false,false,false
7+
Context,normal,234,308,false,false,false
8+
It,normal,270,304,true,false,false
9+
When,normal,311,382,false,false,false
10+
It,normal,344,378,true,false,false
11+
It,normal,385,418,true,false,false
12+
Specify,normal,421,459,true,false,false
13+
Measure,normal,462,516,true,false,false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"name":"Describe","text":"NodotFixture","start":69,"end":669,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"Describe","text":"normal","start":111,"end":231,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"normal","start":148,"end":227,"spec":true,"focused":false,"pending":false,"nodes":[{"name":"By","text":"normal","start":180,"end":199,"spec":false,"focused":false,"pending":false},{"name":"By","text":"normal","start":203,"end":222,"spec":false,"focused":false,"pending":false}]}]},{"name":"Context","text":"normal","start":234,"end":308,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"normal","start":270,"end":304,"spec":true,"focused":false,"pending":false}]},{"name":"When","text":"normal","start":311,"end":382,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"normal","start":344,"end":378,"spec":true,"focused":false,"pending":false}]},{"name":"It","text":"normal","start":385,"end":418,"spec":true,"focused":false,"pending":false},{"name":"Specify","text":"normal","start":421,"end":459,"spec":true,"focused":false,"pending":false},{"name":"Measure","text":"normal","start":462,"end":516,"spec":true,"focused":false,"pending":false}]}]
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package example_test
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
. "github.com/onsi/ginkgo/extensions/table"
6+
)
7+
8+
var _ = Describe("NormalFixture", func() {
9+
Describe("normal", func() {
10+
It("normal", func() {
11+
By("step 1")
12+
By("step 2")
13+
})
14+
})
15+
16+
Context("normal", func() {
17+
It("normal", func() {
18+
19+
})
20+
})
21+
22+
When("normal", func() {
23+
It("normal", func() {
24+
25+
})
26+
})
27+
28+
It("normal", func() {
29+
30+
})
31+
32+
Specify("normal", func() {
33+
34+
})
35+
36+
Measure("normal", func(b Benchmarker) {
37+
38+
}, 2)
39+
40+
DescribeTable("normal",
41+
func() {},
42+
Entry("normal"),
43+
)
44+
45+
DescribeTable("normal",
46+
func() {},
47+
Entry("normal"),
48+
)
49+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Name,Text,Start,End,Spec,Focused,Pending
2+
Describe,NormalFixture,116,605,false,false,false
3+
Describe,normal,152,244,false,false,false
4+
It,normal,182,240,true,false,false
5+
By,step 1,207,219,false,false,false
6+
By,step 2,223,235,false,false,false
7+
Context,normal,247,307,false,false,false
8+
It,normal,276,303,true,false,false
9+
When,normal,310,367,false,false,false
10+
It,normal,336,363,true,false,false
11+
It,normal,370,396,true,false,false
12+
Specify,normal,399,430,true,false,false
13+
Measure,normal,433,480,true,false,false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"name":"Describe","text":"NormalFixture","start":116,"end":605,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"Describe","text":"normal","start":152,"end":244,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"normal","start":182,"end":240,"spec":true,"focused":false,"pending":false,"nodes":[{"name":"By","text":"step 1","start":207,"end":219,"spec":false,"focused":false,"pending":false},{"name":"By","text":"step 2","start":223,"end":235,"spec":false,"focused":false,"pending":false}]}]},{"name":"Context","text":"normal","start":247,"end":307,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"normal","start":276,"end":303,"spec":true,"focused":false,"pending":false}]},{"name":"When","text":"normal","start":310,"end":367,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"It","text":"normal","start":336,"end":363,"spec":true,"focused":false,"pending":false}]},{"name":"It","text":"normal","start":370,"end":396,"spec":true,"focused":false,"pending":false},{"name":"Specify","text":"normal","start":399,"end":430,"spec":true,"focused":false,"pending":false},{"name":"Measure","text":"normal","start":433,"end":480,"spec":true,"focused":false,"pending":false}]}]
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package example_test
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
. "github.com/onsi/ginkgo/extensions/table"
6+
)
7+
8+
var _ = Describe("PendingFixture", func() {
9+
PDescribe("pending", func() {
10+
It("pending", func() {
11+
By("pending")
12+
By("pending")
13+
})
14+
})
15+
16+
PContext("pending", func() {
17+
It("pending", func() {
18+
19+
})
20+
})
21+
22+
PWhen("pending", func() {
23+
It("pending", func() {
24+
25+
})
26+
})
27+
28+
PIt("pending", func() {
29+
30+
})
31+
32+
PSpecify("pending", func() {
33+
34+
})
35+
36+
PMeasure("pending", func(b Benchmarker) {
37+
38+
}, 2)
39+
40+
PDescribeTable("pending",
41+
func() {},
42+
Entry("pending"),
43+
)
44+
45+
DescribeTable("pending",
46+
func() {},
47+
PEntry("pending"),
48+
)
49+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Name,Text,Start,End,Spec,Focused,Pending
2+
Describe,PendingFixture,116,629,false,false,false
3+
PDescribe,pending,153,250,false,false,true
4+
It,pending,185,246,true,false,true
5+
By,pending,211,224,false,false,true
6+
By,pending,228,241,false,false,true
7+
PContext,pending,253,316,false,false,true
8+
It,pending,284,312,true,false,true
9+
PWhen,pending,319,379,false,false,true
10+
It,pending,347,375,true,false,true
11+
PIt,pending,382,410,true,false,true
12+
PSpecify,pending,413,446,true,false,true
13+
PMeasure,pending,449,498,true,false,true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"name":"Describe","text":"PendingFixture","start":116,"end":629,"spec":false,"focused":false,"pending":false,"nodes":[{"name":"PDescribe","text":"pending","start":153,"end":250,"spec":false,"focused":false,"pending":true,"nodes":[{"name":"It","text":"pending","start":185,"end":246,"spec":true,"focused":false,"pending":true,"nodes":[{"name":"By","text":"pending","start":211,"end":224,"spec":false,"focused":false,"pending":true},{"name":"By","text":"pending","start":228,"end":241,"spec":false,"focused":false,"pending":true}]}]},{"name":"PContext","text":"pending","start":253,"end":316,"spec":false,"focused":false,"pending":true,"nodes":[{"name":"It","text":"pending","start":284,"end":312,"spec":true,"focused":false,"pending":true}]},{"name":"PWhen","text":"pending","start":319,"end":379,"spec":false,"focused":false,"pending":true,"nodes":[{"name":"It","text":"pending","start":347,"end":375,"spec":true,"focused":false,"pending":true}]},{"name":"PIt","text":"pending","start":382,"end":410,"spec":true,"focused":false,"pending":true},{"name":"PSpecify","text":"pending","start":413,"end":446,"spec":true,"focused":false,"pending":true},{"name":"PMeasure","text":"pending","start":449,"end":498,"spec":true,"focused":false,"pending":true}]}]
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package example_test
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
. "github.com/onsi/gomega"
6+
7+
"testing"
8+
)
9+
10+
func TestExample(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Example Suite")
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Name,Text,Start,End,Spec,Focused,Pending
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]

‎ginkgo/outline/ginkgo.go

+209
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
package outline
2+
3+
import (
4+
"go/ast"
5+
"go/token"
6+
"strconv"
7+
)
8+
9+
const (
10+
// undefinedTextAlt is used if the spec/container text cannot be derived
11+
undefinedTextAlt = "undefined"
12+
)
13+
14+
// ginkgoMetadata holds useful bits of information for every entry in the outline
15+
type ginkgoMetadata struct {
16+
// Name is the spec or container function name, e.g. `Describe` or `It`
17+
Name string `json:"name"`
18+
19+
// Text is the `text` argument passed to specs, and some containers
20+
Text string `json:"text"`
21+
22+
// Start is the position of first character of the spec or container block
23+
Start token.Pos `json:"start"`
24+
25+
// End is the position of first character immediately after the spec or container block
26+
End token.Pos `json:"end"`
27+
28+
Spec bool `json:"spec"`
29+
Focused bool `json:"focused"`
30+
Pending bool `json:"pending"`
31+
}
32+
33+
// ginkgoNode is used to construct the outline as a tree
34+
type ginkgoNode struct {
35+
ginkgoMetadata
36+
Nodes []*ginkgoNode `json:"nodes,omitempty"`
37+
}
38+
39+
type walkFunc func(n *ginkgoNode)
40+
41+
func (n *ginkgoNode) PreOrder(f walkFunc) {
42+
f(n)
43+
for _, m := range n.Nodes {
44+
m.PreOrder(f)
45+
}
46+
}
47+
48+
func (n *ginkgoNode) PostOrder(f walkFunc) {
49+
for _, m := range n.Nodes {
50+
m.PostOrder(f)
51+
}
52+
f(n)
53+
}
54+
55+
func (n *ginkgoNode) Walk(pre, post walkFunc) {
56+
pre(n)
57+
for _, m := range n.Nodes {
58+
m.Walk(pre, post)
59+
}
60+
post(n)
61+
}
62+
63+
// PropagateInheritedProperties propagates the Pending and Focused properties
64+
// through the subtree rooted at n.
65+
func (n *ginkgoNode) PropagateInheritedProperties() {
66+
n.PreOrder(func(thisNode *ginkgoNode) {
67+
for _, descendantNode := range thisNode.Nodes {
68+
if thisNode.Pending {
69+
descendantNode.Pending = true
70+
descendantNode.Focused = false
71+
}
72+
if thisNode.Focused && !descendantNode.Pending {
73+
descendantNode.Focused = true
74+
}
75+
}
76+
})
77+
}
78+
79+
// BackpropagateUnfocus propagates the Focused property through the subtree
80+
// rooted at n. It applies the rule described in the Ginkgo docs:
81+
// > Nested programmatically focused specs follow a simple rule: if a
82+
// > leaf-node is marked focused, any of its ancestor nodes that are marked
83+
// > focus will be unfocused.
84+
func (n *ginkgoNode) BackpropagateUnfocus() {
85+
focusedSpecInSubtreeStack := []bool{}
86+
n.PostOrder(func(thisNode *ginkgoNode) {
87+
if thisNode.Spec {
88+
focusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, thisNode.Focused)
89+
return
90+
}
91+
focusedSpecInSubtree := false
92+
for range thisNode.Nodes {
93+
focusedSpecInSubtree = focusedSpecInSubtree || focusedSpecInSubtreeStack[len(focusedSpecInSubtreeStack)-1]
94+
focusedSpecInSubtreeStack = focusedSpecInSubtreeStack[0 : len(focusedSpecInSubtreeStack)-1]
95+
}
96+
focusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, focusedSpecInSubtree)
97+
if focusedSpecInSubtree {
98+
thisNode.Focused = false
99+
}
100+
})
101+
102+
}
103+
104+
func ginkgoIdentNameFromCallExpr(ce *ast.CallExpr, ginkgoImportName string) (string, bool) {
105+
switch ex := ce.Fun.(type) {
106+
case *ast.Ident:
107+
if ginkgoImportName != "." {
108+
return "", false
109+
}
110+
return ex.Name, true
111+
case *ast.SelectorExpr:
112+
pkgID, ok := ex.X.(*ast.Ident)
113+
if !ok {
114+
return "", false
115+
}
116+
// A package identifier is top-level, so Obj must be nil
117+
if pkgID.Obj != nil {
118+
return "", false
119+
}
120+
if ginkgoImportName != pkgID.Name {
121+
return "", false
122+
}
123+
if ex.Sel == nil {
124+
return "", false
125+
}
126+
return ex.Sel.Name, true
127+
default:
128+
return "", false
129+
}
130+
}
131+
132+
// ginkgoNodeFromCallExpr derives an outline entry from a go AST subtree
133+
// corresponding to a Ginkgo container or spec.
134+
func ginkgoNodeFromCallExpr(ce *ast.CallExpr, ginkgoImportName string) (*ginkgoNode, bool) {
135+
identName, ok := ginkgoIdentNameFromCallExpr(ce, ginkgoImportName)
136+
if !ok {
137+
return nil, false
138+
}
139+
140+
n := ginkgoNode{}
141+
n.Name = identName
142+
n.Start = ce.Pos()
143+
n.End = ce.End()
144+
145+
switch identName {
146+
case "It", "Measure", "Specify":
147+
n.Spec = true
148+
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
149+
case "FIt", "FMeasure", "FSpecify":
150+
n.Spec = true
151+
n.Focused = true
152+
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
153+
case "PIt", "PMeasure", "PSpecify", "XIt", "XMeasure", "XSpecify":
154+
n.Spec = true
155+
n.Pending = true
156+
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
157+
case "Context", "Describe", "When":
158+
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
159+
case "FContext", "FDescribe", "FWhen":
160+
n.Focused = true
161+
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
162+
case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen":
163+
n.Pending = true
164+
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
165+
case "By":
166+
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
167+
case "AfterEach", "BeforeEach":
168+
case "JustAfterEach", "JustBeforeEach":
169+
case "AfterSuite", "BeforeSuite":
170+
case "SynchronizedAfterSuite", "SynchronizedBeforeSuite":
171+
default:
172+
return nil, false
173+
}
174+
return &n, true
175+
}
176+
177+
// textOrAltFromCallExpr tries to derive the "text" of a Ginkgo spec or
178+
// container. If it cannot derive it, it returns the alt text.
179+
func textOrAltFromCallExpr(ce *ast.CallExpr, alt string) string {
180+
text, defined := textFromCallExpr(ce)
181+
if !defined {
182+
return alt
183+
}
184+
return text
185+
}
186+
187+
// textFromCallExpr tries to derive the "text" of a Ginkgo spec or container. If
188+
// it cannot derive it, it returns false.
189+
func textFromCallExpr(ce *ast.CallExpr) (string, bool) {
190+
if len(ce.Args) < 1 {
191+
return "", false
192+
}
193+
text, ok := ce.Args[0].(*ast.BasicLit)
194+
if !ok {
195+
return "", false
196+
}
197+
switch text.Kind {
198+
case token.CHAR, token.STRING:
199+
// For token.CHAR and token.STRING, Value is quoted
200+
unquoted, err := strconv.Unquote(text.Value)
201+
if err != nil {
202+
// If unquoting fails, just use the raw Value
203+
return text.Value, true
204+
}
205+
return unquoted, true
206+
default:
207+
return text.Value, true
208+
}
209+
}

‎ginkgo/outline/import.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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+
// Most of the required functions were available in the
6+
// "golang.org/x/tools/go/ast/astutil" package, but not exported.
7+
// They were copied from https://github.com/golang/tools/blob/2b0845dc783e36ae26d683f4915a5840ef01ab0f/go/ast/astutil/imports.go
8+
9+
package outline
10+
11+
import (
12+
"go/ast"
13+
"strconv"
14+
"strings"
15+
)
16+
17+
// importNameForPackage returns the import name for the package. If the package
18+
// is not imported, it returns false. Examples:
19+
// How package is imported -> Import Name
20+
// "import example.com/pkg/foo" -> "foo"
21+
// "import fooalias example.com/pkg/foo" -> "fooalias"
22+
// "import . example.com/pkg/foo" -> "."
23+
func importNameForPackage(f *ast.File, path string) (string, bool) {
24+
spec := importSpec(f, path)
25+
if spec == nil {
26+
return "", false
27+
}
28+
name := spec.Name.String()
29+
if name == "<nil>" {
30+
// If the package name is not explicitly specified,
31+
// make an educated guess. This is not guaranteed to be correct.
32+
lastSlash := strings.LastIndex(path, "/")
33+
if lastSlash == -1 {
34+
name = path
35+
} else {
36+
name = path[lastSlash+1:]
37+
}
38+
}
39+
return name, true
40+
}
41+
42+
// importSpec returns the import spec if f imports path,
43+
// or nil otherwise.
44+
func importSpec(f *ast.File, path string) *ast.ImportSpec {
45+
for _, s := range f.Imports {
46+
if importPath(s) == path {
47+
return s
48+
}
49+
}
50+
return nil
51+
}
52+
53+
// importPath returns the unquoted import path of s,
54+
// or "" if the path is not properly quoted.
55+
func importPath(s *ast.ImportSpec) string {
56+
t, err := strconv.Unquote(s.Path.Value)
57+
if err != nil {
58+
return ""
59+
}
60+
return t
61+
}

‎ginkgo/outline/outline.go

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package outline
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"go/ast"
7+
"strings"
8+
9+
"golang.org/x/tools/go/ast/inspector"
10+
)
11+
12+
const (
13+
// ginkgoImportPath is the well-known ginkgo import path
14+
ginkgoImportPath = "github.com/onsi/ginkgo"
15+
)
16+
17+
// FromASTFile returns an outline for a Ginkgo test source file
18+
func FromASTFile(src *ast.File) (*outline, error) {
19+
ginkgoImportName, ok := importNameForPackage(src, ginkgoImportPath)
20+
if !ok {
21+
return nil, fmt.Errorf("file does not import %s", ginkgoImportPath)
22+
}
23+
root := ginkgoNode{
24+
Nodes: []*ginkgoNode{},
25+
}
26+
stack := []*ginkgoNode{&root}
27+
28+
ispr := inspector.New([]*ast.File{src})
29+
ispr.Nodes([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node, push bool) bool {
30+
if push {
31+
// Pre-order traversal
32+
ce, ok := node.(*ast.CallExpr)
33+
if !ok {
34+
// Because `Nodes` calls this function only when the node is an
35+
// ast.CallExpr, this should never happen
36+
panic(fmt.Errorf("node starting at %d, ending at %d is not an *ast.CallExpr", node.Pos(), node.End()))
37+
}
38+
gn, ok := ginkgoNodeFromCallExpr(ce, ginkgoImportName)
39+
if !ok {
40+
// Node is not a Ginkgo spec or container, continue
41+
return true
42+
}
43+
44+
parent := stack[len(stack)-1]
45+
parent.Nodes = append(parent.Nodes, gn)
46+
47+
stack = append(stack, gn)
48+
return true
49+
}
50+
// Post-order traversal
51+
lastVisitedGinkgoNode := stack[len(stack)-1]
52+
if node.Pos() != lastVisitedGinkgoNode.Start || node.End() != lastVisitedGinkgoNode.End {
53+
// Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue
54+
return true
55+
}
56+
stack = stack[0 : len(stack)-1]
57+
return true
58+
})
59+
60+
// Derive the final focused property for all nodes. This must be done
61+
// _before_ propagating the inherited focused property.
62+
root.BackpropagateUnfocus()
63+
// Now, propagate inherited properties, including focused and pending.
64+
root.PropagateInheritedProperties()
65+
66+
return &outline{root}, nil
67+
}
68+
69+
type outline struct {
70+
ginkgoNode
71+
}
72+
73+
func (o *outline) MarshalJSON() ([]byte, error) {
74+
return json.Marshal(o.Nodes)
75+
}
76+
77+
// String returns a CSV-formatted outline. Spec or container are output in
78+
// depth-first order.
79+
func (o *outline) String() string {
80+
return o.StringIndent(0)
81+
}
82+
83+
// StringIndent returns a CSV-formated outline, but every line is indented by
84+
// one 'width' of spaces for every level of nesting.
85+
func (o *outline) StringIndent(width int) string {
86+
var b strings.Builder
87+
b.WriteString("Name,Text,Start,End,Spec,Focused,Pending\n")
88+
89+
currentIndent := 0
90+
pre := func(n *ginkgoNode) {
91+
b.WriteString(fmt.Sprintf("%*s", currentIndent, ""))
92+
b.WriteString(fmt.Sprintf("%s,%s,%d,%d,%t,%t,%t\n", n.Name, n.Text, n.Start, n.End, n.Spec, n.Focused, n.Pending))
93+
currentIndent += width
94+
}
95+
post := func(n *ginkgoNode) {
96+
currentIndent -= width
97+
}
98+
for _, n := range o.Nodes {
99+
n.Walk(pre, post)
100+
}
101+
return b.String()
102+
}

‎ginkgo/outline/outline_suite_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package outline_test
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestOutline(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Outline Suite")
13+
}

‎ginkgo/outline/outline_test.go

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package outline
2+
3+
import (
4+
"encoding/json"
5+
"go/parser"
6+
"go/token"
7+
"io/ioutil"
8+
"log"
9+
"path/filepath"
10+
11+
. "github.com/onsi/ginkgo/extensions/table"
12+
. "github.com/onsi/gomega"
13+
)
14+
15+
var _ = DescribeTable("Validate outline from file with",
16+
func(srcFilename, jsonOutlineFilename, csvOutlineFilename string) {
17+
fset := token.NewFileSet()
18+
astFile, err := parser.ParseFile(fset, filepath.Join("_testdata", srcFilename), nil, 0)
19+
Expect(err).To(BeNil(), "error parsing source: %s", err)
20+
21+
if err != nil {
22+
log.Fatalf("error parsing source: %s", err)
23+
}
24+
25+
o, err := FromASTFile(astFile)
26+
Expect(err).To(BeNil(), "error creating outline: %s", err)
27+
28+
gotJSON, err := json.MarshalIndent(o, "", " ")
29+
Expect(err).To(BeNil(), "error marshalling outline to json: %s", err)
30+
31+
wantJSON, err := ioutil.ReadFile(filepath.Join("_testdata", jsonOutlineFilename))
32+
Expect(err).To(BeNil(), "error reading JSON outline fixture: %s", err)
33+
34+
Expect(gotJSON).To(MatchJSON(wantJSON))
35+
36+
gotCSV := o.String()
37+
38+
wantCSV, err := ioutil.ReadFile(filepath.Join("_testdata", csvOutlineFilename))
39+
Expect(err).To(BeNil(), "error reading CSV outline fixture: %s", err)
40+
41+
Expect(gotCSV).To(Equal(string(wantCSV)))
42+
},
43+
// To add a test:
44+
// 1. Create the input, e.g., `myspecialcase_test.go`
45+
// 2. Create the sample CSV and JSON results: Run `bash ./_testdata/create_result.sh ./_testdata/myspecialcase_test.go`
46+
// 3. Add an Entry below, by copying an existing one, and substituting `myspecialcase` where needed.
47+
// To re-create the sample results for a test:
48+
// 1. Run `bash ./_testdata/create_result.sh ./testdata/myspecialcase_test.go`
49+
// To re-create the sample results for all tests:
50+
// 1. Run `for name in ./_testdata/*_test.go; do bash ./_testdata/create_result.sh $name; done`
51+
Entry("normal import of ginkgo package (no dot, no alias), normal container and specs", "nodot_test.go", "nodot_test.go.json", "nodot_test.go.csv"),
52+
Entry("aliased import of ginkgo package, normal container and specs", "alias_test.go", "alias_test.go.json", "alias_test.go.csv"),
53+
Entry("normal containers and specs", "normal_test.go", "normal_test.go.json", "normal_test.go.csv"),
54+
Entry("focused containers and specs", "focused_test.go", "focused_test.go.json", "focused_test.go.csv"),
55+
Entry("pending containers and specs", "pending_test.go", "pending_test.go.json", "pending_test.go.csv"),
56+
Entry("nested focused containers and specs", "nestedfocused_test.go", "nestedfocused_test.go.json", "nestedfocused_test.go.csv"),
57+
Entry("mixed focused containers and specs", "mixed_test.go", "mixed_test.go.json", "mixed_test.go.csv"),
58+
Entry("suite setup", "suite_test.go", "suite_test.go.json", "suite_test.go.csv"),
59+
)

‎ginkgo/outline_command.go

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"flag"
6+
"fmt"
7+
"go/parser"
8+
"go/token"
9+
"os"
10+
11+
"github.com/onsi/ginkgo/ginkgo/outline"
12+
)
13+
14+
const (
15+
// indentWidth is the width used by the 'indent' output
16+
indentWidth = 4
17+
)
18+
19+
func BuildOutlineCommand() *Command {
20+
const defaultFormat = "csv"
21+
var format string
22+
flagSet := flag.NewFlagSet("outline", flag.ExitOnError)
23+
flagSet.StringVar(&format, "format", defaultFormat, "Format of outline. Accepted: 'csv', 'indent', 'json'")
24+
return &Command{
25+
Name: "outline",
26+
FlagSet: flagSet,
27+
UsageCommand: "ginkgo outline <filename>",
28+
Usage: []string{
29+
"Outline of Ginkgo symbols for the file",
30+
},
31+
Command: func(args []string, additionalArgs []string) {
32+
outlineFile(args, format)
33+
},
34+
}
35+
}
36+
37+
func outlineFile(args []string, format string) {
38+
if len(args) != 1 {
39+
println("usage: ginkgo outline <filename>")
40+
os.Exit(1)
41+
}
42+
43+
filename := args[0]
44+
fset := token.NewFileSet()
45+
46+
src, err := parser.ParseFile(fset, filename, nil, 0)
47+
if err != nil {
48+
println(fmt.Sprintf("error parsing source: %s", err))
49+
os.Exit(1)
50+
}
51+
52+
o, err := outline.FromASTFile(src)
53+
if err != nil {
54+
println(fmt.Sprintf("error creating outline: %s", err))
55+
os.Exit(1)
56+
}
57+
58+
var oerr error
59+
switch format {
60+
case "csv":
61+
_, oerr = fmt.Print(o)
62+
case "indent":
63+
_, oerr = fmt.Print(o.StringIndent(indentWidth))
64+
case "json":
65+
b, err := json.Marshal(o)
66+
if err != nil {
67+
println(fmt.Sprintf("error marshalling to json: %s", err))
68+
}
69+
_, oerr = fmt.Println(string(b))
70+
default:
71+
complainAndQuit(fmt.Sprintf("format %s not accepted", format))
72+
}
73+
if oerr != nil {
74+
println(fmt.Sprintf("error writing outline: %s", oerr))
75+
os.Exit(1)
76+
}
77+
}

‎go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ require (
44
github.com/fsnotify/fsnotify v1.4.9 // indirect
55
github.com/nxadm/tail v1.4.4
66
github.com/onsi/gomega v1.10.1
7-
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299
8-
golang.org/x/text v0.3.2 // indirect
7+
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f
8+
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e
99
)
1010

1111
go 1.13

‎go.sum

+22-6
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,41 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
2121
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
2222
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
2323
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
24+
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
2425
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
26+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
27+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
28+
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
2529
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
26-
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
30+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
31+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
2732
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
33+
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
34+
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
2835
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
36+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
37+
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
2938
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
3039
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
40+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3141
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3242
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3343
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3444
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
35-
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
36-
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
45+
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
46+
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3747
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
38-
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
39-
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
48+
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
49+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
4050
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
41-
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
51+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
52+
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE=
53+
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
54+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
55+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
4256
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
57+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
58+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
4359
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
4460
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
4561
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

0 commit comments

Comments
 (0)
Please sign in to comment.