diff --git a/convey/doc.go b/convey/doc.go index e4944479..38b67e03 100644 --- a/convey/doc.go +++ b/convey/doc.go @@ -39,6 +39,19 @@ func SkipConvey(items ...interface{}) { register(entry) } +// FocusConvey is has the inverse effect of SkipConvey. If the top-level +// Convey is changed to `FocusConvey`, only nested scopes that are defined +// with FocusConvey will be run. The rest will be ignored completely. This +// is handy when debugging a large suite that runs a misbehaving function +// repeatedly as you can disable all but one execution of that function +// without swaths of `SkipConvey` calls, just a targeted chain of calls +// to FocusConvey. +func FocusConvey(items ...interface{}) { + entry := discover(items) + entry.Focus = true + register(entry) +} + func register(entry *execution.Registration) { if entry.IsTopLevel() { suites.Run(entry) diff --git a/convey/focused_execution_test.go b/convey/focused_execution_test.go new file mode 100644 index 00000000..294e32fa --- /dev/null +++ b/convey/focused_execution_test.go @@ -0,0 +1,72 @@ +package convey + +import "testing" + +func TestFocusOnlyAtTopLevel(t *testing.T) { + output := prepare() + + FocusConvey("hi", t, func() { + output += "done" + }) + + expectEqual(t, "done", output) +} + +func TestFocus(t *testing.T) { + output := prepare() + + FocusConvey("hi", t, func() { + output += "1" + + Convey("bye", func() { + output += "2" + }) + }) + + expectEqual(t, "1", output) +} + +func TestNestedFocus(t *testing.T) { + output := prepare() + + FocusConvey("hi", t, func() { + output += "1" + + Convey("This shouldn't run", func() { + output += "boink!" + }) + + FocusConvey("This should run", func() { + output += "2" + + FocusConvey("The should run too", func() { + output += "3" + + }) + + Convey("The should NOT run", func() { + output += "blah blah blah!" + }) + }) + }) + + expectEqual(t, "123", output) +} + +func TestForgotTopLevelFocus(t *testing.T) { + output := prepare() + + Convey("1", t, func() { + output += "1" + + FocusConvey("This will be run because the top-level lacks Focus", func() { + output += "2" + }) + + Convey("3", func() { + output += "3" + }) + }) + + expectEqual(t, "1213", output) +} diff --git a/execution/registration.go b/execution/registration.go index 3b46229c..a48481bf 100644 --- a/execution/registration.go +++ b/execution/registration.go @@ -8,6 +8,7 @@ type Registration struct { Test T File string Line int + Focus bool } func (self *Registration) IsTopLevel() bool { diff --git a/execution/runner.go b/execution/runner.go index a12590d7..510776b0 100644 --- a/execution/runner.go +++ b/execution/runner.go @@ -21,9 +21,11 @@ type runner struct { out reporting.Reporter awaitingNewStory bool + focus bool } func (self *runner) Begin(entry *Registration) { + self.focus = entry.Focus self.ensureStoryCanBegin() self.out.BeginStory(reporting.NewStoryReport(entry.Test)) self.Register(entry) @@ -37,6 +39,9 @@ func (self *runner) ensureStoryCanBegin() { } func (self *runner) Register(entry *Registration) { + if self.focus && !entry.Focus { + return + } self.ensureStoryAlreadyStarted() parentAction := self.link(entry.Action) parent := self.accessScope(parentAction)