AutomatedTestDrivenDevelopmentAgentWithSpinner

InfoGenerateCreated ByPackages

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