Skip to content

Commit

Permalink
Add test only runner
Browse files Browse the repository at this point in the history
  • Loading branch information
mbj committed Feb 12, 2024
1 parent 7096368 commit 93d2b48
Show file tree
Hide file tree
Showing 20 changed files with 830 additions and 210 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ jobs:
ruby: ruby-3.1
- os: macos-latest
ruby: ruby-3.0
execution:
- bundle exec rspec spec/unit
- bundle exec mutant environment test run spec/unit
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- run: bundle exec rspec spec/unit
- run: ${{ matrix.execution }}
ruby-mutant:
name: Mutation coverage
runs-on: ${{ matrix.os }}
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,4 @@ DEPENDENCIES
rubocop (~> 1.7)

BUNDLED WITH
2.4.10
2.5.3
1 change: 1 addition & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ integration:
# Below shows an example configuring rspec to use a static seed from the config file.
arguments:
- --fail-fast # rspec integration default, keep this when specifying manual options!
- --force-color # rspec integration default, keep this if colored output is not an issue for you
- --seed # option
- '0' # option value, needs to be a string.
- spec # rspec integration default, tell rspec integration where to find specs
Expand Down
3 changes: 3 additions & 0 deletions lib/mutant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ module Mutant
require 'mutant/expression/namespace'
require 'mutant/expression/parser'
require 'mutant/test'
require 'mutant/test/runner'
require 'mutant/test/runner/sink'
require 'mutant/timer'
require 'mutant/integration'
require 'mutant/integration/null'
Expand Down Expand Up @@ -243,6 +245,7 @@ module Mutant
require 'mutant/reporter/cli/printer/mutation_result'
require 'mutant/reporter/cli/printer/status_progressive'
require 'mutant/reporter/cli/printer/subject_result'
require 'mutant/reporter/cli/printer/test'
require 'mutant/reporter/cli/format'
require 'mutant/repository'
require 'mutant/repository/diff'
Expand Down
28 changes: 27 additions & 1 deletion lib/mutant/bootstrap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,32 @@ def self.call(env)
selected_subjects.flat_map(&:mutations)
end

setup_integration(
env: env,
mutations: mutations,
selected_subjects: selected_subjects
)
end
end
# rubocop:enable Metrics/MethodLength

# Run test only bootstrap
#
# @param [Env] env
#
# @return [Either<String, Env>]
def self.call_test(env)
env.record(:bootstrap) do
setup_integration(
env: load_hooks(env),
mutations: [],
selected_subjects: []
)
end
end

def self.setup_integration(env:, mutations:, selected_subjects:)
env.record(__method__) do
Integration.setup(env).fmap do |integration|
env.with(
integration: integration,
Expand All @@ -57,7 +83,7 @@ def self.call(env)
end
end
end
# rubocop:enable Metrics/MethodLength
private_class_method :setup_integration

def self.load_hooks(env)
env.record(__method__) do
Expand Down
39 changes: 38 additions & 1 deletion lib/mutant/cli/command/environment/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@ class Test < self
NAME = 'test'
SHORT_DESCRIPTION = 'test subcommands'

private

def parse_remaining_arguments(arguments)
arguments.each(&method(:add_integration_argument))
Either::Right.new(self)
end

def bootstrap
env = Env.empty(world, @config)

env
.record(:config) { Config.load(cli_config: @config, world: world) }
.bind { |config| Bootstrap.call_test(env.with(config: config)) }
end

class List < self
NAME = 'list'
SHORT_DESCRIPTION = 'List tests detected in the environment'
Expand All @@ -28,7 +43,29 @@ def list_tests(env)
end
end

SUBCOMMANDS = [List].freeze
class Run < self
NAME = 'run'
SHORT_DESCRIPTION = 'Run tests'
SUBCOMMANDS = EMPTY_ARRAY

private

def action
bootstrap
.bind(&Mutant::Test::Runner.public_method(:call))
.bind(&method(:from_result))
end

def from_result(result)
if result.success?
Either::Right.new(nil)
else
Either::Left.new('Test failures, exiting nonzero!')
end
end
end

SUBCOMMANDS = [List, Run].freeze
end # Test
end # Environment
end # Command
Expand Down
6 changes: 5 additions & 1 deletion lib/mutant/integration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ module Mutant

# Abstract base class mutant test framework integrations
class Integration
include AbstractType, Adamantium, Anima.new(:arguments, :expression_parser, :world)
include AbstractType, Adamantium, Anima.new(
:arguments,
:expression_parser,
:world
)

LOAD_MESSAGE = <<~'MESSAGE'
Unable to load integration mutant-%<integration_name>s:
Expand Down
22 changes: 16 additions & 6 deletions lib/mutant/integration/rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,36 @@ class Rspec < self
ALL_EXPRESSION = Expression::Namespace::Recursive.new(scope_name: nil)
EXPRESSION_CANDIDATE = /\A([^ ]+)(?: )?/
EXIT_SUCCESS = 0
DEFAULT_CLI_OPTIONS = %w[--fail-fast spec].freeze
DEFAULT_CLI_OPTIONS = %w[--fail-fast --force-color spec].freeze
TEST_ID_FORMAT = 'rspec:%<index>d:%<location>s/%<description>s'

private_constant(*constants(false))

def freeze
super if @setup_elapsed
self
end

# Initialize rspec integration
#
# @return [undefined]
def initialize(*)
super
@runner = RSpec::Core::Runner.new(RSpec::Core::ConfigurationOptions.new(effective_arguments))
@rspec_world = RSpec.world
@runner = RSpec::Core::Runner.new(RSpec::Core::ConfigurationOptions.new(effective_arguments))
@rspec_world = RSpec.world
@setup_elapsed = nil
end

# Setup rspec integration
#
# @return [self]
def setup
@runner.setup($stderr, $stdout)
example_group_map
@setup_elapsed = timer.elapsed do
@runner.setup(world.stderr, world.stdout)
example_group_map
end
reset_examples
self
freeze
end
memoize :setup

Expand All @@ -55,7 +63,9 @@ def setup
#
# @return [Result::Test]
def call(tests)
reset_examples
setup_examples(tests.map(&all_tests_index))
@runner.configuration.start_time = ::Time.now - @setup_elapsed
start = timer.now
passed = @runner.run_specs(@rspec_world.ordered_example_groups).equal?(EXIT_SUCCESS)
Result::Test.new(
Expand Down
28 changes: 28 additions & 0 deletions lib/mutant/reporter/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ def start(env)
self
end

# Report test start
#
# @param [Env] env
#
# @return [self]
def test_start(env)
write(format.test_start(env))
self
end

# Report progress object
#
# @param [Parallel::Status] status
Expand All @@ -38,6 +48,14 @@ def progress(status)
self
end

# Report progress object
#
# @return [self]
def test_progress(status)
write(format.test_progress(status))
self
end

# Report delay in seconds
#
# @return [Float]
Expand Down Expand Up @@ -65,6 +83,16 @@ def report(env)
self
end

# Report env
#
# @param [Result::Env] env
#
# @return [self]
def test_report(env)
Printer::Test::EnvResult.call(output: output, object: env)
self
end

private

def write(frame)
Expand Down
21 changes: 19 additions & 2 deletions lib/mutant/reporter/cli/format.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ class Format

# Progress representation
#
# @param [Runner::Status] status
#
# @return [String]
abstract_method :progress

# Progress representation
#
# @return [String]
abstract_method :test_progress

# Report delay in seconds
#
# @return [Float]
Expand Down Expand Up @@ -69,13 +72,27 @@ def start(env)
format(Printer::Env, env)
end

# Test start representation
#
# @return [String]
def test_start(env)
format(Printer::Test::Env, env)
end

# Progress representation
#
# @return [String]
def progress(status)
format(Printer::StatusProgressive, status)
end

# Progress representation
#
# @return [String]
def test_progress(status)
format(Printer::Test::StatusProgressive, status)
end

private

def new_buffer
Expand Down
Loading

0 comments on commit 93d2b48

Please sign in to comment.