Skip to content

Commit

Permalink
Merge pull request #232 from dogmatiq/to-only-expectation
Browse files Browse the repository at this point in the history
Add `ToOnly[ExecuteCommands|RecordEvents]Matching()`.
  • Loading branch information
jmalloc committed Apr 16, 2021
2 parents eb5b25f + 9516c50 commit 8d46627
Show file tree
Hide file tree
Showing 4 changed files with 378 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ The format is based on [Keep a Changelog], and this project adheres to
[Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
[Semantic Versioning]: https://semver.org/spec/v2.0.0.html

## [Unreleased]

### Added

- Add `ToOnlyExecuteCommandsMatching()` and `ToOnlyRecordEventsMatching()` expectations

## [0.13.1] - 2021-04-13

### Added
Expand Down
137 changes: 137 additions & 0 deletions expectation.messagematch.commandonly_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package testkit_test

import (
"context"
"errors"

"github.com/dogmatiq/dogma"
"github.com/dogmatiq/dogma/fixtures"
. "github.com/dogmatiq/dogma/fixtures"
. "github.com/dogmatiq/testkit"
"github.com/dogmatiq/testkit/internal/testingmock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
)

var _ = Describe("func ToOnlyExecuteCommandsMatching()", func() {
var (
testingT *testingmock.T
app dogma.Application
)

BeforeEach(func() {
testingT = &testingmock.T{
FailSilently: true,
}

app = &Application{
ConfigureFunc: func(c dogma.ApplicationConfigurer) {
c.Identity("<app>", "<app-key>")

c.RegisterProcess(&ProcessMessageHandler{
ConfigureFunc: func(c dogma.ProcessConfigurer) {
c.Identity("<process>", "<process-key>")
c.ConsumesEventType(MessageE{}) // E = event
c.ProducesCommandType(MessageC{}) // C = command
},
RouteEventToInstanceFunc: func(
context.Context,
dogma.Message,
) (string, bool, error) {
return "<instance>", true, nil
},
HandleEventFunc: func(
_ context.Context,
_ dogma.ProcessRoot,
s dogma.ProcessEventScope,
m dogma.Message,
) error {
s.ExecuteCommand(MessageC1)
s.ExecuteCommand(MessageC2)
s.ExecuteCommand(MessageC3)
return nil
},
})
},
}
})

DescribeTable(
"expectation behavior",
func(
a Action,
e Expectation,
ok bool,
rm reportMatcher,
options ...TestOption,
) {
test := Begin(testingT, app, options...)
test.Expect(a, e)
rm(testingT)
Expect(testingT.Failed()).To(Equal(!ok))
},
Entry(
"all executed commands match",
RecordEvent(MessageE1),
ToOnlyExecuteCommandsMatching(
func(m dogma.Message) error {
return nil
},
),
expectPass,
expectReport(
`✓ only execute commands that match the predicate near expectation.messagematch.commandonly_test.go:79`,
),
),
Entry(
"no commands executed at all",
noop,
ToOnlyExecuteCommandsMatching(
func(m dogma.Message) error {
panic("unexpected call")
},
),
expectPass,
expectReport(
`✓ only execute commands that match the predicate near expectation.messagematch.commandonly_test.go:91`,
),
),
Entry(
"some matching commands executed",
RecordEvent(MessageE1),
ToOnlyExecuteCommandsMatching(
func(m dogma.Message) error {
switch m {
case fixtures.MessageC1:
return errors.New("<error>")
case fixtures.MessageC2:
return IgnoreMessage
default:
return nil
}
},
),
expectFail,
expectReport(
`✗ only execute commands that match the predicate near expectation.messagematch.commandonly_test.go:104`,
``,
` | EXPLANATION`,
` | only 1 of 2 relevant commands matched the predicate`,
` | `,
` | FAILED MATCHES`,
` | • fixtures.MessageC: <error>`,
` | `,
` | SUGGESTIONS`,
` | • verify the logic within the predicate function, it ignored 1 command`,
` | • verify the logic within the '<process>' process message handler`,
),
),
)

It("panics if the function is nil", func() {
Expect(func() {
ToOnlyExecuteCommandsMatching(nil)
}).To(PanicWith("ToOnlyExecuteCommandsMatching(<nil>): function must not be nil"))
})
})
132 changes: 132 additions & 0 deletions expectation.messagematch.eventonly_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package testkit_test

import (
"errors"

"github.com/dogmatiq/dogma"
"github.com/dogmatiq/dogma/fixtures"
. "github.com/dogmatiq/dogma/fixtures"
. "github.com/dogmatiq/testkit"
"github.com/dogmatiq/testkit/internal/testingmock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
)

var _ = Describe("func ToOnlyRecordEventsMatching()", func() {
var (
testingT *testingmock.T
app dogma.Application
)

BeforeEach(func() {
testingT = &testingmock.T{
FailSilently: true,
}

app = &Application{
ConfigureFunc: func(c dogma.ApplicationConfigurer) {
c.Identity("<app>", "<app-key>")

c.RegisterAggregate(&AggregateMessageHandler{
ConfigureFunc: func(c dogma.AggregateConfigurer) {
c.Identity("<aggregate>", "<aggregate-key>")
c.ConsumesCommandType(MessageC{}) // C = command
c.ProducesEventType(MessageE{}) // E = event
},
RouteCommandToInstanceFunc: func(dogma.Message) string {
return "<instance>"
},
HandleCommandFunc: func(
_ dogma.AggregateRoot,
s dogma.AggregateCommandScope,
m dogma.Message,
) {
s.RecordEvent(MessageE1)
s.RecordEvent(MessageE2)
s.RecordEvent(MessageE3)
},
})
},
}
})

DescribeTable(
"expectation behavior",
func(
a Action,
e Expectation,
ok bool,
rm reportMatcher,
options ...TestOption,
) {
test := Begin(testingT, app, options...)
test.Expect(a, e)
rm(testingT)
Expect(testingT.Failed()).To(Equal(!ok))
},
Entry(
"all recorded events match",
ExecuteCommand(MessageC1),
ToOnlyRecordEventsMatching(
func(m dogma.Message) error {
return nil
},
),
expectPass,
expectReport(
`✓ only record events that match the predicate near expectation.messagematch.eventonly_test.go:73`,
),
),
Entry(
"no events recorded at all",
noop,
ToOnlyRecordEventsMatching(
func(m dogma.Message) error {
panic("unexpected call")
},
),
expectPass,
expectReport(
`✓ only record events that match the predicate near expectation.messagematch.eventonly_test.go:85`,
),
),
Entry(
"some matching events executed",
ExecuteCommand(MessageC1),
ToOnlyRecordEventsMatching(
func(m dogma.Message) error {
switch m {
case fixtures.MessageE1:
return errors.New("<error>")
case fixtures.MessageE2:
return IgnoreMessage
default:
return nil
}
},
),
expectFail,
expectReport(
`✗ only record events that match the predicate near expectation.messagematch.eventonly_test.go:98`,
``,
` | EXPLANATION`,
` | only 1 of 2 relevant events matched the predicate`,
` | `,
` | FAILED MATCHES`,
` | • fixtures.MessageE: <error>`,
` | `,
` | SUGGESTIONS`,
` | • verify the logic within the predicate function, it ignored 1 event`,
` | • enable integration handlers using the EnableHandlerType() option`,
` | • verify the logic within the '<aggregate>' aggregate message handler`,
),
),
)

It("panics if the function is nil", func() {
Expect(func() {
ToOnlyRecordEventsMatching(nil)
}).To(PanicWith("ToOnlyRecordEventsMatching(<nil>): function must not be nil"))
})
})
Loading

0 comments on commit 8d46627

Please sign in to comment.