require 'json'
require 'open3'
# Spawn the mock-server binary and set MOCK_SERVER_URL for all tests.
#
# Two execution modes:
# 1. External mode (`alef test-apps run` parent): MOCK_SERVER_URL is already set.
# Use it as-is together with any MOCK_SERVERS / MOCK_SERVER_<FIXTURE_ID> vars
# that the parent exported. Do NOT spawn our own server.
# 2. Standalone mode (direct `bundle exec rspec` / `task ruby:smoke`): Build the
# mock-server binary if it is missing, then spawn it, capture its URL, and
# tear it down on exit.
RSpec.configure do |config|
config.before(:suite) do
existing_url = ENV['MOCK_SERVER_URL']
if existing_url && !existing_url.empty?
# Expand the parent-set MOCK_SERVERS JSON into per-fixture
# MOCK_SERVER_<FIXTURE_ID> env vars so tests reading
# `MOCK_SERVER_<UPPER>` find the dedicated per-fixture URL
# (without this, tests fall back to the shared-server namespaced
# URL where origin-relative asset paths 404).
begin
mock_servers_json = ENV['MOCK_SERVERS']
if mock_servers_json && !mock_servers_json.empty?
JSON.parse(mock_servers_json).each do |fid, furl|
ENV["MOCK_SERVER_#{fid.upcase}"] = furl
end
end
rescue JSON::ParserError
# Silently ignore JSON parse errors — MOCK_SERVERS may be malformed.
end
next
end
bin = File.expand_path('../../rust/target/release/mock-server', __dir__)
fixtures_dir = File.expand_path('../../../fixtures', __dir__)
unless File.exist?(bin)
# Build the mock-server from the e2e/rust/ crate that alef generated.
manifest = File.expand_path('../../rust/Cargo.toml', __dir__)
raise "mock-server Cargo.toml not found at #{manifest}" unless File.exist?(manifest)
system(
'cargo', 'build', '--release',
'--manifest-path', manifest,
'--bin', 'mock-server',
exception: true
)
raise "mock-server binary still missing after build: #{bin}" unless File.exist?(bin)
end
stdin, stdout, _stderr, _wait = Open3.popen3(bin, fixtures_dir)
# Read startup lines: MOCK_SERVER_URL= then optional MOCK_SERVERS=.
url = nil
8.times do
line = stdout.readline.strip rescue break
if line.start_with?('MOCK_SERVER_URL=')
url = line.split('=', 2).last
ENV['MOCK_SERVER_URL'] = url
elsif line.start_with?('MOCK_SERVERS=')
json_val = line.split('=', 2).last
ENV['MOCK_SERVERS'] = json_val
JSON.parse(json_val).each do |fid, furl|
ENV["MOCK_SERVER_#{fid.upcase}"] = furl
end
break
elsif url
break
end
end
# Drain stdout in background.
Thread.new { stdout.read }
# Store stdin so we can close it on teardown.
@_mock_server_stdin = stdin
end
config.after(:suite) do
@_mock_server_stdin&.close
end
end