Module: Ace::TestSupport::SubprocessRunner

Included in:
BaseTestCase
Defined in:
lib/ace/test_support/subprocess_runner.rb

Overview

Module for running test code in isolated subprocesses This ensures ENV variables and other global state don’t leak between tests

Instance Method Summary collapse

Instance Method Details

#run_in_clean_env(code:, requires: []) ⇒ Array<String, Process::Status>

Run Ruby code in a clean environment (without PROJECT_ROOT_PATH)

Parameters:

  • code (String)

    Ruby code to execute

  • requires (Array<String>) (defaults to: [])

    Libraries to require before executing code

Returns:

  • (Array<String, Process::Status>)

    stdout+stderr output and exit status



28
29
30
31
32
33
# File 'lib/ace/test_support/subprocess_runner.rb', line 28

def run_in_clean_env(code:, requires: [])
  # Create clean environment without PROJECT_ROOT_PATH
  # We need to explicitly unset it by setting to nil
  clean_env = {"PROJECT_ROOT_PATH" => nil}
  run_in_subprocess(env: clean_env, code: code, requires: requires)
end

#run_in_subprocess(code:, env: {}, requires: []) ⇒ Array<String, Process::Status>

Run Ruby code in a subprocess with specified environment

Parameters:

  • env (Hash) (defaults to: {})

    Environment variables for the subprocess

  • code (String)

    Ruby code to execute

  • requires (Array<String>) (defaults to: [])

    Libraries to require before executing code

Returns:

  • (Array<String, Process::Status>)

    stdout+stderr output and exit status



16
17
18
19
20
21
22
# File 'lib/ace/test_support/subprocess_runner.rb', line 16

def run_in_subprocess(code:, env: {}, requires: [])
  # Build require flags
  require_flags = requires.flat_map { |r| ["-r", r] }

  # Execute in subprocess
  Open3.capture2e(env, RbConfig.ruby, *require_flags, "-e", code)
end

#run_in_temp_dir(code:, env: {}, requires: []) ⇒ Array<String, Process::Status>

Run Ruby code in a subprocess with a temporary working directory

Parameters:

  • env (Hash) (defaults to: {})

    Environment variables for the subprocess

  • code (String)

    Ruby code to execute (will have access to temp_dir variable)

  • requires (Array<String>) (defaults to: [])

    Libraries to require before executing code

Returns:

  • (Array<String, Process::Status>)

    stdout+stderr output and exit status



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ace/test_support/subprocess_runner.rb', line 40

def run_in_temp_dir(code:, env: {}, requires: [])
  Dir.mktmpdir("ace-test-") do |temp_dir|
    wrapped_code = <<~RUBY
      temp_dir = "#{temp_dir}"
      Dir.chdir(temp_dir)
      #{code}
    RUBY

    run_in_subprocess(env: env, code: wrapped_code, requires: requires)
  end
end

#run_isolated_test_file(test_file, env: {}) ⇒ Array<String, Process::Status>

Run a test file in an isolated subprocess Useful for testing code that modifies require paths or other global state

Parameters:

  • test_file (String)

    Path to test file

  • env (Hash) (defaults to: {})

    Environment variables for the subprocess

Returns:

  • (Array<String, Process::Status>)

    stdout+stderr output and exit status



57
58
59
60
61
62
# File 'lib/ace/test_support/subprocess_runner.rb', line 57

def run_isolated_test_file(test_file, env: {})
  clean_env = ENV.to_h.reject { |k, _| k == "PROJECT_ROOT_PATH" }.merge(env)

  # Run the test file directly with Ruby
  Open3.capture2e(clean_env, RbConfig.ruby, test_file)
end