-
-
Notifications
You must be signed in to change notification settings - Fork 151
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[fix #92]
- Loading branch information
Showing
10 changed files
with
278 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
--- | ||
threshold: 18 | ||
total_score: 1177 | ||
total_score: 1211 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
require 'minitest' | ||
|
||
# monkey patch for minitest | ||
module Minitest | ||
# Prevent autorun from running tests when the VM closes | ||
# | ||
# Mutant needs control about the exit status of the VM and | ||
# the moment of test execution | ||
# | ||
# @api private | ||
# | ||
# @return [nil] | ||
def self.autorun | ||
end | ||
|
||
end # Minitest | ||
|
||
module Mutant | ||
class Integration | ||
# Minitest integration | ||
class Minitest < self | ||
TEST_METHOD_PREFIX = 'test_'.freeze | ||
TEST_FILE_PATTERN = './test/**/{test_*,*_test}.rb'.freeze | ||
|
||
register 'minitest' | ||
|
||
# Compose a runnable with test method | ||
# | ||
# This looks actually like a missing object on minitest implementation. | ||
class TestCase | ||
include Adamantium, Concord.new(:klass, :test_method) | ||
|
||
# Identification string | ||
# | ||
# @return [String] | ||
def identification | ||
"minitest:#{klass}##{test_method}" | ||
end | ||
memoize :identification | ||
|
||
# Run test case | ||
# | ||
# @param [Object] reporter | ||
# | ||
# @return [Boolean] | ||
def call(reporter) | ||
::Minitest::Runnable.run_one_method(klass, test_method, reporter) | ||
reporter.passed? | ||
end | ||
|
||
# Cover expression syntaxes | ||
# | ||
# @return [Array<String>] | ||
def expression_syntax | ||
klass.cover_expression | ||
end | ||
|
||
end # TestCase | ||
|
||
private_constant(*constants(false)) | ||
|
||
# Setup integration | ||
# | ||
# @return [self] | ||
def setup | ||
Pathname.glob(TEST_FILE_PATTERN) | ||
.map(&:to_s) | ||
.each(&method(:require)) | ||
|
||
self | ||
end | ||
|
||
# Call test integration | ||
# | ||
# @param [Array<Tests>] tests | ||
# | ||
# @return [Result::Test] | ||
# | ||
# rubocop:disable MethodLength | ||
def call(tests) | ||
test_cases = tests.map(&all_tests_index.method(:fetch)).to_set | ||
|
||
output = StringIO.new | ||
reporter = ::Minitest::SummaryReporter.new(output) | ||
start = Time.now | ||
|
||
passed = test_cases.all? { |test| test.call(reporter) } | ||
output.rewind | ||
|
||
Result::Test.new( | ||
passed: passed, | ||
tests: tests, | ||
output: output.read, | ||
runtime: Time.now - start | ||
) | ||
end | ||
|
||
# All tests exposed by this integration | ||
# | ||
# @return [Array<Test>] | ||
def all_tests | ||
all_tests_index.keys | ||
end | ||
memoize :all_tests | ||
|
||
private | ||
|
||
# The index of all tests to runnable test cases | ||
# | ||
# @return [Hash<Test,TestCase>] | ||
def all_tests_index | ||
all_test_cases.each_with_object({}) do |test_case, index| | ||
index[construct_test(test_case)] = test_case | ||
end | ||
end | ||
memoize :all_tests_index | ||
|
||
# Construct test from test case | ||
# | ||
# @param [TestCase] | ||
# | ||
# @return [Test] | ||
def construct_test(test_case) | ||
Test.new( | ||
id: test_case.identification, | ||
expression: config.expression_parser.(test_case.expression_syntax) | ||
) | ||
end | ||
|
||
# All minitest test cases | ||
# | ||
# Intentional utility method. | ||
# | ||
# @return [Array<TestCase>] | ||
def all_test_cases | ||
::Minitest::Runnable.runnables.flat_map(&method(:test_case)) | ||
end | ||
|
||
# Turn a minitest runnable into its test cases | ||
# | ||
# Intentional utility method. | ||
# | ||
# @param [Object] runnable | ||
# | ||
# @return [Array<TestCase>] | ||
def test_case(runnable) | ||
runnable.runnable_methods.map(&TestCase.method(&:new)) | ||
end | ||
|
||
end # Minitest | ||
end # Integration | ||
end # Mutant |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# encoding: utf-8 | ||
# | ||
require File.expand_path('../lib/mutant/version', __FILE__) | ||
|
||
Gem::Specification.new do |gem| | ||
gem.name = 'mutant-minitest' | ||
gem.version = Mutant::VERSION.dup | ||
gem.authors = ['Markus Schirp'] | ||
gem.email = %w[[email protected]] | ||
gem.description = 'Minitest integration for mutant' | ||
gem.summary = gem.description | ||
gem.homepage = 'https://github.com/mbj/mutant' | ||
gem.license = 'MIT' | ||
|
||
gem.require_paths = %w[lib] | ||
gem.files = `git ls-files -- lib/mutant/integration/minitest.rb`.split("\n") | ||
gem.test_files = `git ls-files -- spec/integration/mutant/minitest.rb`.split("\n") | ||
gem.extra_rdoc_files = %w[TODO LICENSE] | ||
|
||
gem.add_runtime_dependency('mutant', "~> #{gem.version}") | ||
gem.add_runtime_dependency('minitest', '¨> 5.5') | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
RSpec.describe 'minitest integration', mutant: false do | ||
|
||
let(:base_cmd) { 'bundle exec mutant -I test -I lib --require test_app --use minitest' } | ||
|
||
context 'Minitest 5.5.0' do | ||
let(:gemfile) { 'Gemfile.minitest-stdlib' } | ||
|
||
it_behaves_like 'framework integration' | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
RSpec.describe Mutant::Isolation::Fork, mutant: false do | ||
let(:object) { Mutant::Config::DEFAULT.isolation } | ||
|
||
it 'does isolate side effects' do | ||
initial = 1 | ||
object.call { initial = 2 } | ||
expect(initial).to be(1) | ||
end | ||
|
||
it 'return block value' do | ||
expect(object.call { :foo }).to be(:foo) | ||
end | ||
|
||
it 'wraps exceptions' do | ||
expect { object.call { fail } }.to raise_error( | ||
Mutant::Isolation::Error, | ||
'marshal data too short' | ||
) | ||
end | ||
|
||
it 'wraps exceptions caused by crashing ruby' do | ||
expect do | ||
object.call do | ||
fail RbBug.call | ||
end | ||
end.to raise_error(Mutant::Isolation::Error) | ||
end | ||
|
||
it 'redirects $stderr of children to /dev/null' do | ||
begin | ||
Tempfile.open('mutant-test') do |file| | ||
$stderr = file | ||
object.call { $stderr.puts('test') } | ||
file.rewind | ||
expect(file.read).to eql('') | ||
end | ||
ensure | ||
$stderr = STDERR | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
source 'https://rubygems.org' | ||
|
||
gem 'minitest', '~> 5.5' | ||
gem 'mutant', path: '../' | ||
gem 'mutant-minitest', path: '../' | ||
gem 'adamantium' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
$LOAD_PATH << File.join(File.dirname(__FILE__), '../lib') | ||
|
||
require 'test_app' | ||
require 'minitest/autorun' | ||
|
||
# require spec support files and shared behavior | ||
Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file| | ||
require file | ||
end | ||
|
||
class TestAppTest < Minitest::Test | ||
def self.cover(expression) | ||
@expression = expression | ||
end | ||
|
||
def self.cover_expression | ||
unless @expression | ||
fail "Cover expression for #{self} is not specified" | ||
end | ||
|
||
@expression | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
require 'test_helper' | ||
|
||
class TestApp::LiteralTest < TestAppTest | ||
cover 'TestApp::Literal*' | ||
|
||
def test_command | ||
object = ::TestApp::Literal.new | ||
subject = object.command('x') | ||
|
||
assert_equal object, subject | ||
end | ||
|
||
def test_string | ||
object = ::TestApp::Literal.new | ||
subject = object.string | ||
|
||
assert_equal 'string', subject | ||
end | ||
end |