Skip to content

Commit

Permalink
Implement PanicWith().
Browse files Browse the repository at this point in the history
  • Loading branch information
jmalloc authored and williammartin committed May 6, 2020
1 parent c0be499 commit f8032b4
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 5 deletions.
10 changes: 10 additions & 0 deletions matchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,16 @@ func Panic() types.GomegaMatcher {
return &matchers.PanicMatcher{}
}

//PanicWith succeeds if actual is a function that, when invoked, panics with a specific value.
//Actual must be a function that takes no arguments and returns no results.
//
//By default PanicWith uses Equal() to perform the match, however a
//matcher can be passed in instead:
// Expect(fn).Should(PanicWith(MatchRegexp(`.+Foo$`)))
func PanicWith(expected interface{}) types.GomegaMatcher {
return &matchers.PanicMatcher{Expected: expected}
}

//BeAnExistingFile succeeds if a file exists.
//Actual must be a string representing the abs path to the file being checked.
func BeAnExistingFile() types.GomegaMatcher {
Expand Down
44 changes: 40 additions & 4 deletions matchers/panic_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (
)

type PanicMatcher struct {
object interface{}
Expected interface{}
object interface{}
}

func (matcher *PanicMatcher) Match(actual interface{}) (success bool, err error) {
Expand All @@ -28,7 +29,21 @@ func (matcher *PanicMatcher) Match(actual interface{}) (success bool, err error)
defer func() {
if e := recover(); e != nil {
matcher.object = e
success = true

if matcher.Expected == nil {
success = true
return
}

valueMatcher, valueIsMatcher := matcher.Expected.(omegaMatcher)
if !valueIsMatcher {
valueMatcher = &EqualMatcher{Expected: matcher.Expected}
}

success, err = valueMatcher.Match(e)
if err != nil {
err = fmt.Errorf("PanicMatcher's value matcher failed with:\n%s%s", format.Indent, err.Error())
}
}
}()

Expand All @@ -38,9 +53,30 @@ func (matcher *PanicMatcher) Match(actual interface{}) (success bool, err error)
}

func (matcher *PanicMatcher) FailureMessage(actual interface{}) (message string) {
return format.Message(actual, "to panic")
switch matcher.Expected.(type) {
case nil:
return format.Message(actual, "to panic")
case omegaMatcher:
return format.Message(actual, "to panic with a value matching", matcher.Expected)
default:
return format.Message(actual, "to panic with", matcher.Expected)
}
}

func (matcher *PanicMatcher) NegatedFailureMessage(actual interface{}) (message string) {
return format.Message(actual, fmt.Sprintf("not to panic, but panicked with\n%s", format.Object(matcher.object, 1)))
switch matcher.Expected.(type) {
case nil:
return format.Message(actual, fmt.Sprintf("not to panic, but panicked with\n%s", format.Object(matcher.object, 1)))
case omegaMatcher:
return format.Message(
actual,
fmt.Sprintf(
"not to panic with a value matching\n%s\nbut panicked with\n%s",
format.Object(matcher.Expected, 1),
format.Object(matcher.object, 1),
),
)
default:
return format.Message(actual, "not to panic with", matcher.Expected)
}
}
45 changes: 44 additions & 1 deletion matchers/panic_matcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var _ = Describe("Panic", func() {
})

When("assertion fails", func() {
It("prints the object passed to Panic when negative", func() {
It("prints the object passed to panic() when negative", func() {
failuresMessages := InterceptGomegaFailures(func() {
Expect(func() { panic("ack!") }).NotTo(Panic())
})
Expand All @@ -50,3 +50,46 @@ var _ = Describe("Panic", func() {
})
})
})

var _ = Describe("PanicWith", func() {
When("passed a function of the correct type", func() {
It("should call the function and pass if the function panics with the expected value", func() {
Expect(func() { panic("ack!") }).To(PanicWith("ack!"))
Expect(func() {}).NotTo(PanicWith("ack!"))
})
})

When("assertion fails", func() {
It("prints simple message when positive", func() {
failuresMessages := InterceptGomegaFailures(func() {
Expect(func() {}).To(PanicWith("ack!"))
})
Expect(failuresMessages).To(ConsistOf(MatchRegexp("Expected\n\\s+<func\\(\\)>: .+\nto panic with\\s+<string>: ack!")))
})

It("prints simple message when negative", func() {
failuresMessages := InterceptGomegaFailures(func() {
Expect(func() { panic("ack!") }).NotTo(PanicWith("ack!"))
})
Expect(failuresMessages).To(ConsistOf(MatchRegexp("Expected\n\\s+<func\\(\\)>: .+\nnot to panic with\\s+<string>: ack!")))
})

When("the expected value is actually a matcher", func() {
It("prints simple message when positive", func() {
failuresMessages := InterceptGomegaFailures(func() {
Expect(func() {}).To(PanicWith(Equal("ack!")))
})
Expect(failuresMessages).To(ConsistOf(MatchRegexp("Expected\n\\s+<func\\(\\)>: .+\nto panic with a value matching\n.+EqualMatcher.+ack!")))
})

It("prints the object passed to panic() when negative", func() {
failuresMessages := InterceptGomegaFailures(func() {
Expect(func() { panic("ack!") }).NotTo(PanicWith(MatchRegexp("ack")))
})
Expect(failuresMessages).To(ConsistOf(
MatchRegexp("Expected\n\\s+<func\\(\\)>: .+\nnot to panic with a value matching\n.+MatchRegexpMatcher.+ack.+\nbut panicked with\n <string>: ack!"),
))
})
})
})
})

0 comments on commit f8032b4

Please sign in to comment.