136 lines
3.9 KiB
Go
136 lines
3.9 KiB
Go
package cmd_test
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"github.com/inkyblackness/hacked/ss1"
|
|
"github.com/inkyblackness/hacked/ss1/edit/undoable/cmd"
|
|
"github.com/inkyblackness/hacked/ss1/world"
|
|
)
|
|
|
|
func TestTransactionBuilder(t *testing.T) {
|
|
suite.Run(t, new(TransactionBuilderSuite))
|
|
}
|
|
|
|
type TransactionBuilderSuite struct {
|
|
suite.Suite
|
|
|
|
builder cmd.TransactionBuilder
|
|
command cmd.Command
|
|
result []string
|
|
err error
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) SetupTest() {
|
|
suite.builder = cmd.TransactionBuilder{Commander: suite}
|
|
suite.command = nil
|
|
suite.result = nil
|
|
suite.err = nil
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) TestTransactionCallsForwardTasksFromLeftToRight() {
|
|
suite.givenRegisteredTransaction(
|
|
cmd.Forward(suite.aTask("fa")),
|
|
cmd.Forward(suite.aTask("fb")),
|
|
cmd.Reverse(suite.aTask("ra")),
|
|
)
|
|
suite.whenCommandIsDone()
|
|
suite.thenResultShouldBe([]string{"fa", "fb"})
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) TestTransactionCallsReverseTasksFromRightToLeft() {
|
|
suite.givenRegisteredTransaction(
|
|
cmd.Forward(suite.aTask("fa")),
|
|
cmd.Reverse(suite.aTask("ra")),
|
|
cmd.Reverse(suite.aTask("rb")),
|
|
)
|
|
suite.whenCommandIsUndone()
|
|
suite.thenResultShouldBe([]string{"rb", "ra"})
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) TestTransactionCallsNestedInForwardDirection() {
|
|
suite.givenRegisteredTransaction(
|
|
cmd.Forward(suite.aTask("fa")),
|
|
cmd.Nested(func() error {
|
|
return suite.builder.Register(cmd.Forward(suite.aTask("na")))
|
|
}),
|
|
cmd.Forward(suite.aTask("fb")),
|
|
)
|
|
suite.whenCommandIsDone()
|
|
suite.thenResultShouldBe([]string{"fa", "na", "fb"})
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) TestTransactionCallsNestedInReverseDirection() {
|
|
suite.givenRegisteredTransaction(
|
|
cmd.Reverse(suite.aTask("ra")),
|
|
cmd.Nested(func() error {
|
|
return suite.builder.Register(cmd.Reverse(suite.aTask("na")), cmd.Reverse(suite.aTask("nb")))
|
|
}),
|
|
cmd.Reverse(suite.aTask("rb")),
|
|
)
|
|
suite.whenCommandIsUndone()
|
|
suite.thenResultShouldBe([]string{"rb", "nb", "na", "ra"})
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) TestTransactionReturnsErrorWithNamedPath() {
|
|
suite.givenRegisteredTransaction(
|
|
cmd.Named("main"),
|
|
cmd.Forward(suite.aTask("fa")),
|
|
cmd.Nested(func() error {
|
|
return suite.builder.Register(cmd.Named("nested"), cmd.Forward(suite.aTaskReturning(ss1.StringError("fail"))))
|
|
}),
|
|
cmd.Forward(suite.aTask("fb")),
|
|
)
|
|
suite.whenCommandIsDone()
|
|
suite.thenResultShouldBeError("main[1]: nested[0]: fail")
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) givenRegisteredTransaction(modifier ...cmd.TransactionModifier) {
|
|
err := suite.builder.Register(modifier...)
|
|
require.Nil(suite.T(), err, "no error expected registering transaction")
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) whenCommandIsDone() {
|
|
suite.err = suite.command.Do(nil)
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) whenCommandIsUndone() {
|
|
suite.err = suite.command.Undo(nil)
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) thenResultShouldBe(expected []string) {
|
|
assert.Equal(suite.T(), expected, suite.result)
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) thenResultShouldBeError(expected string) {
|
|
require.NotNil(suite.T(), suite.err, "no error returned")
|
|
var txnErr cmd.TransactionError
|
|
isTxnErr := errors.As(suite.err, &txnErr)
|
|
require.True(suite.T(), isTxnErr, "error is not a transaction error: %v", suite.err)
|
|
assert.Equal(suite.T(), expected, txnErr.Error())
|
|
assert.NotNil(suite.T(), txnErr.Nested, "no nested error set")
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) Queue(command cmd.Command) {
|
|
require.Nil(suite.T(), suite.command, "Not expecting a second command")
|
|
suite.command = command
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) aTask(text string) cmd.Task {
|
|
return func(modder world.Modder) error {
|
|
suite.result = append(suite.result, text)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func (suite *TransactionBuilderSuite) aTaskReturning(err error) cmd.Task {
|
|
return func(modder world.Modder) error {
|
|
return err
|
|
}
|
|
}
|