m 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby-ci.yml +15 -10
- data/.gitignore +1 -0
- data/.standard.yml +1 -0
- data/Gemfile +6 -6
- data/README.md +4 -40
- data/Rakefile +13 -87
- data/bin/m +2 -2
- data/lib/error_tests/error_test.rb +1 -1
- data/lib/m/executor.rb +23 -24
- data/lib/m/finish_line.rb +83 -0
- data/lib/m/frameworks.rb +27 -23
- data/lib/m/parser.rb +33 -33
- data/lib/m/runner.rb +3 -3
- data/lib/m/runners/base.rb +4 -4
- data/lib/m/runners/minitest_4.rb +1 -1
- data/lib/m/runners/minitest_5.rb +3 -5
- data/lib/m/runners/minitest_6.rb +3 -0
- data/lib/m/runners/test_unit.rb +6 -6
- data/lib/m/runners/unsupported_framework.rb +2 -2
- data/lib/m/test_collection.rb +5 -5
- data/lib/m/test_method.rb +13 -18
- data/lib/m/testable.rb +2 -2
- data/lib/m/version.rb +1 -1
- data/lib/m.rb +4 -4
- data/m.gemspec +14 -16
- data/test/Rakefile +2 -2
- data/test/active_support_test.rb +22 -17
- data/test/allocations.rb +10 -13
- data/test/bench.rb +10 -17
- data/test/empty_test.rb +2 -2
- data/test/everything_test.rb +8 -12
- data/test/examples/active_support_example_test.rb +2 -5
- data/test/examples/active_support_unescaped_example_test.rb +2 -5
- data/test/examples/empty_example_test.rb +1 -1
- data/test/examples/{minitest_5_example_test.rb → minitest_5_or_6_example_test.rb} +2 -2
- data/test/examples/minitest_example_test.rb +3 -5
- data/test/examples/multiple_example_test.rb +3 -3
- data/test/examples/subdir/a_test.rb +1 -1
- data/test/examples/subdir/another_subdir/d_test.rb +1 -1
- data/test/examples/subdir/another_subdir/yet_another_subdir/e_test.rb +1 -1
- data/test/examples/subdir/b_test.rb +1 -1
- data/test/examples/subdir/c_test.rb +1 -1
- data/test/examples/subdir_with_failures/a_test.rb +1 -1
- data/test/examples/test_unit_example_test.rb +2 -2
- data/test/exit_codes_test.rb +7 -7
- data/test/{minitest_5_test.rb → minitest_test.rb} +18 -12
- data/test/multiple_test.rb +4 -4
- data/test/options_test.rb +14 -14
- data/test/test_helper.rb +18 -24
- data/test/test_unit_test.rb +14 -9
- metadata +17 -95
- data/.travis.yml +0 -19
- data/Appraisals +0 -11
- data/Gemfile.lock +0 -74
- data/gemfiles/minitest4.gemfile +0 -10
- data/gemfiles/minitest4.gemfile.lock +0 -73
- data/gemfiles/minitest5.gemfile +0 -10
- data/gemfiles/minitest5.gemfile.lock +0 -73
- data/gemfiles/test_unit_gem.gemfile +0 -10
- data/gemfiles/test_unit_gem.gemfile.lock +0 -76
- data/test/examples/minitest_4_example_test.rb +0 -34
- data/test/minitest_4_test.rb +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4e5825f9f89739032571e003824817f6ee777b2ce56f32b6404956b6d6a29d93
|
|
4
|
+
data.tar.gz: c54e2cc45a805c2b4ed8e3a7fa7104aafea8d81b0492fd40505a850247a36a64
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b612e6a37f7c14b6247ffa753ba89bc790cc4c3ea51b569e96fbe04d10fc91e4df4ef29f5ff7526a2aece12706ee8d0fbd8b6fd80d65a3fb5c072038d368c57
|
|
7
|
+
data.tar.gz: 800ddcf684b4a736c697f439986cdd3979d2ef80f9c037e4fdfcca1ad263eb518de7809a8bc76a312623358cdbd47a8c1b7b77a939deaba472681a659cf8205a
|
|
@@ -10,27 +10,32 @@ on:
|
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
12
|
test:
|
|
13
|
-
runs-on: ubuntu-latest
|
|
14
13
|
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
15
|
matrix:
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
- minitest5
|
|
19
|
-
- test_unit_gem
|
|
16
|
+
os:
|
|
17
|
+
- ubuntu-latest
|
|
20
18
|
ruby:
|
|
21
|
-
- ruby-2.6
|
|
22
19
|
- ruby-2.7
|
|
23
20
|
- ruby-3.0
|
|
21
|
+
- ruby-3.1
|
|
22
|
+
- ruby-3.2
|
|
23
|
+
- ruby-3.3
|
|
24
|
+
- ruby-3.4
|
|
25
|
+
- ruby-4.0
|
|
26
|
+
- jruby
|
|
24
27
|
- truffleruby
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
include:
|
|
29
|
+
- { os: macos-latest, ruby: ruby-2.7 }
|
|
30
|
+
- { os: macos-latest, ruby: ruby-4.0 }
|
|
31
|
+
runs-on: ${{ matrix.os }}
|
|
27
32
|
steps:
|
|
28
33
|
- name: Checkout
|
|
29
|
-
uses: actions/checkout@
|
|
34
|
+
uses: actions/checkout@v6
|
|
30
35
|
- name: Install
|
|
31
36
|
uses: ruby/setup-ruby@v1
|
|
32
37
|
with:
|
|
33
38
|
ruby-version: ${{ matrix.ruby }}
|
|
34
39
|
bundler-cache: true
|
|
35
40
|
- name: Test
|
|
36
|
-
run: bundle exec rake
|
|
41
|
+
run: bundle exec rake test
|
data/.gitignore
CHANGED
data/.standard.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby_version: 2.7
|
data/Gemfile
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
source
|
|
1
|
+
source "https://rubygems.org"
|
|
2
2
|
|
|
3
|
-
gem
|
|
4
|
-
gem
|
|
3
|
+
gem "benchmark-ips"
|
|
4
|
+
gem "coveralls", require: false
|
|
5
|
+
gem "minitest", ">= 5"
|
|
6
|
+
gem "test-unit"
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
gem 'allocation_stats'
|
|
8
|
-
end
|
|
8
|
+
gem "allocation_stats" unless defined?(JRUBY_VERSION)
|
|
9
9
|
|
|
10
10
|
gemspec
|
data/README.md
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
M.RB
|
|
2
|
-
|
|
3
|
-
[](https://rubygems.org/gems/m) [](https://codeclimate.com/github/qrush/m) [](https://travis-ci.org/qrush/m) [](https://coveralls.io/r/qrush/m)
|
|
4
|
-
|
|
5
|
-
|
|
6
2
|
----
|
|
7
3
|
|
|
8
4
|
`m` stands for metal, a better test/unit and minitest test runner that can run tests by line number.
|
|
@@ -20,23 +16,10 @@ If you’re using Bundler, you’ll need to include it in your Gemfile. Toss it
|
|
|
20
16
|
|
|
21
17
|
``` ruby
|
|
22
18
|
group :test do
|
|
23
|
-
gem
|
|
19
|
+
gem "m"
|
|
24
20
|
end
|
|
25
21
|
```
|
|
26
22
|
|
|
27
|
-
Developing a RubyGem? Add m as a development dependency.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
``` ruby
|
|
31
|
-
Gem::Specification.new do |gem|
|
|
32
|
-
# ...
|
|
33
|
-
gem.add_development_dependency "m", "~> 1.5.0"
|
|
34
|
-
end
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
m works on Ruby 2.0+ only and support is only provided for [versions currently maintained by the community](https://www.ruby-lang.org/en/downloads/branches/).
|
|
38
|
-
|
|
39
|
-
|
|
40
23
|
USAGE
|
|
41
24
|
=====
|
|
42
25
|
|
|
@@ -129,38 +112,19 @@ SUPPORT
|
|
|
129
112
|
|
|
130
113
|
`m` works with a few Ruby test frameworks:
|
|
131
114
|
|
|
115
|
+
- Minitest::Test
|
|
116
|
+
- Minitest::Spec
|
|
132
117
|
- Test::Unit
|
|
133
118
|
- ActiveSupport::TestCase
|
|
134
|
-
- MiniTest::Unit::TestCase
|
|
135
|
-
- Minitest
|
|
136
|
-
|
|
137
119
|
|
|
138
120
|
CONTRIBUTING
|
|
139
121
|
============
|
|
140
122
|
|
|
141
|
-
## Setup
|
|
142
|
-
|
|
143
|
-
This project uses [Appraisal](https://github.com/thoughtbot/appraisal) to test against different versions of dependencies.
|
|
144
|
-
|
|
145
|
-
To install all scenarios (appraisals):
|
|
146
|
-
|
|
147
|
-
bundle install
|
|
148
|
-
bundle exec appraisal install
|
|
149
|
-
|
|
150
123
|
## Testing
|
|
151
124
|
|
|
152
125
|
You can run all the tests with:
|
|
153
126
|
|
|
154
|
-
bundle exec rake
|
|
155
|
-
|
|
156
|
-
You can also run tests selectively. For minitest 4 run:
|
|
157
|
-
|
|
158
|
-
appraisal minitest4 rake test
|
|
159
|
-
|
|
160
|
-
and the ones for minitest 5 with:
|
|
161
|
-
|
|
162
|
-
appraisal minitest5 rake test
|
|
163
|
-
|
|
127
|
+
bundle exec rake test
|
|
164
128
|
|
|
165
129
|
LICENSE
|
|
166
130
|
=======
|
data/Rakefile
CHANGED
|
@@ -1,96 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
2
|
+
require "rubygems"
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "coveralls"
|
|
5
|
+
require "bundler/gem_tasks"
|
|
6
|
+
require "rake/clean"
|
|
7
|
+
require "rake/testtask"
|
|
8
|
+
require "standard/rake"
|
|
9
|
+
require "rbconfig"
|
|
9
10
|
|
|
10
|
-
task :
|
|
11
|
+
task default: [:test, "standard:fix"]
|
|
11
12
|
|
|
12
13
|
Rake::TestTask.new do |t|
|
|
13
|
-
t.
|
|
14
|
-
t.libs << 'lib'
|
|
15
|
-
t.pattern = 'test/*_test.rb'
|
|
14
|
+
t.pattern = "test/*_test.rb"
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
desc
|
|
19
|
-
task :tests do
|
|
20
|
-
system "rake test" or exit!(1)
|
|
21
|
-
system "appraisal minitest4 rake test" or exit!(1)
|
|
22
|
-
system "appraisal minitest5 rake test TEST=test/minitest_5_test.rb" or exit!(1)
|
|
23
|
-
system "appraisal test_unit_gem rake test TEST=test/test_unit_test.rb" or exit!(1)
|
|
24
|
-
Coveralls.push!
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
desc 'Run simple benchmarks'
|
|
17
|
+
desc "Run simple benchmarks"
|
|
28
18
|
task :bench do
|
|
29
19
|
current_commit = `git rev-parse HEAD`
|
|
30
|
-
file_name = "benchmarks/#{Time.now.strftime
|
|
31
|
-
exec "echo -e 'Data for commit: #{current_commit}' > #{file_name} && ruby test/bench.rb >> #{file_name}"
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# ROCCO ===============================================================
|
|
35
|
-
|
|
36
|
-
begin
|
|
37
|
-
require 'rdiscount'
|
|
38
|
-
rescue LoadError => e
|
|
39
|
-
warn e.inspect
|
|
40
|
-
end
|
|
41
|
-
begin
|
|
42
|
-
require 'rocco/tasks'
|
|
43
|
-
Rocco::make 'docs/'
|
|
44
|
-
rescue LoadError => e
|
|
45
|
-
warn e.inspect
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
desc 'Build rocco docs'
|
|
49
|
-
task :docs => :rocco
|
|
50
|
-
directory 'docs/'
|
|
51
|
-
|
|
52
|
-
desc 'Build docs and open in browser for the reading'
|
|
53
|
-
task :read => :docs do
|
|
54
|
-
sh 'open docs/lib/m.html'
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Make index.html a copy of rocco.html
|
|
58
|
-
file 'docs/index.html' => 'docs/lib/m.html' do |f|
|
|
59
|
-
cp 'docs/lib/m.html', 'docs/index.html', :preserve => true
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
task :docs => 'docs/index.html'
|
|
63
|
-
CLEAN.include 'docs/index.html'
|
|
64
|
-
|
|
65
|
-
# Alias for docs task
|
|
66
|
-
task :doc => :docs
|
|
67
|
-
|
|
68
|
-
# GITHUB PAGES ===============================================================
|
|
69
|
-
|
|
70
|
-
desc "really kill docs folder"
|
|
71
|
-
task :clean_docs do
|
|
72
|
-
sh "rm -rf docs/"
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
desc 'Update gh-pages branch'
|
|
76
|
-
task :pages => [:clean_docs, 'docs/.git', :docs] do
|
|
77
|
-
rev = `git rev-parse --short HEAD`.strip
|
|
78
|
-
Dir.chdir 'docs' do
|
|
79
|
-
sh "mv lib/m m"
|
|
80
|
-
sh "mv lib/m.html m.html"
|
|
81
|
-
sh "git add -A"
|
|
82
|
-
sh "git commit -m 'rebuild pages from #{rev}'" do |ok,res|
|
|
83
|
-
if ok
|
|
84
|
-
verbose { puts "gh-pages updated" }
|
|
85
|
-
sh "git push -q o HEAD:gh-pages"
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# Update the pages/ directory clone
|
|
92
|
-
file 'docs/.git' => ['docs/'] do |f|
|
|
93
|
-
sh "cd docs && git init -q && git remote add o ../.git" if !File.exist?(f.name)
|
|
94
|
-
sh "cd docs && git fetch -q o && git reset -q --hard o/gh-pages && git rm -r . && git commit -m 'blank out' && touch ."
|
|
20
|
+
file_name = "benchmarks/#{Time.now.strftime "%Y%m%d"}-benchmark.log"
|
|
21
|
+
exec "echo -e 'Data for commit: #{current_commit}' > #{file_name} && #{RbConfig.ruby} test/bench.rb >> #{file_name}"
|
|
95
22
|
end
|
|
96
|
-
CLOBBER.include 'docs/.git'
|
data/bin/m
CHANGED
data/lib/m/executor.rb
CHANGED
|
@@ -1,46 +1,47 @@
|
|
|
1
|
-
require_relative
|
|
2
|
-
require_relative
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
1
|
+
require_relative "runners/base"
|
|
2
|
+
require_relative "runners/minitest_6"
|
|
3
|
+
require_relative "runners/minitest_5"
|
|
4
|
+
require_relative "runners/minitest_4"
|
|
5
|
+
require_relative "runners/test_unit"
|
|
6
|
+
require_relative "runners/unsupported_framework"
|
|
6
7
|
|
|
7
8
|
module M
|
|
8
9
|
class Executor
|
|
9
|
-
def initialize
|
|
10
|
+
def initialize testable
|
|
10
11
|
@testable = testable
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def execute
|
|
14
15
|
# Locate tests to run that may be inside of this line. There could be more than one!
|
|
15
|
-
tests_to_run = tests.within
|
|
16
|
+
tests_to_run = tests.within testable.lines
|
|
16
17
|
|
|
17
18
|
# If we found any tests,
|
|
18
|
-
if tests_to_run.size
|
|
19
|
+
if tests_to_run.size.positive?
|
|
19
20
|
# assemble the regexp to run these tests,
|
|
20
|
-
test_names = tests_to_run.map { |test| Regexp.escape(test.name) }.join(
|
|
21
|
+
test_names = tests_to_run.map { |test| Regexp.escape(test.name) }.join("|")
|
|
21
22
|
|
|
22
23
|
# set up the args needed for the runner
|
|
23
24
|
test_arguments = ["-n", "/^(#{test_names})$/"]
|
|
24
25
|
|
|
25
26
|
# directly run the tests from here and exit with the status of the tests passing or failing
|
|
26
|
-
runner.run
|
|
27
|
-
elsif tests.size
|
|
27
|
+
runner.run test_arguments + testable.passthrough_options
|
|
28
|
+
elsif tests.size.positive?
|
|
28
29
|
# Otherwise we found no tests on this line, so you need to pick one.
|
|
29
|
-
message = "No tests found on line #{testable.lines.join
|
|
30
|
+
message = "No tests found on line #{testable.lines.join ", "}. Valid tests to run:\n\n"
|
|
30
31
|
|
|
31
32
|
# For every test ordered by line number,
|
|
32
33
|
# spit out the test name and line number where it starts,
|
|
33
34
|
tests.by_line_number do |test|
|
|
34
|
-
message << "#{
|
|
35
|
+
message << "#{format "%0#{tests.column_size}s", test.name}: m #{testable.file}:#{test.start_line}\n"
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
# Spit out helpful message and bail
|
|
38
|
-
|
|
39
|
+
warn message
|
|
39
40
|
false
|
|
40
41
|
else
|
|
41
42
|
# There were no tests at all
|
|
42
43
|
message = "There were no tests found.\n\n"
|
|
43
|
-
|
|
44
|
+
warn message
|
|
44
45
|
false
|
|
45
46
|
end
|
|
46
47
|
end
|
|
@@ -58,27 +59,27 @@ module M
|
|
|
58
59
|
# With each suite and array of tests,
|
|
59
60
|
# and with each test method present in this test file,
|
|
60
61
|
# shove a new test method into this collection.
|
|
61
|
-
suites.
|
|
62
|
+
suites.each_with_object TestCollection.new do |(suite_class, test_methods), collection|
|
|
62
63
|
test_methods.each do |test_method|
|
|
63
64
|
collection << TestMethod.create(suite_class, test_method)
|
|
64
65
|
end
|
|
65
|
-
collection
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
|
|
71
70
|
# Finds all test suites in this test file, with test methods included.
|
|
72
71
|
def suites
|
|
73
72
|
# Since we're not using `ruby -Itest -Ilib` to run the tests, we need to add this directory to the `LOAD_PATH`
|
|
74
|
-
|
|
73
|
+
$LOAD_PATH.unshift "./test", "./spec", "./lib"
|
|
75
74
|
|
|
76
75
|
begin
|
|
77
76
|
# Fire up this Ruby file. Let's hope it actually has tests.
|
|
78
|
-
|
|
77
|
+
file = testable.file
|
|
78
|
+
file = "./#{testable.file}" unless file.start_with? "/"
|
|
79
|
+
require file
|
|
79
80
|
rescue LoadError => e
|
|
80
81
|
# Fail with a happier error message instead of spitting out a backtrace from this gem
|
|
81
|
-
|
|
82
|
+
warn "Failed loading test file:\n#{e.message}"
|
|
82
83
|
return []
|
|
83
84
|
end
|
|
84
85
|
|
|
@@ -87,9 +88,7 @@ module M
|
|
|
87
88
|
# Use some janky internal APIs to group test methods by test suite.
|
|
88
89
|
suites.each_with_object({}) do |suite_class, test_suites|
|
|
89
90
|
# End up with a hash of suite class name to an array of test methods, so we can later find them and ignore empty test suites
|
|
90
|
-
if runner.test_methods(suite_class).any?
|
|
91
|
-
test_suites[suite_class] = runner.test_methods(suite_class)
|
|
92
|
-
end
|
|
91
|
+
test_suites[suite_class] = runner.test_methods(suite_class) if runner.test_methods(suite_class).any?
|
|
93
92
|
end
|
|
94
93
|
end
|
|
95
94
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require "ripper"
|
|
2
|
+
|
|
3
|
+
module M
|
|
4
|
+
# Stripped down parser that can determine the ending line for a method.
|
|
5
|
+
class FinishLine < Ripper
|
|
6
|
+
# Brazenly stolen from Rails::TestUnit::TestParser by Carl Brasic @brasic
|
|
7
|
+
|
|
8
|
+
# Helper to translate a method object into the path and line range where
|
|
9
|
+
# the method was defined.
|
|
10
|
+
def self.ending_line_for(method_obj)
|
|
11
|
+
path, begin_line = method_obj.source_location
|
|
12
|
+
new(File.read(path), path).parse[begin_line]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize(*)
|
|
16
|
+
# A hash mapping the 1-indexed line numbers that tests start on to where they end.
|
|
17
|
+
@begins_to_ends = {}
|
|
18
|
+
super
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def parse
|
|
22
|
+
super
|
|
23
|
+
@begins_to_ends
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# method test e.g. `def test_some_description`
|
|
27
|
+
# This event's first argument gets the `ident` node containing the method
|
|
28
|
+
# name, which we have overridden to return the line number of the ident
|
|
29
|
+
# instead.
|
|
30
|
+
def on_def(begin_line, *)
|
|
31
|
+
@begins_to_ends[begin_line] = lineno
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Everything past this point is to support declarative tests, which
|
|
35
|
+
# require more work to get right because of the many different ways
|
|
36
|
+
# methods can be invoked in ruby, all of which are parsed differently.
|
|
37
|
+
#
|
|
38
|
+
# The approach is just to store the current line number when the
|
|
39
|
+
# "test" method is called and pass it up the tree so it's available at
|
|
40
|
+
# the point when we also know the line where the associated block ends.
|
|
41
|
+
|
|
42
|
+
def on_method_add_block(begin_line, end_line)
|
|
43
|
+
if begin_line && end_line
|
|
44
|
+
@begins_to_ends[begin_line] = end_line
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def on_command_call(*, begin_lineno, _args)
|
|
49
|
+
begin_lineno
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def first_arg(arg, *)
|
|
53
|
+
arg
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def just_lineno(*)
|
|
57
|
+
lineno
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
alias_method :on_method_add_arg, :first_arg
|
|
61
|
+
alias_method :on_command, :first_arg
|
|
62
|
+
alias_method :on_stmts_add, :first_arg
|
|
63
|
+
alias_method :on_arg_paren, :first_arg
|
|
64
|
+
alias_method :on_bodystmt, :first_arg
|
|
65
|
+
|
|
66
|
+
alias_method :on_ident, :just_lineno
|
|
67
|
+
alias_method :on_do_block, :just_lineno
|
|
68
|
+
alias_method :on_stmts_new, :just_lineno
|
|
69
|
+
alias_method :on_brace_block, :just_lineno
|
|
70
|
+
|
|
71
|
+
def on_args_new
|
|
72
|
+
[]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def on_args_add(parts, part)
|
|
76
|
+
parts << part
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def on_args_add_block(args, *rest)
|
|
80
|
+
args.first
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
data/lib/m/frameworks.rb
CHANGED
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
module M
|
|
2
2
|
class Frameworks
|
|
3
|
+
def self.minitest_version_major
|
|
4
|
+
if defined?(Minitest::Unit::VERSION)
|
|
5
|
+
Minitest::Unit::VERSION.slice(/\d+/)
|
|
6
|
+
elsif defined?(Minitest::VERSION)
|
|
7
|
+
Minitest::VERSION.slice(/\d+/)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.minitest6?
|
|
12
|
+
minitest_version_major == "6"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.minitest5?
|
|
16
|
+
minitest_version_major == "5"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.test_unit?
|
|
20
|
+
defined?(Test::Unit)
|
|
21
|
+
end
|
|
22
|
+
|
|
3
23
|
def self.framework_runner
|
|
4
24
|
new.framework_runner
|
|
5
25
|
end
|
|
6
26
|
|
|
7
27
|
def framework_runner
|
|
8
|
-
if
|
|
28
|
+
if minitest6?
|
|
29
|
+
Runners::Minitest6.new
|
|
30
|
+
elsif minitest5?
|
|
9
31
|
Runners::Minitest5.new
|
|
10
|
-
elsif minitest4?
|
|
11
|
-
Runners::Minitest4.new
|
|
12
32
|
elsif test_unit?
|
|
13
33
|
Runners::TestUnit.new
|
|
14
34
|
else
|
|
@@ -18,32 +38,16 @@ module M
|
|
|
18
38
|
|
|
19
39
|
private
|
|
20
40
|
|
|
21
|
-
def
|
|
22
|
-
self.class.
|
|
41
|
+
def minitest6?
|
|
42
|
+
self.class.minitest6?
|
|
23
43
|
end
|
|
24
44
|
|
|
25
|
-
def
|
|
26
|
-
self.class.
|
|
45
|
+
def minitest5?
|
|
46
|
+
self.class.minitest5?
|
|
27
47
|
end
|
|
28
48
|
|
|
29
49
|
def test_unit?
|
|
30
50
|
self.class.test_unit?
|
|
31
51
|
end
|
|
32
|
-
|
|
33
|
-
def self.minitest_version_major
|
|
34
|
-
defined?(Minitest) ? Minitest::Unit::VERSION.slice(/\d+/) : nil
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def self.minitest5?
|
|
38
|
-
minitest_version_major == "5"
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def self.minitest4?
|
|
42
|
-
minitest_version_major == "4"
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def self.test_unit?
|
|
46
|
-
defined?(Test::Unit)
|
|
47
|
-
end
|
|
48
52
|
end
|
|
49
53
|
end
|
data/lib/m/parser.rb
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
require_relative
|
|
1
|
+
require_relative "testable"
|
|
2
|
+
require "rbconfig"
|
|
2
3
|
|
|
3
4
|
module M
|
|
4
5
|
class Parser
|
|
5
|
-
def initialize
|
|
6
|
+
def initialize argv
|
|
6
7
|
@argv = argv
|
|
7
8
|
@testable = Testable.new
|
|
8
9
|
end
|
|
@@ -11,16 +12,16 @@ module M
|
|
|
11
12
|
# With no arguments,
|
|
12
13
|
if argv.empty?
|
|
13
14
|
# Just shell out to `rake test`.
|
|
14
|
-
exec "rake test"
|
|
15
|
+
exec "#{RbConfig.ruby} -S rake test"
|
|
15
16
|
else
|
|
16
17
|
parse_options! argv
|
|
17
18
|
|
|
18
|
-
if argv.first.start_with?
|
|
19
|
-
exec "rake test #{argv.join}"
|
|
19
|
+
if argv.first.start_with? "--"
|
|
20
|
+
exec "#{RbConfig.ruby} -S rake test #{argv.join}"
|
|
20
21
|
exit 0
|
|
21
22
|
else
|
|
22
23
|
# Parse out ARGV, it should be coming in in a format like `test/test_file.rb:9:19`
|
|
23
|
-
parsed = argv.shift.split
|
|
24
|
+
parsed = argv.shift.split ":"
|
|
24
25
|
testable.file = parsed.shift
|
|
25
26
|
testable.lines = parsed if testable.lines.none?
|
|
26
27
|
# Anything else on ARGV will be passed along to the runner
|
|
@@ -28,26 +29,25 @@ module M
|
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
# If this file is a directory, not a file, run the tests inside of this directory
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
# Invoke the rake task and exit, hopefully it'll work!
|
|
41
|
-
begin
|
|
42
|
-
Rake::Task['m_custom'].invoke
|
|
43
|
-
rescue RuntimeError
|
|
44
|
-
exit(1)
|
|
45
|
-
ensure
|
|
46
|
-
exit($?.exitstatus)
|
|
47
|
-
end
|
|
48
|
-
else
|
|
49
|
-
return testable
|
|
32
|
+
return testable unless Dir.exist? testable.file
|
|
33
|
+
|
|
34
|
+
# Make a new rake test task with a hopefully unique name, and run every test looking file in it
|
|
35
|
+
require "rake/testtask"
|
|
36
|
+
Rake::TestTask.new :m_custom do |t|
|
|
37
|
+
t.libs << "test"
|
|
38
|
+
t.libs << "spec"
|
|
39
|
+
t.test_files = FileList[wildcard("test"), wildcard("spec")]
|
|
40
|
+
t.warning = false
|
|
50
41
|
end
|
|
42
|
+
# Invoke the rake task and exit, hopefully it'll work!
|
|
43
|
+
begin
|
|
44
|
+
Rake::Task["m_custom"].invoke
|
|
45
|
+
rescue RuntimeError
|
|
46
|
+
exit 1
|
|
47
|
+
ensure
|
|
48
|
+
exit $?.exitstatus
|
|
49
|
+
end
|
|
50
|
+
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -55,29 +55,29 @@ module M
|
|
|
55
55
|
|
|
56
56
|
attr_reader :argv, :testable
|
|
57
57
|
|
|
58
|
-
def parse_options!
|
|
59
|
-
require
|
|
58
|
+
def parse_options! argv
|
|
59
|
+
require "optparse"
|
|
60
60
|
|
|
61
61
|
OptionParser.new do |opts|
|
|
62
|
-
opts.banner
|
|
62
|
+
opts.banner = "Options:"
|
|
63
63
|
opts.version = M::VERSION
|
|
64
64
|
|
|
65
|
-
opts.on
|
|
65
|
+
opts.on "-h", "--help", "Display this help." do
|
|
66
66
|
puts "Usage: m [OPTIONS] [FILES]\n\n", opts
|
|
67
67
|
exit
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
opts.on
|
|
70
|
+
opts.on "--version", "Display the version." do
|
|
71
71
|
puts "m #{M::VERSION}"
|
|
72
72
|
exit
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
opts.on
|
|
75
|
+
opts.on "-l", "--line LINE", Integer, "Line number for file." do |line|
|
|
76
76
|
p "parsing line #{line}"
|
|
77
77
|
testable.lines = [line]
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
opts.on
|
|
80
|
+
opts.on "-r", "--recursive DIR", "Search provided directory recursively." do |directory|
|
|
81
81
|
testable.recursive = true
|
|
82
82
|
argv << directory
|
|
83
83
|
end
|
|
@@ -86,7 +86,7 @@ module M
|
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
def wildcard
|
|
89
|
+
def wildcard type
|
|
90
90
|
if testable.recursive
|
|
91
91
|
"#{testable.file}/**/*#{type}*.rb"
|
|
92
92
|
else
|