Merge lp:~rogpeppe/gocheck/add-list-flag into lp:gocheck

Proposed by Roger Peppe
Status: Merged
Merged at revision: 82
Proposed branch: lp:~rogpeppe/gocheck/add-list-flag
Merge into: lp:gocheck
Diff against target: 367 lines (+105/-61)
8 files modified
bootstrap_test.go (+1/-1)
checkers.go (+1/-2)
foundation_test.go (+3/-3)
gocheck.go (+24/-32)
gocheck_test.go (+4/-4)
helpers_test.go (+1/-2)
run.go (+40/-5)
run_test.go (+31/-12)
To merge this branch: bzr merge lp:~rogpeppe/gocheck/add-list-flag
Reviewer Review Type Date Requested Status
Gustavo Niemeyer Pending
Review via email: mp+94937@code.launchpad.net

Description of the change

gocheck: add -gocheck.list flag

https://codereview.appspot.com/5705044/

To post a comment you must log in.
Revision history for this message
Roger Peppe (rogpeppe) wrote :

Reviewers: mp+94937_code.launchpad.net,

Message:
Please take a look.

Description:
Also make the filter flag consistent with gotest by naming
it "gocheck.run", and make it easier to see what will
be matched against by matching against the list output.

https://code.launchpad.net/~rogpeppe/gocheck/add-list-flag/+merge/94937

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/5705044/

Affected files:
   M gocheck.go
   M run.go
   M run_test.go

Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

Please separate the two changes. We can't modify .f before the next
announced release.

https://codereview.appspot.com/5705044/

Revision history for this message
Roger Peppe (rogpeppe) wrote :
lp:~rogpeppe/gocheck/add-list-flag updated
76. By Roger Peppe

revert -gocheck.run to -gocheck.f

Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

https://codereview.appspot.com/5705044/diff/2002/gocheck.go
File gocheck.go (left):

https://codereview.appspot.com/5705044/diff/2002/gocheck.go#oldcode554
gocheck.go:554: filterRegexp.MatchString(suiteName+"."+testName))
We can't change the behavior of .f before the next announced release.

https://codereview.appspot.com/5705044/diff/2002/run.go
File run.go (right):

https://codereview.appspot.com/5705044/diff/2002/run.go#newcode28
run.go:28: "Regular expression selecting what to run (use -gocheck.list
to see what this matches against)")
Please revert this. -gocheck.list is documented below already.

https://codereview.appspot.com/5705044/diff/2002/run_test.go
File run_test.go (right):

https://codereview.appspot.com/5705044/diff/2002/run_test.go#newcode296
run_test.go:296: "*gocheck_test.FixtureHelper.Test2",
What is this "*" doing there?

https://codereview.appspot.com/5705044/

Revision history for this message
Roger Peppe (rogpeppe) wrote :

https://codereview.appspot.com/5705044/diff/2002/gocheck.go
File gocheck.go (left):

https://codereview.appspot.com/5705044/diff/2002/gocheck.go#oldcode554
gocheck.go:554: filterRegexp.MatchString(suiteName+"."+testName))
On 2012/02/28 14:17:27, niemeyer wrote:
> We can't change the behavior of .f before the next announced release.

FWIW the new behaviour is exactly the old behaviour if the user doesn't
use ^ or $ in their regexp. none of the tests needed to change, which is
a useful indicator.

i'll revert nonetheless.

https://codereview.appspot.com/5705044/diff/2002/run.go
File run.go (right):

https://codereview.appspot.com/5705044/diff/2002/run.go#newcode28
run.go:28: "Regular expression selecting what to run (use -gocheck.list
to see what this matches against)")
On 2012/02/28 14:17:27, niemeyer wrote:
> Please revert this. -gocheck.list is documented below already.

AFAIK the text that the regexp matches is not documented anywhere (for
instance i didn't know that you could filter on a suite name until i
read the source code). if this isn't a reasonable place to document the
behaviour, perhaps you could suggest another.

https://codereview.appspot.com/5705044/diff/2002/run_test.go
File run_test.go (right):

https://codereview.appspot.com/5705044/diff/2002/run_test.go#newcode296
run_test.go:296: "*gocheck_test.FixtureHelper.Test2",
On 2012/02/28 14:17:27, niemeyer wrote:
> What is this "*" doing there?

the method is on a pointer type. i've found this info useful in the
past. perhaps it shouldn't be indicated though.

https://codereview.appspot.com/5705044/

Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

https://codereview.appspot.com/5705044/diff/2002/gocheck.go
File gocheck.go (left):

https://codereview.appspot.com/5705044/diff/2002/gocheck.go#oldcode554
gocheck.go:554: filterRegexp.MatchString(suiteName+"."+testName))
On 2012/02/28 14:37:20, rog wrote:
> On 2012/02/28 14:17:27, niemeyer wrote:
> > We can't change the behavior of .f before the next announced
release.

> FWIW the new behaviour is exactly the old behaviour if the user
doesn't use ^ or
> $ in their regexp. none of the tests needed to change, which is a
useful
> indicator.

> i'll revert nonetheless.

The new behavior is exactly the old behavior except when it's not.

https://codereview.appspot.com/5705044/diff/2002/run.go
File run.go (right):

https://codereview.appspot.com/5705044/diff/2002/run.go#newcode28
run.go:28: "Regular expression selecting what to run (use -gocheck.list
to see what this matches against)")
On 2012/02/28 14:37:20, rog wrote:
> On 2012/02/28 14:17:27, niemeyer wrote:
> > Please revert this. -gocheck.list is documented below already.

> AFAIK the text that the regexp matches is not documented anywhere (for
instance
> i didn't know that you could filter on a suite name until i read the
source
> code). if this isn't a reasonable place to document the behaviour,
perhaps you
> could suggest another.

Documenting the -gocheck.list option twice isn't a good way to do what
you want. You can say something like:

"Regular expression selecting which test and/or suite to run"

Also, when you see a test name in a verbose run or on a failure, that
format works, so it's not like it's entirely magical.

https://codereview.appspot.com/5705044/diff/2002/run_test.go
File run_test.go (right):

https://codereview.appspot.com/5705044/diff/2002/run_test.go#newcode296
run_test.go:296: "*gocheck_test.FixtureHelper.Test2",
On 2012/02/28 14:37:20, rog wrote:
> On 2012/02/28 14:17:27, niemeyer wrote:
> > What is this "*" doing there?

> the method is on a pointer type. i've found this info useful in the
past.
> perhaps it shouldn't be indicated though.

Yeah, not relevant here.

https://codereview.appspot.com/5705044/

Revision history for this message
Roger Peppe (rogpeppe) wrote :
Revision history for this message
Roger Peppe (rogpeppe) wrote :

PTAL

https://codereview.appspot.com/5705044/diff/2002/gocheck.go
File gocheck.go (left):

https://codereview.appspot.com/5705044/diff/2002/gocheck.go#oldcode554
gocheck.go:554: filterRegexp.MatchString(suiteName+"."+testName))
On 2012/02/28 14:45:03, niemeyer wrote:
> On 2012/02/28 14:37:20, rog wrote:
> > On 2012/02/28 14:17:27, niemeyer wrote:
> > > We can't change the behavior of .f before the next announced
release.
> >
> > FWIW the new behaviour is exactly the old behaviour if the user
doesn't use ^
> or
> > $ in their regexp. none of the tests needed to change, which is a
useful
> > indicator.
> >
> > i'll revert nonetheless.

> The new behavior is exactly the old behavior except when it's not.

i've reverted to the old behaviour, but left the implementation similar
to this, so that the simplification can be made easily later.

https://codereview.appspot.com/5705044/diff/2002/run.go
File run.go (right):

https://codereview.appspot.com/5705044/diff/2002/run.go#newcode28
run.go:28: "Regular expression selecting what to run (use -gocheck.list
to see what this matches against)")
On 2012/02/28 14:45:03, niemeyer wrote:
> On 2012/02/28 14:37:20, rog wrote:
> > On 2012/02/28 14:17:27, niemeyer wrote:
> > > Please revert this. -gocheck.list is documented below already.
> >
> > AFAIK the text that the regexp matches is not documented anywhere
(for
> instance
> > i didn't know that you could filter on a suite name until i read the
source
> > code). if this isn't a reasonable place to document the behaviour,
perhaps you
> > could suggest another.

> Documenting the -gocheck.list option twice isn't a good way to do what
you want.

that wasn't what i was trying to do. i was trying to document that the
gocheck.f flag matches against the text produced by list, not what list
does.

i like the idea that {go test -gocheck.list | grep pat} will print
exactly the same tests that {go test -gocheck.f pat} will run.

> You can say something like:

> "Regular expression selecting which test and/or suite to run"

> Also, when you see a test name in a verbose run or on a failure, that
format
> works, so it's not like it's entirely magical.

the fact that it tries the regexp against three pieces of text was
unexpected to me. i hope that you think it's a reasonable idea in the
future to standardise on a single form of text to match against - easier
to document and to use IMHO.

https://codereview.appspot.com/5705044/diff/2002/run_test.go
File run_test.go (right):

https://codereview.appspot.com/5705044/diff/2002/run_test.go#newcode296
run_test.go:296: "*gocheck_test.FixtureHelper.Test2",
On 2012/02/28 14:45:03, niemeyer wrote:
> On 2012/02/28 14:37:20, rog wrote:
> > On 2012/02/28 14:17:27, niemeyer wrote:
> > > What is this "*" doing there?
> >
> > the method is on a pointer type. i've found this info useful in the
past.
> > perhaps it shouldn't be indicated though.

> Yeah, not relevant here.

Done.

https://codereview.appspot.com/5705044/

lp:~rogpeppe/gocheck/add-list-flag updated
77. By Roger Peppe

changes in response to review

78. By Roger Peppe

go fmt

Revision history for this message
Roger Peppe (rogpeppe) wrote :
lp:~rogpeppe/gocheck/add-list-flag updated
79. By Roger Peppe

a little test

Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

LGTM.. I'm merging this with tip and integrating.

https://codereview.appspot.com/5705044/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bootstrap_test.go'
2--- bootstrap_test.go 2011-11-08 15:09:50 +0000
3+++ bootstrap_test.go 2012-03-14 14:30:29 +0000
4@@ -13,9 +13,9 @@
5 package gocheck_test
6
7 import (
8+ "fmt"
9 "launchpad.net/gocheck"
10 "strings"
11- "fmt"
12 )
13
14 type BootstrapS struct{}
15
16=== modified file 'checkers.go'
17--- checkers.go 2012-02-25 19:01:16 +0000
18+++ checkers.go 2012-03-14 14:30:29 +0000
19@@ -1,9 +1,9 @@
20 package gocheck
21
22 import (
23+ "fmt"
24 "reflect"
25 "regexp"
26- "fmt"
27 )
28
29 // -----------------------------------------------------------------------
30@@ -238,7 +238,6 @@
31 return value.Len() == n, ""
32 }
33
34-
35 // -----------------------------------------------------------------------
36 // ErrorMatches checker.
37
38
39=== modified file 'foundation_test.go'
40--- foundation_test.go 2012-02-25 16:58:37 +0000
41+++ foundation_test.go 2012-03-14 14:30:29 +0000
42@@ -7,12 +7,12 @@
43 package gocheck_test
44
45 import (
46+ "fmt"
47 "launchpad.net/gocheck"
48- "strings"
49- "regexp"
50- "fmt"
51 "log"
52 "os"
53+ "regexp"
54+ "strings"
55 )
56
57 // -----------------------------------------------------------------------
58
59=== modified file 'gocheck.go'
60--- gocheck.go 2012-02-25 18:28:36 +0000
61+++ gocheck.go 2012-03-14 14:30:29 +0000
62@@ -53,6 +53,24 @@
63 return method.Info.Func.Pointer()
64 }
65
66+func (method *methodType) suiteName() string {
67+ t := method.Info.Type.In(0)
68+ if t.Kind() == reflect.Ptr {
69+ t = t.Elem()
70+ }
71+ return t.Name()
72+}
73+
74+func (method *methodType) String() string {
75+ return fmt.Sprintf("%v.%s", method.suiteName(), method.Info.Name)
76+}
77+
78+func (method *methodType) matches(re *regexp.Regexp) bool {
79+ return re.MatchString(method.Info.Name) ||
80+ re.MatchString(method.suiteName()) ||
81+ re.MatchString(method.String())
82+}
83+
84 type C struct {
85 method *methodType
86 kind funcKind
87@@ -112,7 +130,7 @@
88 if td._path != "" {
89 err := os.RemoveAll(td._path)
90 if err != nil {
91- fmt.Fprintf(os.Stderr, "WARNING: Error cleaning up temporaries: " + err.Error())
92+ fmt.Fprintf(os.Stderr, "WARNING: Error cleaning up temporaries: "+err.Error())
93 }
94 }
95 }
96@@ -190,7 +208,7 @@
97 i := 0
98 n := len(s)
99 for i < n {
100- j := i+1
101+ j := i + 1
102 for j < n && s[j-1] != '\n' {
103 j++
104 }
105@@ -502,24 +520,8 @@
106 }
107 }
108
109- // This map will be used to filter out duplicated methods. This
110- // looks like a bug in Go, described on issue 906:
111- // http://code.google.com/p/go/issues/detail?id=906
112- seen := make(map[uintptr]bool, suiteNumMethods)
113-
114- // XXX Shouldn't Name() work here? Why does it return an empty string?
115- suiteName := suiteType.String()
116- if index := strings.LastIndex(suiteName, "."); index != -1 {
117- suiteName = suiteName[index+1:]
118- }
119-
120 for i := 0; i != suiteNumMethods; i++ {
121 method := newMethod(suiteValue, i)
122- methodPC := method.PC()
123- if _, found := seen[methodPC]; found {
124- continue
125- }
126- seen[methodPC] = true
127 switch method.Info.Name {
128 case "SetUpSuite":
129 runner.setUpSuite = method
130@@ -530,7 +532,10 @@
131 case "TearDownTest":
132 runner.tearDownTest = method
133 default:
134- if isWantedTest(suiteName, method.Info.Name, filterRegexp) {
135+ if !strings.HasPrefix(method.Info.Name, "Test") {
136+ continue
137+ }
138+ if filterRegexp == nil || method.matches(filterRegexp) {
139 runner.tests[testsLen] = method
140 testsLen += 1
141 }
142@@ -541,19 +546,6 @@
143 return runner
144 }
145
146-// Return true if the given suite name and method name should be
147-// considered as a test to be run.
148-func isWantedTest(suiteName, testName string, filterRegexp *regexp.Regexp) bool {
149- if !strings.HasPrefix(testName, "Test") {
150- return false
151- } else if filterRegexp == nil {
152- return true
153- }
154- return (filterRegexp.MatchString(testName) ||
155- filterRegexp.MatchString(suiteName) ||
156- filterRegexp.MatchString(suiteName+"."+testName))
157-}
158-
159 // Run all methods in the given suite.
160 func (runner *suiteRunner) run() *Result {
161 if runner.tracker.result.RunError == nil && len(runner.tests) > 0 {
162
163=== modified file 'gocheck_test.go'
164--- gocheck_test.go 2012-02-17 01:57:02 +0000
165+++ gocheck_test.go 2012-03-14 14:30:29 +0000
166@@ -4,13 +4,13 @@
167 package gocheck_test
168
169 import (
170- "launchpad.net/gocheck"
171- "testing"
172- "runtime"
173- "regexp"
174 "flag"
175 "fmt"
176+ "launchpad.net/gocheck"
177 "os"
178+ "regexp"
179+ "runtime"
180+ "testing"
181 )
182
183 // We count the number of suites run at least to get a vague hint that the
184
185=== modified file 'helpers_test.go'
186--- helpers_test.go 2012-02-25 18:28:36 +0000
187+++ helpers_test.go 2012-03-14 14:30:29 +0000
188@@ -126,7 +126,7 @@
189 testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
190 func() interface{} {
191 // Nice leading comment.
192- return c.Check(1, checker, 2) // Hello there
193+ return c.Check(1, checker, 2) // Hello there
194 })
195 }
196
197@@ -379,7 +379,6 @@
198 })
199 }
200
201-
202 // -----------------------------------------------------------------------
203 // MakeDir() tests.
204
205
206=== modified file 'run.go'
207--- run.go 2012-02-25 13:01:18 +0000
208+++ run.go 2012-03-14 14:30:29 +0000
209@@ -1,9 +1,11 @@
210 package gocheck
211
212 import (
213- "testing"
214+ "bufio"
215 "flag"
216 "fmt"
217+ "os"
218+ "testing"
219 )
220
221 // -----------------------------------------------------------------------
222@@ -23,24 +25,35 @@
223 // Public running interface.
224
225 var filterFlag = flag.String("gocheck.f", "",
226- "Regular expression selecting what to run")
227+ "Regular expression selecting which tests and/or suites to run")
228 var verboseFlag = flag.Bool("gocheck.v", false,
229 "Verbose mode")
230 var streamFlag = flag.Bool("gocheck.vv", false,
231 "Super verbose mode (disables output caching)")
232+var listFlag = flag.Bool("gocheck.list", false,
233+ "List the names of all tests that will be run")
234
235 // Run all test suites registered with the Suite() function, printing
236 // results to stdout, and reporting any failures back to the 'testing'
237 // module.
238 func TestingT(testingT *testing.T) {
239- result := RunAll(&RunConf{Filter: *filterFlag, Verbose: *verboseFlag, Stream: *streamFlag})
240+ conf := &RunConf{Filter: *filterFlag, Verbose: *verboseFlag, Stream: *streamFlag}
241+ if *listFlag {
242+ w := bufio.NewWriter(os.Stdout)
243+ for _, name := range ListAll(conf) {
244+ fmt.Fprintf(w, "%s\n", name)
245+ }
246+ w.Flush()
247+ return
248+ }
249+ result := RunAll(conf)
250 println(result.String())
251 if !result.Passed() {
252 testingT.Fail()
253 }
254 }
255
256-// Run all test suites registered with the Suite() function, using the
257+// RunAll runs all test suites registered with the Suite() function, using the
258 // given run configuration.
259 func RunAll(runConf *RunConf) *Result {
260 result := Result{}
261@@ -50,12 +63,34 @@
262 return &result
263 }
264
265-// Run the given test suite using the provided run configuration.
266+// Run runs the given test suite using the provided run configuration.
267 func Run(suite interface{}, runConf *RunConf) *Result {
268 runner := newSuiteRunner(suite, runConf)
269 return runner.run()
270 }
271
272+// ListAll returns the names of all the test functions registered with the
273+// Suite function that will be run with the provided run configuration.
274+func ListAll(runConf *RunConf) []string {
275+ var names []string
276+ for _, suite := range allSuites {
277+ names = append(names, List(suite, runConf)...)
278+ }
279+ return names
280+}
281+
282+// List prints the names of the test functions in the given
283+// suite that will be run with the provided run configuration
284+// to the given Writer.
285+func List(suite interface{}, runConf *RunConf) []string {
286+ var names []string
287+ runner := newSuiteRunner(suite, runConf)
288+ for _, t := range runner.tests {
289+ names = append(names, t.String())
290+ }
291+ return names
292+}
293+
294 // -----------------------------------------------------------------------
295 // Result methods.
296
297
298=== modified file 'run_test.go'
299--- run_test.go 2012-02-25 13:01:18 +0000
300+++ run_test.go 2012-03-14 14:30:29 +0000
301@@ -2,6 +2,7 @@
302
303 package gocheck_test
304
305+
306 import (
307 "errors"
308 . "launchpad.net/gocheck"
309@@ -99,21 +100,21 @@
310
311 func (s *RunS) TestAdd(c *C) {
312 result := &Result{
313- Succeeded: 1,
314- Skipped: 2,
315- Failed: 3,
316- Panicked: 4,
317- FixturePanicked: 5,
318- Missed: 6,
319+ Succeeded: 1,
320+ Skipped: 2,
321+ Failed: 3,
322+ Panicked: 4,
323+ FixturePanicked: 5,
324+ Missed: 6,
325 ExpectedFailures: 7,
326 }
327 result.Add(&Result{
328- Succeeded: 10,
329- Skipped: 20,
330- Failed: 30,
331- Panicked: 40,
332- FixturePanicked: 50,
333- Missed: 60,
334+ Succeeded: 10,
335+ Skipped: 20,
336+ Failed: 30,
337+ Panicked: 40,
338+ FixturePanicked: 50,
339+ Missed: 60,
340 ExpectedFailures: 70,
341 })
342 c.Check(result.Succeeded, Equals, 11)
343@@ -280,6 +281,24 @@
344 }
345
346 // -----------------------------------------------------------------------
347+// Verify that List works correctly.
348+
349+func (s *RunS) TestListFiltered(c *C) {
350+ names := List(&FixtureHelper{}, &RunConf{Filter: "1"})
351+ c.Assert(names, DeepEquals, []string{
352+ "FixtureHelper.Test1",
353+ })
354+}
355+
356+func (s *RunS) TestList(c *C) {
357+ names := List(&FixtureHelper{}, &RunConf{})
358+ c.Assert(names, DeepEquals, []string{
359+ "FixtureHelper.Test1",
360+ "FixtureHelper.Test2",
361+ })
362+}
363+
364+// -----------------------------------------------------------------------
365 // Verify that verbose mode prints tests which pass as well.
366
367 func (s *RunS) TestVerboseMode(c *C) {

Subscribers

People subscribed via source and target branches