diff --git a/docs/specs/test-reporting.md b/docs/specs/test-reporting.md index 98a59c87..58381685 100644 --- a/docs/specs/test-reporting.md +++ b/docs/specs/test-reporting.md @@ -30,7 +30,7 @@ specific runs, and share the results with others. ## Requirements -- [x] The user can generate a test report by running `ie test //report=` +- [x] The user can generate a test report by running `ie test --report=` - [x] Reports capture the yaml metadata of the scenario. - [x] Reports store the variables declared in the scenario and their values. - [x] The report is generated in JSON format. @@ -43,7 +43,7 @@ specific runs, and share the results with others. - The report will be generated in JSON format, but in the future we may consider other formats like yaml or HTML. JSON format was chosen for v1 because it is easy to parse, and it is a common format for sharing data. -- Users must specify `//report=` to generate a report. If the path is not +- Users must specify `--report=` to generate a report. If the path is not specified, the report will not be generated. ### Report schema @@ -109,8 +109,8 @@ documentation about each field until then. "stepName": "First step", // The step number "stepNumber": 0, - // Whether the step was successful or not - "success": true, + // The status of the codeblock (success, failure, or pending if never executed). + "status": "success", // The computed similarity score of the output (between 0 - 1) "similarityScore": 0 }, @@ -133,7 +133,7 @@ documentation about each field until then. "stdOut": "", "stepName": "Second step", "stepNumber": 1, - "success": true, + "status": "success", "similarityScore": 0 } ] @@ -186,7 +186,7 @@ The output of the command above should look like this: "stdOut": "Hello, world!\n", "stepName": "First step", "stepNumber": 0, - "success": true, + "status": "success", "similarityScore": 1 }, { @@ -208,7 +208,7 @@ The output of the command above should look like this: "stdOut": "", "stepName": "Second step", "stepNumber": 1, - "success": true, + "status": "success", "similarityScore": 1 } ] diff --git a/internal/engine/common/codeblock.go b/internal/engine/common/codeblock.go index 89360233..ece04a5f 100644 --- a/internal/engine/common/codeblock.go +++ b/internal/engine/common/codeblock.go @@ -2,6 +2,12 @@ package common import "github.com/Azure/InnovationEngine/internal/parsers" +const ( + STATUS_SUCCESS = "success" + STATUS_FAILURE = "failure" + STATUS_PENDING = "pending" +) + // State for the codeblock in interactive mode. Used to keep track of the // state of each codeblock. type StatefulCodeBlock struct { @@ -12,12 +18,20 @@ type StatefulCodeBlock struct { StdOut string `json:"stdOut"` StepName string `json:"stepName"` StepNumber int `json:"stepNumber"` - Success bool `json:"success"` + Status string `json:"status"` SimilarityScore float64 `json:"similarityScore"` } // Checks if a codeblock was executed by looking at the // output, errors, and if success is true. func (s StatefulCodeBlock) WasExecuted() bool { - return s.StdOut != "" || s.StdErr != "" || s.Error != nil || s.Success + return s.Status != STATUS_PENDING +} + +func (s StatefulCodeBlock) Succeeded() bool { + return s.Status == STATUS_SUCCESS +} + +func (s StatefulCodeBlock) Failed() bool { + return s.Status == STATUS_FAILURE } diff --git a/internal/engine/interactive/components.go b/internal/engine/interactive/components.go new file mode 100644 index 00000000..5bf9add2 --- /dev/null +++ b/internal/engine/interactive/components.go @@ -0,0 +1,88 @@ +package interactive + +import ( + "github.com/charmbracelet/bubbles/paginator" + "github.com/charmbracelet/bubbles/viewport" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" +) + +type interactiveModeComponents struct { + paginator paginator.Model + stepViewport viewport.Model + outputViewport viewport.Model + azureCLIViewport viewport.Model +} + +// Initializes the viewports for the interactive mode model. +func initializeComponents(model InteractiveModeModel, width, height int) interactiveModeComponents { + // paginator setup + p := paginator.New() + p.TotalPages = len(model.codeBlockState) + p.Type = paginator.Dots + // Dots + p.ActiveDot = lipgloss.NewStyle(). + Foreground(lipgloss.AdaptiveColor{Light: "235", Dark: "252"}). + Render("•") + p.InactiveDot = lipgloss.NewStyle(). + Foreground(lipgloss.AdaptiveColor{Light: "250", Dark: "238"}). + Render("•") + + p.KeyMap.PrevPage = model.commands.previous + p.KeyMap.NextPage = model.commands.next + + stepViewport := viewport.New(width, 4) + outputViewport := viewport.New(width, 2) + azureCLIViewport := viewport.New(width, height) + + components := interactiveModeComponents{ + paginator: p, + stepViewport: stepViewport, + outputViewport: outputViewport, + azureCLIViewport: azureCLIViewport, + } + + components.updateViewportHeight(height) + return components +} + +func (components *interactiveModeComponents) updateViewportHeight(terminalHeight int) { + stepViewportPercent := 0.4 + outputViewportPercent := 0.2 + stepViewportHeight := int(float64(terminalHeight) * stepViewportPercent) + outputViewportHeight := int(float64(terminalHeight) * outputViewportPercent) + + if stepViewportHeight < 4 { + stepViewportHeight = 4 + } + + if outputViewportHeight < 2 { + outputViewportHeight = 2 + } + + components.stepViewport.Height = stepViewportHeight + components.outputViewport.Height = outputViewportHeight + components.azureCLIViewport.Height = terminalHeight - 1 +} + +func updateComponents( + components interactiveModeComponents, + currentBlock int, + message tea.Msg, +) (interactiveModeComponents, []tea.Cmd) { + var commands []tea.Cmd + var command tea.Cmd + + components.paginator.Page = currentBlock + + components.stepViewport, command = components.stepViewport.Update(message) + commands = append(commands, command) + + components.outputViewport, command = components.outputViewport.Update(message) + commands = append(commands, command) + + components.azureCLIViewport, command = components.azureCLIViewport.Update(message) + commands = append(commands, command) + + return components, commands +} diff --git a/internal/engine/interactive/input.go b/internal/engine/interactive/input.go new file mode 100644 index 00000000..4b4c9551 --- /dev/null +++ b/internal/engine/interactive/input.go @@ -0,0 +1,198 @@ +package interactive + +import ( + "strconv" + + "github.com/Azure/InnovationEngine/internal/engine/common" + "github.com/Azure/InnovationEngine/internal/engine/environments" + "github.com/Azure/InnovationEngine/internal/lib" + "github.com/Azure/InnovationEngine/internal/logging" + "github.com/Azure/InnovationEngine/internal/patterns" + "github.com/charmbracelet/bubbles/key" + tea "github.com/charmbracelet/bubbletea" +) + +// All interactive mode inputs. +type InteractiveModeCommands struct { + execute key.Binding + executeAll key.Binding + executeMany key.Binding + next key.Binding + pause key.Binding + previous key.Binding + quit key.Binding +} + +// NewInteractiveModeCommands creates a new set of interactive mode commands. +func NewInteractiveModeCommands() InteractiveModeCommands { + return InteractiveModeCommands{ + execute: key.NewBinding( + key.WithKeys("e"), + key.WithHelp("e", "Execute the current command."), + ), + quit: key.NewBinding( + key.WithKeys("q"), + key.WithHelp("q", "Quit the scenario."), + ), + previous: key.NewBinding( + key.WithKeys("left"), + key.WithHelp("←", "Go to the previous command."), + ), + next: key.NewBinding( + key.WithKeys("right"), + key.WithHelp("→", "Go to the next command."), + ), + // Only enabled when in the azure environment. + executeAll: key.NewBinding( + key.WithKeys("a"), + key.WithHelp("a", "Execute all remaining commands."), + ), + executeMany: key.NewBinding( + key.WithKeys("m"), + key.WithHelp("m", "Execute the next commands."), + ), + pause: key.NewBinding( + key.WithKeys("p"), + key.WithHelp("p", "Pause execution of commands."), + ), + } +} + +func handleUserInput( + model InteractiveModeModel, + message tea.KeyMsg, +) (InteractiveModeModel, []tea.Cmd) { + var commands []tea.Cmd + + // If we're recording input for a multi-char command, + if model.recordingInput { + isNumber := lib.IsNumber(message.String()) + + // If the input is a number, append it to the recorded input. + if message.Type == tea.KeyRunes && isNumber { + model.recordedInput += message.String() + return model, commands + } + + // If the input is not a number, we'll stop recording input and reset + // the commands remaining to the recorded input. + if message.Type == tea.KeyEnter || !isNumber { + commandsRemaining, _ := strconv.Atoi(model.recordedInput) + + if commandsRemaining > len(model.codeBlockState)-model.currentCodeBlock { + commandsRemaining = len(model.codeBlockState) - model.currentCodeBlock + } + + logging.GlobalLogger.Debugf("Will execute the next %d steps", commandsRemaining) + model.stepsToBeExecuted = commandsRemaining + commands = append(commands, func() tea.Msg { + return tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'e'}} + }) + + model.recordingInput = false + model.recordedInput = "" + logging.GlobalLogger.Debugf( + "Recording input stopped and previously recorded input cleared.", + ) + return model, commands + } + } + + switch { + case key.Matches(message, model.commands.execute): + if model.executingCommand { + logging.GlobalLogger.Info("Command is already executing, ignoring execute command") + break + } + + // Prevent the user from executing a command if the previous command has + // not been executed successfully or executed at all. + previousCodeBlock := model.currentCodeBlock - 1 + if previousCodeBlock >= 0 { + previousCodeBlockState := model.codeBlockState[previousCodeBlock] + if !previousCodeBlockState.Succeeded() { + logging.GlobalLogger.Info( + "Previous command has not been executed successfully, ignoring execute command", + ) + break + } + } + + // Prevent the user from executing a command if the current command has + // already been executed successfully. + codeBlockState := model.codeBlockState[model.currentCodeBlock] + if codeBlockState.Succeeded() { + logging.GlobalLogger.Info( + "Command has already been executed successfully, ignoring execute command", + ) + break + } + + codeBlock := codeBlockState.CodeBlock + + model.executingCommand = true + + // If we're on the last step and the command is an SSH command, we need + // to report the status before executing the command. This is needed for + // one click deployments and does not affect the normal execution flow. + if model.currentCodeBlock == len(model.codeBlockState)-1 && + patterns.SshCommand.MatchString(codeBlock.Content) { + model.azureStatus.Status = "Succeeded" + environments.AttachResourceURIsToAzureStatus( + &model.azureStatus, + model.resourceGroupName, + model.environment, + ) + + commands = append(commands, tea.Sequence( + common.UpdateAzureStatus(model.azureStatus, model.environment), + func() tea.Msg { + return common.ExecuteCodeBlockSync(codeBlock, lib.CopyMap(model.env)) + })) + + } else { + commands = append(commands, common.ExecuteCodeBlockAsync( + codeBlock, + lib.CopyMap(model.env), + )) + } + + case key.Matches(message, model.commands.previous): + if model.executingCommand { + logging.GlobalLogger.Info("Command is already executing, ignoring execute command") + break + } + if model.currentCodeBlock > 0 { + model.currentCodeBlock-- + } + case key.Matches(message, model.commands.next): + if model.executingCommand { + logging.GlobalLogger.Info("Command is already executing, ignoring execute command") + break + } + if model.currentCodeBlock < len(model.codeBlockState)-1 { + model.currentCodeBlock++ + } + + case key.Matches(message, model.commands.quit): + commands = append(commands, tea.Quit) + + case key.Matches(message, model.commands.executeAll): + model.stepsToBeExecuted = len(model.codeBlockState) - model.currentCodeBlock + commands = append( + commands, + func() tea.Msg { + return tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'e'}} + }, + ) + case key.Matches(message, model.commands.executeMany): + model.recordingInput = true + case key.Matches(message, model.commands.pause): + if !model.executingCommand { + logging.GlobalLogger.Info("No command is currently executing, ignoring pause command") + } + model.stepsToBeExecuted = 0 + } + + return model, commands +} diff --git a/internal/engine/interactive/interactive.go b/internal/engine/interactive/model.go similarity index 59% rename from internal/engine/interactive/interactive.go rename to internal/engine/interactive/model.go index 83d67e70..f76b613a 100644 --- a/internal/engine/interactive/interactive.go +++ b/internal/engine/interactive/model.go @@ -2,44 +2,22 @@ package interactive import ( "fmt" - "strconv" "strings" "time" "github.com/Azure/InnovationEngine/internal/az" "github.com/Azure/InnovationEngine/internal/engine/common" "github.com/Azure/InnovationEngine/internal/engine/environments" - "github.com/Azure/InnovationEngine/internal/lib" "github.com/Azure/InnovationEngine/internal/logging" "github.com/Azure/InnovationEngine/internal/patterns" "github.com/Azure/InnovationEngine/internal/ui" "github.com/charmbracelet/bubbles/help" "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/paginator" - "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/glamour" "github.com/charmbracelet/lipgloss" ) -// All interactive mode inputs. -type InteractiveModeCommands struct { - execute key.Binding - executeAll key.Binding - executeMany key.Binding - next key.Binding - pause key.Binding - previous key.Binding - quit key.Binding -} - -type interactiveModeComponents struct { - paginator paginator.Model - stepViewport viewport.Model - outputViewport viewport.Model - azureCLIViewport viewport.Model -} - type InteractiveModeModel struct { azureStatus environments.AzureDeploymentStatus codeBlockState map[int]common.StatefulCodeBlock @@ -71,197 +49,6 @@ func (model InteractiveModeModel) Init() tea.Cmd { })) } -// Initializes the viewports for the interactive mode model. -func initializeComponents(model InteractiveModeModel, width, height int) interactiveModeComponents { - // paginator setup - p := paginator.New() - p.TotalPages = len(model.codeBlockState) - p.Type = paginator.Dots - // Dots - p.ActiveDot = lipgloss.NewStyle(). - Foreground(lipgloss.AdaptiveColor{Light: "235", Dark: "252"}). - Render("•") - p.InactiveDot = lipgloss.NewStyle(). - Foreground(lipgloss.AdaptiveColor{Light: "250", Dark: "238"}). - Render("•") - - p.KeyMap.PrevPage = model.commands.previous - p.KeyMap.NextPage = model.commands.next - - stepViewport := viewport.New(width, 4) - outputViewport := viewport.New(width, 2) - azureCLIViewport := viewport.New(width, height) - - components := interactiveModeComponents{ - paginator: p, - stepViewport: stepViewport, - outputViewport: outputViewport, - azureCLIViewport: azureCLIViewport, - } - - components.updateViewportHeight(height) - return components -} - -// Handle user input for interactive mode. -func handleUserInput( - model InteractiveModeModel, - message tea.KeyMsg, -) (InteractiveModeModel, []tea.Cmd) { - var commands []tea.Cmd - - // If we're recording input for a multi-char command, - if model.recordingInput { - isNumber := lib.IsNumber(message.String()) - - // If the input is a number, append it to the recorded input. - if message.Type == tea.KeyRunes && isNumber { - model.recordedInput += message.String() - return model, commands - } - - // If the input is not a number, we'll stop recording input and reset - // the commands remaining to the recorded input. - if message.Type == tea.KeyEnter || !isNumber { - commandsRemaining, _ := strconv.Atoi(model.recordedInput) - - if commandsRemaining > len(model.codeBlockState)-model.currentCodeBlock { - commandsRemaining = len(model.codeBlockState) - model.currentCodeBlock - } - - logging.GlobalLogger.Debugf("Will execute the next %d steps", commandsRemaining) - model.stepsToBeExecuted = commandsRemaining - commands = append(commands, func() tea.Msg { - return tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'e'}} - }) - - model.recordingInput = false - model.recordedInput = "" - logging.GlobalLogger.Debugf( - "Recording input stopped and previously recorded input cleared.", - ) - return model, commands - } - } - - switch { - case key.Matches(message, model.commands.execute): - if model.executingCommand { - logging.GlobalLogger.Info("Command is already executing, ignoring execute command") - break - } - - // Prevent the user from executing a command if the previous command has - // not been executed successfully or executed at all. - previousCodeBlock := model.currentCodeBlock - 1 - if previousCodeBlock >= 0 { - previousCodeBlockState := model.codeBlockState[previousCodeBlock] - if !previousCodeBlockState.Success { - logging.GlobalLogger.Info( - "Previous command has not been executed successfully, ignoring execute command", - ) - break - } - } - - // Prevent the user from executing a command if the current command has - // already been executed successfully. - codeBlockState := model.codeBlockState[model.currentCodeBlock] - if codeBlockState.Success { - logging.GlobalLogger.Info( - "Command has already been executed successfully, ignoring execute command", - ) - break - } - - codeBlock := codeBlockState.CodeBlock - - model.executingCommand = true - - // If we're on the last step and the command is an SSH command, we need - // to report the status before executing the command. This is needed for - // one click deployments and does not affect the normal execution flow. - if model.currentCodeBlock == len(model.codeBlockState)-1 && - patterns.SshCommand.MatchString(codeBlock.Content) { - model.azureStatus.Status = "Succeeded" - environments.AttachResourceURIsToAzureStatus( - &model.azureStatus, - model.resourceGroupName, - model.environment, - ) - - commands = append(commands, tea.Sequence( - common.UpdateAzureStatus(model.azureStatus, model.environment), - func() tea.Msg { - return common.ExecuteCodeBlockSync(codeBlock, lib.CopyMap(model.env)) - })) - - } else { - commands = append(commands, common.ExecuteCodeBlockAsync( - codeBlock, - lib.CopyMap(model.env), - )) - } - - case key.Matches(message, model.commands.previous): - if model.executingCommand { - logging.GlobalLogger.Info("Command is already executing, ignoring execute command") - break - } - if model.currentCodeBlock > 0 { - model.currentCodeBlock-- - } - case key.Matches(message, model.commands.next): - if model.executingCommand { - logging.GlobalLogger.Info("Command is already executing, ignoring execute command") - break - } - if model.currentCodeBlock < len(model.codeBlockState)-1 { - model.currentCodeBlock++ - } - - case key.Matches(message, model.commands.quit): - commands = append(commands, tea.Quit) - - case key.Matches(message, model.commands.executeAll): - model.stepsToBeExecuted = len(model.codeBlockState) - model.currentCodeBlock - commands = append( - commands, - func() tea.Msg { - return tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'e'}} - }, - ) - case key.Matches(message, model.commands.executeMany): - model.recordingInput = true - case key.Matches(message, model.commands.pause): - if !model.executingCommand { - logging.GlobalLogger.Info("No command is currently executing, ignoring pause command") - } - model.stepsToBeExecuted = 0 - } - - return model, commands -} - -func (components *interactiveModeComponents) updateViewportHeight(terminalHeight int) { - stepViewportPercent := 0.4 - outputViewportPercent := 0.2 - stepViewportHeight := int(float64(terminalHeight) * stepViewportPercent) - outputViewportHeight := int(float64(terminalHeight) * outputViewportPercent) - - if stepViewportHeight < 4 { - stepViewportHeight = 4 - } - - if outputViewportHeight < 2 { - outputViewportHeight = 2 - } - - components.stepViewport.Height = stepViewportHeight - components.outputViewport.Height = outputViewportHeight - components.azureCLIViewport.Height = terminalHeight - 1 -} - // Updates the intractive mode model func (model InteractiveModeModel) Update(message tea.Msg) (tea.Model, tea.Cmd) { var commands []tea.Cmd @@ -292,9 +79,11 @@ func (model InteractiveModeModel) Update(message tea.Msg) (tea.Model, tea.Cmd) { // Update the state of the codeblock which finished executing. codeBlockState := model.codeBlockState[step] + codeBlockState.StdOut = message.StdOut codeBlockState.StdErr = message.StdErr - codeBlockState.Success = true + codeBlockState.Status = common.STATUS_SUCCESS + model.codeBlockState[step] = codeBlockState logging.GlobalLogger.Infof("Finished executing:\n %s", codeBlockState.CodeBlock.Content) @@ -376,7 +165,7 @@ func (model InteractiveModeModel) Update(message tea.Msg) (tea.Model, tea.Cmd) { codeBlockState := model.codeBlockState[step] codeBlockState.StdOut = message.StdOut codeBlockState.StdErr = message.StdErr - codeBlockState.Success = false + codeBlockState.Status = common.STATUS_FAILURE model.codeBlockState[step] = codeBlockState model.CommandLines = append(model.CommandLines, codeBlockState.StdErr) @@ -462,27 +251,27 @@ func (model InteractiveModeModel) Update(message tea.Msg) (tea.Model, tea.Cmd) { renderedStepSection, ) - if block.Success { - model.components.outputViewport.SetContent(block.StdOut) + // Only set the output if the block was executed, otherwise reset it. + if block.WasExecuted() { + if block.Succeeded() { + model.components.outputViewport.SetContent(block.StdOut) + } else { + model.components.outputViewport.SetContent(block.StdErr) + } } else { - model.components.outputViewport.SetContent(block.StdErr) + model.components.outputViewport.SetContent("") } model.components.azureCLIViewport.SetContent(strings.Join(model.CommandLines, "\n")) // Update all the viewports and append resulting commands. - var command tea.Cmd - - model.components.paginator.Page = model.currentCodeBlock - - model.components.stepViewport, command = model.components.stepViewport.Update(message) - commands = append(commands, command) - - model.components.outputViewport, command = model.components.outputViewport.Update(message) - commands = append(commands, command) - - model.components.azureCLIViewport, command = model.components.azureCLIViewport.Update(message) - commands = append(commands, command) + updatedComponents, componentCommands := updateComponents( + model.components, + model.currentCodeBlock, + message, + ) + commands = append(commands, componentCommands...) + model.components = updatedComponents return model, tea.Batch(commands...) } @@ -602,7 +391,7 @@ func NewInteractiveModeModel( StdOut: "", StdErr: "", Error: nil, - Success: false, + Status: common.STATUS_PENDING, } totalCodeBlocks += 1 @@ -615,46 +404,10 @@ func NewInteractiveModeModel( ui.CommandPrompt(language) + codeBlockState[0].CodeBlock.Content, } - // Configure extra keybinds used for executing the many/all commands. - executeAllKeybind := key.NewBinding( - key.WithKeys("a"), - key.WithHelp("a", "Execute all remaining commands."), - ) - - executeManyKeybind := key.NewBinding( - key.WithKeys("m"), - key.WithHelp("m", "Execute the next commands."), - ) - pauseKeybind := key.NewBinding( - key.WithKeys("p", "Pause execution of commands."), - ) - return InteractiveModeModel{ - scenarioTitle: title, - commands: InteractiveModeCommands{ - execute: key.NewBinding( - key.WithKeys("e"), - key.WithHelp("e", "Execute the current command."), - ), - quit: key.NewBinding( - key.WithKeys("q"), - key.WithHelp("q", "Quit the scenario."), - ), - previous: key.NewBinding( - key.WithKeys("left"), - key.WithHelp("←", "Go to the previous command."), - ), - next: key.NewBinding( - key.WithKeys("right"), - key.WithHelp("→", "Go to the next command."), - ), - // Only enabled when in the azure environment. - executeAll: executeAllKeybind, - executeMany: executeManyKeybind, - pause: pauseKeybind, - }, + scenarioTitle: title, + commands: NewInteractiveModeCommands(), stepsToBeExecuted: 0, - env: env, subscription: subscription, resourceGroupName: "", diff --git a/internal/engine/test/model.go b/internal/engine/test/model.go index b3388300..ad2c3f68 100644 --- a/internal/engine/test/model.go +++ b/internal/engine/test/model.go @@ -116,7 +116,7 @@ func (model TestModeModel) Update(message tea.Msg) (tea.Model, tea.Cmd) { codeBlockState := model.codeBlockState[step] codeBlockState.StdOut = message.StdOut codeBlockState.StdErr = message.StdErr - codeBlockState.Success = true + codeBlockState.Status = common.STATUS_SUCCESS codeBlockState.SimilarityScore = message.SimilarityScore model.codeBlockState[step] = codeBlockState @@ -174,7 +174,7 @@ func (model TestModeModel) Update(message tea.Msg) (tea.Model, tea.Cmd) { codeBlockState.StdOut = message.StdOut codeBlockState.StdErr = message.StdErr codeBlockState.Error = message.Error - codeBlockState.Success = false + codeBlockState.Status = common.STATUS_FAILURE codeBlockState.SimilarityScore = message.SimilarityScore model.codeBlockState[step] = codeBlockState @@ -278,7 +278,7 @@ func NewTestModeModel( StdOut: "", StdErr: "", Error: nil, - Success: false, + Status: common.STATUS_PENDING, } totalCodeBlocks += 1 diff --git a/internal/engine/test/model_test.go b/internal/engine/test/model_test.go index 6bd025ff..23c1c62b 100644 --- a/internal/engine/test/model_test.go +++ b/internal/engine/test/model_test.go @@ -57,7 +57,7 @@ func TestTestModeModel(t *testing.T) { assert.Equal(t, "bash", state.CodeBlock.Language) assert.Equal(t, "header1", state.CodeBlock.Header) assert.Equal(t, "echo 'hello world'", state.CodeBlock.Content) - assert.Equal(t, false, state.Success) + assert.Equal(t, true, state.Succeeded()) }) t.Run( @@ -89,7 +89,7 @@ func TestTestModeModel(t *testing.T) { // Assert outputs of the executed block. assert.Equal(t, "hello world\n", executedBlock.StdOut) assert.Equal(t, "", executedBlock.StdErr) - assert.Equal(t, true, executedBlock.Success) + assert.Equal(t, true, executedBlock.Succeeded()) } }, ) @@ -124,7 +124,7 @@ func TestTestModeModel(t *testing.T) { // Assert outputs of the executed block. assert.Equal(t, "hello world\n", executedBlock.StdOut) assert.Equal(t, "", executedBlock.StdErr) - assert.Equal(t, true, executedBlock.Success) + assert.Equal(t, true, executedBlock.Succeeded()) } else { assert.Fail(t, "Model is not a TestModeModel") } @@ -188,7 +188,7 @@ func TestTestModeModel(t *testing.T) { // Assert outputs of the executed block. assert.Equal(t, "hello world\n", executedBlock.StdOut) assert.Equal(t, "", executedBlock.StdErr) - assert.Equal(t, true, executedBlock.Success) + assert.Equal(t, true, executedBlock.Succeeded()) } else { assert.Fail(t, "Model is not a TestModeModel")