AutoRspecPassBlueprint

InfoGenerateCreated ByPackages

This code defines a module structure within `Sublayer` and a class `RspecAutomationGenerator` under the `Generators` module. The purpose of this class is to automatically modify an implementation file until all associated RSpec tests pass. Here's a high-level description of its functionality:

1. **Initialization**: The `RspecAutomationGenerator` class initializes with paths to the implementation and test files, setting an initial state of tests not passing.
2. **Generate Method**: The `generate` method runs in a loop until all tests pass. It:
- Runs the RSpec tests.
- Checks the test status.
- If tests are failing, modifies the implementation file in an attempt to pass the tests on the next run.
3. **Check Status Method**: This method runs the tests using a command, captures the output and status, and sets the `@tests_passing` flag based on the test results. It also prints the test status.
4. **Take Step Method**: This method generates a modified implementation based on the current implementation file, test file, and test output. It then writes the modified implementation back to the file system.

Noteworthy details: This class relies on other components (`RunTestCommandAction`, `ModifiedImplementationToPassTestsGenerator`, and `WriteFileAction`) to perform specific actions like running tests and generating modifications, making it modular and extensible.

module Sublayer
  module Generators
    class RspecAutomationGenerator
      def initialize(implementation_file_path:, test_file_path:)
        @implementation_file_path = implementation_file_path
        @test_file_path = test_file_path
        @tests_passing = false
      end

      def generate
        until @tests_passing
          puts "Running tests..."
          check_status
          next if @tests_passing

          puts "Modifying implementation to pass tests..."
          take_step
        end
        puts "All tests are passing!"
      end

      private

      def check_status
        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

      def take_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
    end
  end
end