AutomatedTestDrivenDevelopmentAgentWithSpinner
This code defines a class `RspecAgentWithSpinner` within the `Sublayer::Agents` module, which appears to be an agent designed to automatically run tests on a specified implementation file and make modifications to that file in order to ensure the tests pass. The class inherits from a base class named `Base` and has several methods:
- Initialization (`initialize`): Takes paths to an implementation file and a test file and sets up initial flags and variables.
- `trigger_on_files_changed`: Triggers actions when the specified files have changed.
- `check_status`: Runs the tests using the `rspec` command on the test file and updates the status based on whether the tests pass or fail. Outputs the result to the console.
- `goal_condition`: Defines a goal condition where all tests must be passing.
- `step`: Takes a step to modify the implementation file in such a way that the tests should pass. It generates a modified implementation and writes it back to the file.
- `with_spinner`: A utility method that adds a spinner animation to indicate progress during long-running operations.
- `check_status_with_spinner`: Adds a spinner to the `check_status` method for visual feedback.
- `step_with_spinner`: Adds a spinner to the `step` method for visual feedback.
Noteworthy details include the use of threads for the spinner animation and ensuring that these threads are properly killed after the operation completes. This class automates the process of running tests and modifying code to pass those tests, providing visual feedback through spinner animations.
module Sublayer
module Agents
class RspecAgentWithSpinner < Base
def initialize(implementation_file_path:, test_file_path:)
@implementation_file_path = implementation_file_path
@test_file_path = test_file_path
@tests_passing = false
end
trigger_on_files_changed do
[@implementation_file_path, @test_file_path]
end
check_status do
stdout, stderr, status = Sublayer::Actions::RunTestCommandAction.new( test_command: "rspec #{@test_file_path}").call
puts stdout
@test_output = stdout
@tests_passing = (status.exitstatus == 0)
@tests_passing ? puts("Tests passing") : puts("Tests failing")
end
goal_condition do
@tests_passing == true
end
step do
puts "Taking a step"
modified_implementation = Sublayer::Generators::ModifiedImplementationToPassTestsGenerator.new(
implementation_file_contents: File.read(@implementation_file_path),
test_file_contents: File.read(@test_file_path),
test_output: @test_output
).generate
Sublayer::Actions::WriteFileAction.new( file_contents: modified_implementation, file_path: @implementation_file_path).call
end
# New method to add a spinner
def with_spinner(message)
chars = ['|', '/', '-', '\']
delay = 0.1
thread = Thread.new do
while true do
chars.each do |char|
print "\r#{message} #{char}"
sleep(delay)
end
end
end
yield
ensure
thread.kill
print "\r"
end
# Modify check_status to include the spinner
def check_status_with_spinner
with_spinner('Running tests') do
check_status
end
end
# Modify step to include the spinner
def step_with_spinner
with_spinner('Modifying implementation') do
step
end
end
end
end
end