From 2cb24e3a51f018c01dd92462d12cf51826705625 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Sun, 12 Feb 2017 13:35:17 +0100 Subject: [PATCH 1/2] Ensure Null integration can be loaded --- lib/mutest.rb | 1 + lib/mutest/integration.rb | 24 ------------------------ lib/mutest/integration/null.rb | 27 +++++++++++++++++++++++++++ spec/unit/mutest/cli_spec.rb | 15 ++++++++++++++- spec/unit/mutest/integration_spec.rb | 4 ++-- 5 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 lib/mutest/integration/null.rb diff --git a/lib/mutest.rb b/lib/mutest.rb index 5033f386..ea8068ce 100644 --- a/lib/mutest.rb +++ b/lib/mutest.rb @@ -179,6 +179,7 @@ def self.ci? require 'mutest/expression/namespace' require 'mutest/test' require 'mutest/integration' +require 'mutest/integration/null' require 'mutest/selector' require 'mutest/selector/expression' require 'mutest/config' diff --git a/lib/mutest/integration.rb b/lib/mutest/integration.rb index ae1954fa..df70c3c6 100644 --- a/lib/mutest/integration.rb +++ b/lib/mutest/integration.rb @@ -47,29 +47,5 @@ def setup def expression_parser config.expression_parser end - - # Null integration that never kills a mutation - class Null < self - # Available tests for integration - # - # @return [Enumerable] - def all_tests - EMPTY_ARRAY - end - - # Run a collection of tests - # - # @param [Enumerable] tests - # - # @return [Result::Test] - def call(tests) - Result::Test.new( - output: '', - passed: true, - runtime: 0.0, - tests: tests - ) - end - end # Null end # Integration end # Mutest diff --git a/lib/mutest/integration/null.rb b/lib/mutest/integration/null.rb new file mode 100644 index 00000000..1de7b154 --- /dev/null +++ b/lib/mutest/integration/null.rb @@ -0,0 +1,27 @@ +module Mutest + class Integration + # Null integration that never kills a mutation + class Null < self + # Available tests for integration + # + # @return [Enumerable] + def all_tests + EMPTY_ARRAY + end + + # Run a collection of tests + # + # @param [Enumerable] tests + # + # @return [Result::Test] + def call(tests) + Result::Test.new( + output: '', + passed: true, + runtime: 0.0, + tests: tests + ) + end + end # Null + end # Integration +end # Mutest diff --git a/spec/unit/mutest/cli_spec.rb b/spec/unit/mutest/cli_spec.rb index d8a320ad..1bbc1cc4 100644 --- a/spec/unit/mutest/cli_spec.rb +++ b/spec/unit/mutest/cli_spec.rb @@ -137,7 +137,7 @@ end context 'with use flag' do - context 'when integration exists' do + context 'when using the existing integration with rspec' do let(:flags) { %w[--use rspec] } before do @@ -151,6 +151,19 @@ let(:expected_integration) { Mutest::Integration::Rspec } end + context 'when specifying the default null integration explicitely' do + let(:flags) { %w[--use null] } + let(:expected_integration) { Mutest::Integration::Null } + + before do + expect(Kernel).to receive(:require) + .with('mutest/integration/null') + .and_call_original + end + + it_should_behave_like 'a cli parser' + end + context 'when integration does NOT exist' do let(:flags) { %w[--use other] } diff --git a/spec/unit/mutest/integration_spec.rb b/spec/unit/mutest/integration_spec.rb index 7b028199..41067104 100644 --- a/spec/unit/mutest/integration_spec.rb +++ b/spec/unit/mutest/integration_spec.rb @@ -13,8 +13,8 @@ describe '.setup' do subject { described_class.setup(kernel, name) } - let(:name) { 'null' } - let(:kernel) { class_double(Kernel) } + let(:name) { 'null' } + let(:kernel) { Kernel } before do expect(kernel).to receive(:require) From 6c5d8b49616b33a3797e89e8e05478d6baf1dcde Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Sat, 18 Feb 2017 09:29:42 +0100 Subject: [PATCH 2/2] Expose Kernel#require and use it Rubygems overrides Kernel#require but not Kernel.require. This means using Kernel.require makes requires fail for modules installed through rubygems. This commit introduces a new class, Requirer, that exposes the normally private method Kernel#require, and updates the DI mechanism to call that method instead of Kernel.require. --- lib/mutest.rb | 2 ++ lib/mutest/cli.rb | 2 +- lib/mutest/config.rb | 1 + lib/mutest/requirer.rb | 6 ++++++ spec/unit/mutest/cli_spec.rb | 7 +++---- spec/unit/mutest/integration_spec.rb | 8 ++++---- 6 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 lib/mutest/requirer.rb diff --git a/lib/mutest.rb b/lib/mutest.rb index ea8068ce..377696c7 100644 --- a/lib/mutest.rb +++ b/lib/mutest.rb @@ -207,6 +207,7 @@ def self.ci? require 'mutest/reporter/cli/tput' require 'mutest/reporter/cli/format' require 'mutest/repository' +require 'mutest/requirer' require 'mutest/zombifier' module Mutest @@ -231,6 +232,7 @@ class Config process: Process ), jobs: ::Parallel.processor_count, + requirer: Requirer.new, kernel: Kernel, load_path: $LOAD_PATH, matcher: Matcher::Config::DEFAULT, diff --git a/lib/mutest/cli.rb b/lib/mutest/cli.rb index 22384c04..c1e73b11 100644 --- a/lib/mutest/cli.rb +++ b/lib/mutest/cli.rb @@ -99,7 +99,7 @@ def add_environment_options(opts) # # @return [undefined] def setup_integration(name) - with(integration: Integration.setup(config.kernel, name)) + with(integration: Integration.setup(config.requirer, name)) rescue LoadError raise Error, "Could not load integration #{name.inspect} (you may want to try installing the gem mutest-#{name})" end diff --git a/lib/mutest/config.rb b/lib/mutest/config.rb index 0970a48d..eeee1b5d 100644 --- a/lib/mutest/config.rb +++ b/lib/mutest/config.rb @@ -16,6 +16,7 @@ class Config :matcher, :open3, :pathname, + :requirer, :requires, :reporter, :zombie diff --git a/lib/mutest/requirer.rb b/lib/mutest/requirer.rb new file mode 100644 index 00000000..da5d530a --- /dev/null +++ b/lib/mutest/requirer.rb @@ -0,0 +1,6 @@ +module Mutest + # Class that exposes #require as a public method + class Requirer + public :require + end # Requirer +end # Mutest diff --git a/spec/unit/mutest/cli_spec.rb b/spec/unit/mutest/cli_spec.rb index 1bbc1cc4..4a5a3895 100644 --- a/spec/unit/mutest/cli_spec.rb +++ b/spec/unit/mutest/cli_spec.rb @@ -139,16 +139,15 @@ context 'with use flag' do context 'when using the existing integration with rspec' do let(:flags) { %w[--use rspec] } + let(:expected_integration) { Mutest::Integration::Rspec } before do - expect(Kernel).to receive(:require) + expect(Mutest::Config::DEFAULT.requirer).to receive(:require) .with('mutest/integration/rspec') .and_call_original end it_should_behave_like 'a cli parser' - - let(:expected_integration) { Mutest::Integration::Rspec } end context 'when specifying the default null integration explicitely' do @@ -156,7 +155,7 @@ let(:expected_integration) { Mutest::Integration::Null } before do - expect(Kernel).to receive(:require) + expect(Mutest::Config::DEFAULT.requirer).to receive(:require) .with('mutest/integration/null') .and_call_original end diff --git a/spec/unit/mutest/integration_spec.rb b/spec/unit/mutest/integration_spec.rb index 41067104..cbe5aba4 100644 --- a/spec/unit/mutest/integration_spec.rb +++ b/spec/unit/mutest/integration_spec.rb @@ -11,13 +11,13 @@ end describe '.setup' do - subject { described_class.setup(kernel, name) } + subject { described_class.setup(requirer, name) } - let(:name) { 'null' } - let(:kernel) { Kernel } + let(:name) { 'null' } + let(:requirer) { Mutest::Requirer.new } before do - expect(kernel).to receive(:require) + expect(requirer).to receive(:require) .with('mutest/integration/null') end