m 1.4.0 → 1.6.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.
@@ -2,7 +2,9 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "coveralls", :require => false, :group => :coverage
5
+ gem "coveralls", require: false
6
+ gem "benchmark-ips"
7
+ gem "allocation_stats"
6
8
  gem "test-unit"
7
9
 
8
- gemspec :path => "../"
10
+ gemspec path: "../"
@@ -1,80 +1,71 @@
1
1
  PATH
2
- remote: ../
2
+ remote: ..
3
3
  specs:
4
- m (1.3.4)
4
+ m (1.5.1)
5
5
  method_source (>= 0.6.7)
6
6
  rake (>= 0.9.2.2)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (4.2.3)
12
- i18n (~> 0.7)
13
- json (~> 1.7, >= 1.7.7)
14
- minitest (~> 5.1)
15
- thread_safe (~> 0.3, >= 0.3.4)
16
- tzinfo (~> 1.1)
17
- appraisal (2.0.2)
11
+ activesupport (6.1.4.1)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 1.6, < 2)
14
+ minitest (>= 5.1)
15
+ tzinfo (~> 2.0)
16
+ zeitwerk (~> 2.3)
17
+ allocation_stats (0.1.5)
18
+ appraisal (2.4.1)
18
19
  bundler
19
20
  rake
20
21
  thor (>= 0.14.0)
21
- coveralls (0.8.2)
22
- json (~> 1.8)
23
- rest-client (>= 1.6.8, < 2)
24
- simplecov (~> 0.10.0)
22
+ benchmark-ips (2.9.1)
23
+ concurrent-ruby (1.1.9)
24
+ coveralls (0.8.23)
25
+ json (>= 1.8, < 3)
26
+ simplecov (~> 0.16.1)
25
27
  term-ansicolor (~> 1.3)
26
- thor (~> 0.19.1)
27
- docile (1.1.5)
28
- domain_name (0.5.24)
29
- unf (>= 0.0.5, < 1.0.0)
30
- http-cookie (1.0.2)
31
- domain_name (~> 0.5)
32
- i18n (0.7.0)
33
- json (1.8.3)
34
- json (1.8.3-java)
35
- method_source (0.8.2)
36
- mime-types (2.6.1)
37
- minitest (5.7.0)
38
- mustache (1.0.2)
39
- netrc (0.10.3)
40
- power_assert (0.2.4)
41
- rake (10.4.2)
42
- rdiscount (2.1.8)
43
- redcarpet (3.3.2)
44
- rest-client (1.8.0)
45
- http-cookie (>= 1.0.2, < 2.0)
46
- mime-types (>= 1.16, < 3.0)
47
- netrc (~> 0.7)
28
+ thor (>= 0.19.4, < 2.0)
29
+ tins (~> 1.6)
30
+ docile (1.4.0)
31
+ i18n (1.8.10)
32
+ concurrent-ruby (~> 1.0)
33
+ json (2.5.1)
34
+ method_source (1.0.0)
35
+ minitest (5.14.4)
36
+ mustache (1.1.1)
37
+ power_assert (2.0.1)
38
+ rake (13.0.6)
39
+ rdiscount (2.2.0.2)
40
+ redcarpet (3.5.1)
48
41
  rocco (0.8.2)
49
42
  mustache
50
43
  redcarpet
51
- simplecov (0.10.0)
52
- docile (~> 1.1.0)
53
- json (~> 1.8)
44
+ simplecov (0.16.1)
45
+ docile (~> 1.1)
46
+ json (>= 1.8, < 3)
54
47
  simplecov-html (~> 0.10.0)
55
- simplecov-html (0.10.0)
56
- term-ansicolor (1.3.2)
48
+ simplecov-html (0.10.2)
49
+ sync (0.5.0)
50
+ term-ansicolor (1.7.1)
57
51
  tins (~> 1.0)
58
- test-unit (3.1.2)
52
+ test-unit (3.4.4)
59
53
  power_assert
60
- thor (0.19.1)
61
- thread_safe (0.3.5)
62
- thread_safe (0.3.5-java)
63
- tins (1.5.4)
64
- tzinfo (1.2.2)
65
- thread_safe (~> 0.1)
66
- unf (0.1.4)
67
- unf_ext
68
- unf (0.1.4-java)
69
- unf_ext (0.0.7.1)
54
+ thor (1.1.0)
55
+ tins (1.29.1)
56
+ sync
57
+ tzinfo (2.0.4)
58
+ concurrent-ruby (~> 1.0)
59
+ zeitwerk (2.4.2)
70
60
 
71
61
  PLATFORMS
72
- java
73
62
  ruby
74
63
 
75
64
  DEPENDENCIES
76
65
  activesupport
66
+ allocation_stats
77
67
  appraisal
68
+ benchmark-ips
78
69
  coveralls
79
70
  m!
80
71
  rdiscount
@@ -82,4 +73,4 @@ DEPENDENCIES
82
73
  test-unit
83
74
 
84
75
  BUNDLED WITH
85
- 1.10.6
76
+ 2.2.26
@@ -0,0 +1,7 @@
1
+ require_relative "../../test/test_helper.rb"
2
+
3
+ class ErrorTest < MTest
4
+ def test_purposeful_error
5
+ raise RuntimeError
6
+ end
7
+ end
data/lib/m/executor.rb CHANGED
@@ -12,7 +12,7 @@ module M
12
12
 
13
13
  def execute
14
14
  # Locate tests to run that may be inside of this line. There could be more than one!
15
- tests_to_run = tests.within(testable.line)
15
+ tests_to_run = tests.within(testable.lines)
16
16
 
17
17
  # If we found any tests,
18
18
  if tests_to_run.size > 0
@@ -23,10 +23,10 @@ module M
23
23
  test_arguments = ["-n", "/^(#{test_names})$/"]
24
24
 
25
25
  # directly run the tests from here and exit with the status of the tests passing or failing
26
- runner.run(test_arguments)
26
+ runner.run(test_arguments + testable.passthrough_options)
27
27
  elsif tests.size > 0
28
28
  # Otherwise we found no tests on this line, so you need to pick one.
29
- message = "No tests found on line #{testable.line}. Valid tests to run:\n\n"
29
+ message = "No tests found on line #{testable.lines.join(', ')}. Valid tests to run:\n\n"
30
30
 
31
31
  # For every test ordered by line number,
32
32
  # spit out the test name and line number where it starts,
data/lib/m/frameworks.rb CHANGED
@@ -30,12 +30,16 @@ module M
30
30
  self.class.test_unit?
31
31
  end
32
32
 
33
+ def self.minitest_version_major
34
+ defined?(Minitest) ? Minitest::Unit::VERSION.slice(/\d+/) : nil
35
+ end
36
+
33
37
  def self.minitest5?
34
- defined?(Minitest) && Minitest::Unit::VERSION.start_with?("5")
38
+ minitest_version_major == "5"
35
39
  end
36
40
 
37
41
  def self.minitest4?
38
- defined?(MiniTest)
42
+ minitest_version_major == "4"
39
43
  end
40
44
 
41
45
  def self.test_unit?
data/lib/m/parser.rb CHANGED
@@ -15,8 +15,17 @@ module M
15
15
  else
16
16
  parse_options! argv
17
17
 
18
- # Parse out ARGV, it should be coming in in a format like `test/test_file.rb:9`
19
- testable.file, testable.line = argv.first.split(':')
18
+ if argv.first.start_with?("--")
19
+ exec "rake test #{argv.join}"
20
+ exit 0
21
+ else
22
+ # Parse out ARGV, it should be coming in in a format like `test/test_file.rb:9:19`
23
+ parsed = argv.shift.split(':')
24
+ testable.file = parsed.shift
25
+ testable.lines = parsed if testable.lines.none?
26
+ # Anything else on ARGV will be passed along to the runner
27
+ testable.passthrough_options = argv
28
+ end
20
29
 
21
30
  # If this file is a directory, not a file, run the tests inside of this directory
22
31
  if Dir.exist?(testable.file)
@@ -25,15 +34,16 @@ module M
25
34
  Rake::TestTask.new(:m_custom) do |t|
26
35
  t.libs << 'test'
27
36
  t.libs << 'spec'
28
- t.test_files = FileList["#{testable.file}/*test*.rb", "#{testable.file}/*spec*.rb"]
37
+ t.test_files = FileList[wildcard("test"), wildcard("spec")]
38
+ t.warning = false
29
39
  end
30
40
  # Invoke the rake task and exit, hopefully it'll work!
31
41
  begin
32
42
  Rake::Task['m_custom'].invoke
33
43
  rescue RuntimeError
34
- exit
44
+ exit(1)
35
45
  ensure
36
- exit
46
+ exit($?.exitstatus)
37
47
  end
38
48
  else
39
49
  return testable
@@ -64,11 +74,24 @@ module M
64
74
 
65
75
  opts.on '-l', '--line LINE', Integer, 'Line number for file.' do |line|
66
76
  p "parsing line #{line}"
67
- testable.line = line
77
+ testable.lines = [line]
78
+ end
79
+
80
+ opts.on '-r', '--recursive DIR', 'Search provided directory recursively.' do |directory|
81
+ testable.recursive = true
82
+ argv << directory
68
83
  end
69
84
 
70
85
  opts.parse! argv
71
86
  end
72
87
  end
88
+
89
+ def wildcard(type)
90
+ if testable.recursive
91
+ "#{testable.file}/**/*#{type}*.rb"
92
+ else
93
+ "#{testable.file}/*#{type}*.rb"
94
+ end
95
+ end
73
96
  end
74
97
  end
@@ -17,13 +17,12 @@ module M
17
17
 
18
18
  # Slice out tests that may be within the given line.
19
19
  # Returns a new TestCollection with the results.
20
- def within(line)
20
+ def within(lines)
21
21
  # Into a new collection, filter only the tests that...
22
- self.class.new(select do |test|
23
- # are within the given boundary for this method
24
- # or include everything if the line given is zero (no line)
25
- line.zero? || (test.start_line..test.end_line).include?(line)
26
- end)
22
+ collection = select do |test|
23
+ lines.none? || lines.any? { |line| (test.start_line..test.end_line).include?(line) }
24
+ end
25
+ self.class.new(collection)
27
26
  end
28
27
 
29
28
  # Used to line up method names in `#sprintf` when `m` aborts
data/lib/m/test_method.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require "method_source"
2
+
1
3
  module M
2
4
  ### Simple data structure for what a test method contains.
3
5
  #
@@ -22,7 +24,7 @@ module M
22
24
  #
23
25
  # The end line should be the number of line breaks in the method source,
24
26
  # added to the starting line and subtracted by one.
25
- require "method_source"
27
+
26
28
  end_line = method.source.split("\n").size + start_line - 1
27
29
 
28
30
  # Shove the given attributes into a new databag
data/lib/m/testable.rb CHANGED
@@ -1,15 +1,17 @@
1
1
  module M
2
2
  class Testable
3
- attr_accessor :file
4
- attr_reader :line
3
+ attr_accessor :file, :recursive, :passthrough_options
4
+ attr_reader :lines
5
5
 
6
- def initialize(file = "", line = nil)
6
+ def initialize(file = "", lines = [], recursive = false)
7
7
  @file = file
8
- @line = line
8
+ @recursive = recursive
9
+ @passthrough_options = []
10
+ self.lines = lines
9
11
  end
10
12
 
11
- def line=(line)
12
- @line ||= line.to_i
13
+ def lines=(lines)
14
+ @lines = lines.map(&:to_i)
13
15
  end
14
16
  end
15
17
  end
data/lib/m/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module M
2
+ VERSION = "1.6.0"
3
+ end
data/lib/m.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  ### M, your metal test runner
2
2
  # Maybe this gem should have a longer name? Metal?
3
- require_relative 'version'
3
+ require_relative 'm/version'
4
4
  require_relative 'm/frameworks'
5
5
  require_relative 'm/runner'
6
6
 
@@ -2,28 +2,28 @@ require 'test_helper'
2
2
 
3
3
  class ActiveSupportTest < MTest
4
4
  def test_run_simple_test_by_line_number
5
- output = m('examples/active_support_example_test.rb:11')
6
- assert_output(/1 tests, 1 assertions/, output)
5
+ output = m('examples/active_support_example_test.rb:12')
6
+ assert_output(/1 (runs|tests), 1 assertions/, output)
7
7
  end
8
8
 
9
9
  def test_runs_entire_test_without_line_number
10
10
  output = m('examples/active_support_example_test.rb')
11
- assert_output(/4 tests/, output)
11
+ assert_output(/4 (runs|tests)/, output)
12
12
  end
13
13
 
14
14
  def test_run_inside_of_test
15
- output = m('examples/active_support_example_test.rb:12')
16
- assert_output(/1 tests, 1 assertions/, output)
15
+ output = m('examples/active_support_example_test.rb:13')
16
+ assert_output(/1 (runs|tests), 1 assertions/, output)
17
17
  end
18
18
 
19
19
  def test_run_on_end_of_test
20
- output = m('examples/active_support_example_test.rb:13')
21
- assert_output(/1 tests, 1 assertions/, output)
20
+ output = m('examples/active_support_example_test.rb:14')
21
+ assert_output(/1 (runs|tests), 1 assertions/, output)
22
22
  end
23
23
 
24
24
  def test_run_inside_big_test
25
- output = m('examples/active_support_example_test.rb:17')
26
- assert_output(/1 tests, 3 assertions/, output)
25
+ output = m('examples/active_support_example_test.rb:18')
26
+ assert_output(/1 (runs|tests), 3 assertions/, output)
27
27
  end
28
28
 
29
29
  def test_run_on_blank_line_orders_tests_by_line_number
@@ -33,21 +33,21 @@ class ActiveSupportTest < MTest
33
33
  expected = <<-EOF
34
34
  No tests found on line 2. Valid tests to run:
35
35
 
36
- test_normal: m examples/active_support_example_test.rb:7
37
- test_carrot: m examples/active_support_example_test.rb:11
38
- test_daikon: m examples/active_support_example_test.rb:15
39
- test_eggplant_fig: m examples/active_support_example_test.rb:21
36
+ test_normal: m examples/active_support_example_test.rb:8
37
+ test_carrot: m examples/active_support_example_test.rb:12
38
+ test_daikon: m examples/active_support_example_test.rb:16
39
+ test_eggplant_fig: m examples/active_support_example_test.rb:22
40
40
  EOF
41
41
  assert_equal expected.strip, output
42
42
  end
43
43
 
44
44
  def test_run_on_test_with_spaces
45
- output = m('examples/active_support_example_test.rb:21')
46
- assert_output(/1 tests, 1 assertions/, output)
45
+ output = m('examples/active_support_example_test.rb:22')
46
+ assert_output(/1 (runs|tests), 1 assertions/, output)
47
47
  end
48
48
 
49
49
  def test_run_on_test_with_unescaped_regular_express_characters
50
- output = m('examples/active_support_unescaped_example_test.rb:7')
51
- assert_output(/1 tests, 1 assertions/, output)
50
+ output = m('examples/active_support_unescaped_example_test.rb:8')
51
+ assert_output(/1 (runs|tests), 1 assertions/, output)
52
52
  end
53
53
  end
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  class EverythingTest < MTest
4
4
  def test_runs_entire_test_suite_with_no_arguments
5
5
  output = m('')
6
- assert_output(/12 tests/, output)
6
+ assert_output(/12 (runs|tests)/, output)
7
7
  end
8
8
 
9
9
  def test_missing_file_gives_a_decent_error_message
@@ -19,15 +19,15 @@ class EverythingTest < MTest
19
19
 
20
20
  def test_running_tests_within_a_subdirectory
21
21
  output = m('examples/subdir')
22
- assert_output(/3 tests/, output)
22
+ assert_output(/3 (runs|tests)/, output)
23
23
 
24
24
  output = m('examples')
25
- assert_output(/12 tests/, output)
25
+ assert_output(/12 (runs|tests)/, output)
26
26
  end
27
27
 
28
28
  def test_running_tests_with_failures_within_a_subdirectory
29
29
  output = m('examples/subdir_with_failures')
30
- assert_output(/1 tests, 1 assertions, 1 failures/, output)
30
+ assert_output_for_failed_execution(/1 (runs|tests), 1 assertions, 1 failures/, output)
31
31
  end
32
32
 
33
33
  def test_blank_file_is_quieter
@@ -1,3 +1,4 @@
1
+ require 'active_support'
1
2
  require 'active_support/test_case'
2
3
 
3
4
  class ActiveSupportExampleTest < ActiveSupport::TestCase
@@ -1,3 +1,4 @@
1
+ require 'active_support'
1
2
  require 'active_support/test_case'
2
3
 
3
4
  class ActiveSupportExampleTest < ActiveSupport::TestCase
@@ -0,0 +1,36 @@
1
+ require 'minitest/unit'
2
+
3
+ class Meme
4
+ def i_can_has_cheezburger?
5
+ "OHAI!"
6
+ end
7
+
8
+ def will_it_blend?
9
+ "YES!"
10
+ end
11
+ end
12
+
13
+ Test = M::Frameworks.minitest4? ? MiniTest::Unit::TestCase : Minitest::Test
14
+
15
+ class TestMeme < Test
16
+ def setup
17
+ @meme = Meme.new
18
+ end
19
+
20
+ def test_that_kitty_can_eat
21
+ assert_equal "OHAI!", @meme.i_can_has_cheezburger?
22
+ end
23
+
24
+ def test_that_it_will_not_blend
25
+ refute_match(/^maybe/i, @meme.will_it_blend?)
26
+ refute_match(/^no/i, @meme.will_it_blend?)
27
+ refute_match(/^lolz/i, @meme.will_it_blend?)
28
+ end
29
+
30
+ def test_that_kitty_can_eat_two_time
31
+ assert_equal "OHAI!", @meme.i_can_has_cheezburger?
32
+ assert_equal "OHAI!", @meme.i_can_has_cheezburger?
33
+ end
34
+
35
+ Minitest.after_run { p "ran after run block" } if Minitest.respond_to?(:after_run)
36
+ end