diff --git a/src/config/param_variant_test.go b/src/config/param_variant_test.go deleted file mode 100644 index 98bfa2f9..00000000 --- a/src/config/param_variant_test.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright (c) 2024 Murex - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package config - -import "testing" - -func Test_valid_variant_values(t *testing.T) { - t.Skip("work in progress") - tests := []struct { - input string - expectedValue string - expectedError error - }{ - { - input: "relaxed", - expectedValue: "relaxed", - expectedError: nil, - }, - } - - for _, test := range tests { - t.Run(test.input, func(t *testing.T) { - // TODO - }) - } -} diff --git a/src/config/tcr_config.go b/src/config/tcr_config.go index 1ebc45b9..185eb4d2 100644 --- a/src/config/tcr_config.go +++ b/src/config/tcr_config.go @@ -28,7 +28,6 @@ import ( "github.com/murex/tcr/settings" "github.com/murex/tcr/toolchain" "github.com/murex/tcr/utils" - "github.com/murex/tcr/variant" "github.com/spf13/cobra" "github.com/spf13/viper" "io" @@ -221,7 +220,7 @@ func UpdateEngineParams(p *params.Params) { p.Toolchain = Config.Toolchain.GetValue() p.PollingPeriod = Config.PollingPeriod.GetValue() p.AutoPush = Config.AutoPush.GetValue() - p.Variant = variant.Variant(Config.Variant.GetValue()) + p.Variant = Config.Variant.GetValue() p.CommitFailures = Config.CommitFailures.GetValue() p.VCS = Config.VCS.GetValue() p.MessageSuffix = Config.MessageSuffix.GetValue() diff --git a/src/engine/tcr.go b/src/engine/tcr.go index fce84f66..fd52498e 100644 --- a/src/engine/tcr.go +++ b/src/engine/tcr.go @@ -59,7 +59,7 @@ type ( ToggleAutoPush() SetAutoPush(flag bool) SetCommitOnFail(flag bool) - SetVariant(variant variant.Variant) + SetVariant(variant string) GetCurrentRole() role.Role RunAsDriver() RunAsNavigator() @@ -94,7 +94,7 @@ type ( // before starting a new one roleMutex sync.Mutex commitOnFail bool - variant variant.Variant + variant *variant.Variant messageSuffix string // shoot channel is used for handling interruptions coming from the UI shoot chan bool @@ -109,10 +109,6 @@ type ( } ) -func (tcr *TCREngine) SetVariant(variant variant.Variant) { - tcr.variant = variant -} - const traceReporterWaitingTime = 100 * time.Millisecond const fsWatchRearmDelay = 100 * time.Millisecond @@ -200,6 +196,18 @@ func (tcr *TCREngine) SetCommitOnFail(flag bool) { } } +// SetVariant sets the TCR variant that will be used by TCR engine +func (tcr *TCREngine) SetVariant(variantName string) { + var err error + tcr.variant, err = variant.Select(variantName) + if err != nil { + var unsupportedVariantError *variant.UnsupportedVariantError + if errors.As(err, &unsupportedVariantError) { + tcr.handleError(err, true, status.ConfigError) + } + } +} + func (tcr *TCREngine) setMobTimerDuration(duration time.Duration) { if settings.EnableMobTimer { if tcr.mode.IsMultiRole() { @@ -633,14 +641,14 @@ func (tcr *TCREngine) revert(event events.TCREvent) { } func (tcr *TCREngine) noFilesRevertedMessage() string { - if tcr.variant == variant.Relaxed { + if *tcr.variant == variant.Relaxed { return "No file reverted (only test files were updated since last commit)" } return "No file reverted" } func (tcr *TCREngine) shouldRevertFile(path string) bool { - return tcr.variant == variant.BTCR || tcr.language.IsSrcFile(path) + return *tcr.variant == variant.BTCR || tcr.language.IsSrcFile(path) } func (tcr *TCREngine) commitTestBreakingChanges(event events.TCREvent) (err error) { @@ -694,7 +702,7 @@ func (tcr *TCREngine) GetSessionInfo() SessionInfo { VCSSessionSummary: tcr.vcs.SessionSummary(), GitAutoPush: tcr.vcs.IsAutoPushEnabled(), CommitOnFail: tcr.commitOnFail, - Variant: string(tcr.variant), + Variant: tcr.variant.Name(), MessageSuffix: tcr.messageSuffix, } } diff --git a/src/engine/tcr_test.go b/src/engine/tcr_test.go index 929efbb8..f49bad62 100644 --- a/src/engine/tcr_test.go +++ b/src/engine/tcr_test.go @@ -350,7 +350,7 @@ func Test_variant_specific_reverts(t *testing.T) { }, ) tcr, vcsFake := initTCREngineWithFakesWithFileDiffs( - params.AParamSet(params.WithVariant(tt.variant)), + params.AParamSet(params.WithVariant(tt.variant.Name())), nil, nil, nil, tt.fileDiffs) tcr.revert(*events.ATcrEvent()) sniffer.Stop() @@ -363,7 +363,7 @@ func Test_variant_specific_reverts(t *testing.T) { func Test_introspective_variant(t *testing.T) { t.Skip("work in progress") tcr, vcsFake := initTCREngineWithFakesWithFileDiffs( - params.AParamSet(params.WithVariant(variant.Introspective)), + params.AParamSet(params.WithVariant(variant.Introspective.Name())), nil, nil, nil, vcs.FileDiffs{ vcs.NewFileDiff("fake-src", 1, 1), vcs.NewFileDiff("fake-test", 1, 1), @@ -589,7 +589,7 @@ func Test_set_variant(t *testing.T) { for _, tt := range testFlags { t.Run(fmt.Sprintf("Variant %v", tt.variant), func(t *testing.T) { tcr, _ = initTCREngineWithFakes(nil, nil, nil, nil) - tcr.SetVariant(tt.variant) + tcr.SetVariant(tt.variant.Name()) assert.Equal(t, string(tt.variant), tcr.GetSessionInfo().Variant) }) } diff --git a/src/params/params.go b/src/params/params.go index 16533e95..55b9f85d 100644 --- a/src/params/params.go +++ b/src/params/params.go @@ -24,7 +24,6 @@ package params import ( "github.com/murex/tcr/runmode" - "github.com/murex/tcr/variant" "time" ) @@ -37,7 +36,7 @@ type Params struct { Toolchain string MobTurnDuration time.Duration AutoPush bool - Variant variant.Variant + Variant string CommitFailures bool PollingPeriod time.Duration Mode runmode.RunMode diff --git a/src/params/params_test_data_builder.go b/src/params/params_test_data_builder.go index 862c20b9..162ed620 100644 --- a/src/params/params_test_data_builder.go +++ b/src/params/params_test_data_builder.go @@ -26,7 +26,6 @@ package params import ( "github.com/murex/tcr/runmode" - "github.com/murex/tcr/variant" "time" ) @@ -40,7 +39,7 @@ func AParamSet(builders ...func(params *Params)) *Params { Toolchain: "", MobTurnDuration: 0, AutoPush: false, - Variant: variant.Relaxed, + Variant: "relaxed", PollingPeriod: 0, Mode: runmode.OneShot{}, VCS: "git", @@ -110,7 +109,7 @@ func WithAutoPush(value bool) func(params *Params) { } // WithVariant sets the provided value as the variant to be used -func WithVariant(variant variant.Variant) func(params *Params) { +func WithVariant(variant string) func(params *Params) { return func(params *Params) { params.Variant = variant } diff --git a/src/variant/variant.go b/src/variant/variant.go index 07c74a3e..8fd189df 100644 --- a/src/variant/variant.go +++ b/src/variant/variant.go @@ -22,16 +22,45 @@ SOFTWARE. package variant -// Variant represents the possible values for the TCR Variant -// https://medium.com/@tdeniffel/tcr-variants-test-commit-revert-bf6bd84b17d3 -type Variant string +import "fmt" -func (v Variant) Name() string { - return string(v) +// UnsupportedVariantError is returned when the provided Variant name is not supported. +type UnsupportedVariantError struct { + variantName string } +// Error returns the error description +func (e *UnsupportedVariantError) Error() string { + return fmt.Sprintf("variant not supported: \"%s\"", e.variantName) +} + +// Variant represents the possible values for the TCR Variant. +// These values are inspired by the following blog-post: +// https://medium.com/@tdeniffel/tcr-variants-test-commit-revert-bf6bd84b17d3 +type Variant string + +// Recognized variant values const ( Relaxed Variant = "relaxed" BTCR Variant = "btcr" Introspective Variant = "introspective" ) + +var recognized = []Variant{Relaxed, BTCR, Introspective} + +// Select returns a variant instance for the provided name. +// It returns an UnsupportedVariantError if the name is not recognized as a +// valid variant name. +func Select(name string) (*Variant, error) { + for _, variant := range recognized { + if name == variant.Name() { + return &variant, nil + } + } + return nil, &UnsupportedVariantError{name} +} + +// Name returns the variant name +func (v Variant) Name() string { + return string(v) +} diff --git a/src/variant/variant_test.go b/src/variant/variant_test.go index 33c87891..1cbc29f8 100644 --- a/src/variant/variant_test.go +++ b/src/variant/variant_test.go @@ -44,3 +44,30 @@ func Test_get_variant_name(t *testing.T) { }) } } + +func Test_select_variant(t *testing.T) { + relaxed, btcr, introspective := Relaxed, BTCR, Introspective + tests := []struct { + name string + expectedVariant *Variant + expectedError error + }{ + {"relaxed", &relaxed, nil}, + {"btcr", &btcr, nil}, + {"introspective", &introspective, nil}, + {"unknown", nil, &UnsupportedVariantError{"unknown"}}, + {"", nil, &UnsupportedVariantError{""}}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + variant, err := Select(test.name) + assert.Equal(t, test.expectedVariant, variant) + assert.Equal(t, test.expectedError, err) + }) + } +} + +func Test_unsupported_variant_message_format(t *testing.T) { + err := UnsupportedVariantError{"some-variant"} + assert.Equal(t, "variant not supported: \"some-variant\"", err.Error()) +}