Narnach-minitest 0.3.1 → 0.3.2
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.
- data/README.rdoc +29 -1
- data/lib/minitest.rb +46 -66
- data/lib/mixins/rcov_mixin.rb +26 -0
- data/lib/mixins/rspec_mixin.rb +28 -0
- data/minitest.gemspec +2 -2
- data/spec/minitest_spec.rb +23 -0
- metadata +3 -1
data/README.rdoc
CHANGED
@@ -4,6 +4,20 @@ It can be used with 'plain' Ruby projects and Ruby on Rails.
|
|
4
4
|
|
5
5
|
== Recent changes
|
6
6
|
|
7
|
+
=== Version 0.3.2
|
8
|
+
* Bugfixes:
|
9
|
+
* Minitest will not run non-existent specs
|
10
|
+
* Rcov will not run non-existent specs
|
11
|
+
* Documentation changes:
|
12
|
+
* Readme examples match current functionality
|
13
|
+
* Readme has a todo section
|
14
|
+
* Minitest documentation updated
|
15
|
+
* DirMonitor documentation updated
|
16
|
+
* Code cleanups:
|
17
|
+
* Gemspec is a lot more readable
|
18
|
+
* Numerous refactorings in Minitest and DirMonitor
|
19
|
+
* Set extension has its own file
|
20
|
+
|
7
21
|
=== Version 0.3.1
|
8
22
|
Minitest gained support to test Test::Unit tests and RSpec specs at the same time.
|
9
23
|
|
@@ -40,7 +54,21 @@ You can also combine options:
|
|
40
54
|
== Todo / ideas / plans
|
41
55
|
* Figure out how to get RCov to run specs and tests at the same time and implement it.
|
42
56
|
* Add 'recent' option (was removed in 0.3.0).
|
43
|
-
*
|
57
|
+
* Cleanup Minitest class / rewrite in a clean and testable way.
|
58
|
+
|
59
|
+
== Minitest cleanup
|
60
|
+
|
61
|
+
The Minitest class started as a simple script and thus was not designed to focus on one responsibility.
|
62
|
+
Right now it tries to do too much:
|
63
|
+
* Infinite loop
|
64
|
+
* Execute RSpec for changed files
|
65
|
+
* Execute test/unit for changed files
|
66
|
+
* Execute RCov when terminating the loop
|
67
|
+
Instead of delegating these tasks, it actually performs them.
|
68
|
+
|
69
|
+
Adding three classes is a good first step to reduce complexity.
|
70
|
+
Each 'executable' gets its own class: RSpec, RCov and test/unit.
|
71
|
+
When that is done, the code in Minitest should be reduced to looping and delegating.
|
44
72
|
|
45
73
|
== About
|
46
74
|
Author:: Wes 'Narnach' Oldenbeuving (narnach@gmail.com)
|
data/lib/minitest.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'set_ext'
|
2
2
|
require 'dir_monitor'
|
3
|
+
require 'mixins/rcov_mixin'
|
4
|
+
require 'mixins/rspec_mixin'
|
3
5
|
|
4
6
|
# = Minitest
|
5
7
|
# The default usage of Minitest is this:
|
@@ -10,104 +12,82 @@ require 'dir_monitor'
|
|
10
12
|
# - Frequently check for new or changed files; run rspec or test/unit on their associated specs or tests
|
11
13
|
# - Run rcov (code coverage tester) on all specs when exiting (Press ctrl-C on send SIGINT to the process)
|
12
14
|
class Minitest
|
15
|
+
include RcovMixin
|
16
|
+
include RspecMixin
|
17
|
+
|
13
18
|
attr_accessor :source_dirs
|
14
|
-
|
15
|
-
|
16
|
-
attr_reader :need_testing, :known_specs
|
19
|
+
attr_reader :specs_to_run, :known_specs
|
20
|
+
attr_reader :tests_to_run
|
17
21
|
|
18
|
-
DEFAULT_RCOV_IGNORES = %w[spec/ db/ plugins/ vendor/ config/]
|
19
22
|
DEFAULT_SOURCE_DIRS = %w[lib app spec test]
|
20
23
|
|
21
24
|
def initialize
|
22
25
|
@active = false
|
23
26
|
@known_specs = Set.new
|
24
|
-
@
|
27
|
+
@specs_to_run = Set.new
|
28
|
+
@tests_to_run = Set.new
|
25
29
|
end
|
26
30
|
|
27
31
|
def active?
|
28
32
|
@active == true
|
29
33
|
end
|
30
34
|
|
31
|
-
# Partial filepaths to exclude from rcov output
|
32
|
-
def rcov_ignores
|
33
|
-
ignores = (@rcov_ignores || DEFAULT_RCOV_IGNORES).dup
|
34
|
-
ignores << spec_cmd
|
35
|
-
ignores.join(",")
|
36
|
-
end
|
37
|
-
|
38
35
|
def source_dirs
|
39
36
|
@source_dirs || DEFAULT_SOURCE_DIRS
|
40
37
|
end
|
41
38
|
|
42
|
-
|
43
|
-
|
39
|
+
# Compile list of new or changed files with specs.
|
40
|
+
# Execute rspec on their specs.
|
41
|
+
def check_specs
|
42
|
+
specs_to_run.clear
|
43
|
+
@spec_monitor.scan_new_or_changed_with_spec do |file, spec|
|
44
|
+
next if specs_to_ignore.include?(spec)
|
45
|
+
known_specs << spec
|
46
|
+
specs_to_run << spec
|
47
|
+
end
|
48
|
+
if specs_to_run.size > 0
|
49
|
+
print "\nTesting files: #{specs_to_run.join(" ")}\n"
|
50
|
+
system rspec(specs_to_run)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Compile list of new or changed files with tests.
|
55
|
+
# Execute test/unit on the test files.
|
56
|
+
def check_tests
|
57
|
+
tests_to_run.clear
|
58
|
+
@test_monitor.scan_new_or_changed_with_test do |file, test|
|
59
|
+
tests_to_run << test
|
60
|
+
end
|
61
|
+
if tests_to_run.size > 0
|
62
|
+
print "\nTesting files: #{tests_to_run.join(" ")}\n"
|
63
|
+
system 'ruby -e "" -rtest/unit %s' % tests_to_run.map{|test| '-r%s' % test}.join(" ")
|
64
|
+
end
|
44
65
|
end
|
45
66
|
|
67
|
+
# Start an infinite loop which does the following:
|
68
|
+
# * Check for files to test and test them, both for specs and tests
|
69
|
+
# * Sleep for a second
|
70
|
+
# Prior to starting the loop, the INT signal is trapped,
|
71
|
+
# so interrupting the process will not directly kill it.
|
72
|
+
# Instead, RCov is ran on all known specs.
|
46
73
|
def start
|
47
74
|
@active = true
|
48
75
|
@spec_monitor = DirMonitor.new(source_dirs)
|
49
76
|
@test_monitor = DirMonitor.new(source_dirs)
|
50
77
|
trap_int_for_rcov
|
51
78
|
while active? do
|
52
|
-
|
53
|
-
|
54
|
-
known_specs << spec
|
55
|
-
need_testing << spec
|
56
|
-
end
|
57
|
-
if need_testing.size > 0
|
58
|
-
print "\nTesting files: #{need_testing.join(" ")}\n"
|
59
|
-
system rspec(need_testing)
|
60
|
-
end
|
61
|
-
tests_to_run = Set.new
|
62
|
-
@test_monitor.scan_new_or_changed_with_test do |file, test|
|
63
|
-
tests_to_run << test
|
64
|
-
end
|
65
|
-
if tests_to_run.size > 0
|
66
|
-
print "\nTesting files: #{tests_to_run.join(" ")}\n"
|
67
|
-
system 'ruby -e "" -rtest/unit %s' % tests_to_run.map{|test| '-r%s' % test}.join(" ")
|
68
|
-
end
|
79
|
+
check_specs
|
80
|
+
check_tests
|
69
81
|
sleep 1
|
70
82
|
end
|
71
83
|
end
|
72
84
|
|
73
|
-
private
|
74
|
-
|
75
|
-
def find_rcov_cmd
|
76
|
-
`which rcov`.strip
|
77
|
-
end
|
78
|
-
|
79
|
-
def find_spec_cmd
|
80
|
-
`which spec`.strip
|
81
|
-
end
|
82
|
-
|
83
|
-
# Command line string to run rcov for all monitored specs.
|
84
|
-
def rcov
|
85
|
-
"#{rcov_cmd} -T --exclude \"#{rcov_ignores}\" -Ilib #{spec_cmd} -- " + known_specs.join(" ")
|
86
|
-
end
|
87
|
-
|
88
|
-
def rcov_cmd
|
89
|
-
@rcov_cmd ||= find_rcov_cmd
|
90
|
-
end
|
91
|
-
|
92
|
-
def reset_need_testing
|
93
|
-
@need_testing = Set.new
|
94
|
-
end
|
95
|
-
|
96
|
-
# Command line string to run rspec for an array of specs. Defaults to all specs.
|
97
|
-
def rspec(specs=known_specs)
|
98
|
-
"#{spec_cmd} #{specs.join(" ")} #{spec_opts}"
|
99
|
-
end
|
100
|
-
|
101
|
-
# The command to use to run specs.
|
102
|
-
def spec_cmd
|
103
|
-
@spec_cmd ||= ( File.exist?('script/spec') ? 'script/spec' : find_spec_cmd )
|
104
|
-
end
|
105
|
-
|
106
85
|
def trap_int_for_rcov
|
107
86
|
Signal.trap("INT") do
|
108
87
|
print "\nNow we run rcov and we're done.\n\n"
|
109
|
-
|
110
|
-
|
88
|
+
specs = known_specs.select{|s| File.exist?(s)}
|
89
|
+
puts rcov(specs)
|
90
|
+
system rcov(specs)
|
111
91
|
@active = false
|
112
92
|
end
|
113
93
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RcovMixin
|
2
|
+
DEFAULT_RCOV_IGNORES = %w[spec/ db/ plugins/ vendor/ config/]
|
3
|
+
attr_accessor :rcov_ignores
|
4
|
+
|
5
|
+
# Partial filepaths to exclude from rcov output
|
6
|
+
def rcov_ignores
|
7
|
+
ignores = (@rcov_ignores || DEFAULT_RCOV_IGNORES).dup
|
8
|
+
ignores << spec_cmd
|
9
|
+
ignores.join(",")
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def find_rcov_cmd
|
15
|
+
`which rcov`.strip
|
16
|
+
end
|
17
|
+
|
18
|
+
# Command line string to run rcov for all monitored specs.
|
19
|
+
def rcov(files)
|
20
|
+
"#{rcov_cmd} -T --exclude \"#{rcov_ignores}\" -Ilib #{spec_cmd} -- " + files.join(" ")
|
21
|
+
end
|
22
|
+
|
23
|
+
def rcov_cmd
|
24
|
+
@rcov_cmd ||= find_rcov_cmd
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RspecMixin
|
2
|
+
attr_accessor :spec_cmd, :spec_opts
|
3
|
+
DEFAULT_SPECS_TO_IGNORE = %w[spec/spec_helper.rb]
|
4
|
+
|
5
|
+
def spec_opts
|
6
|
+
@spec_opts ||= ( File.exist?('spec/spec.opts') ? '-O spec/spec.opts' : '' )
|
7
|
+
end
|
8
|
+
|
9
|
+
def specs_to_ignore
|
10
|
+
@specs_to_ignore ||= Set.new(DEFAULT_SPECS_TO_IGNORE)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def find_spec_cmd
|
16
|
+
`which spec`.strip
|
17
|
+
end
|
18
|
+
|
19
|
+
# Command line string to run rspec for an array of specs. Defaults to all specs.
|
20
|
+
def rspec(specs=known_specs)
|
21
|
+
"#{spec_cmd} #{specs.join(" ")} #{spec_opts}"
|
22
|
+
end
|
23
|
+
|
24
|
+
# The command to use to run specs.
|
25
|
+
def spec_cmd
|
26
|
+
@spec_cmd ||= ( File.exist?('script/spec') ? 'script/spec' : find_spec_cmd )
|
27
|
+
end
|
28
|
+
end
|
data/minitest.gemspec
CHANGED
@@ -3,7 +3,7 @@ Gem::Specification.new do |s|
|
|
3
3
|
s.name = 'minitest'
|
4
4
|
s.summary = "Minitest is a simple autotester tool."
|
5
5
|
s.description = "Minitest is a simple autotester tool, which uses rSpec and rCov to test ruby and rails projects."
|
6
|
-
s.version = '0.3.
|
6
|
+
s.version = '0.3.2'
|
7
7
|
s.date = '2008-08-14'
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Wes Oldenbeuving"]
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
# Files
|
14
14
|
root_files = %w[MIT-LICENSE README.rdoc Rakefile minitest.gemspec]
|
15
15
|
bin_files = %w[minitest]
|
16
|
-
lib_files = %w[minitest dir_monitor set_ext]
|
16
|
+
lib_files = %w[minitest dir_monitor set_ext mixins/rcov_mixin mixins/rspec_mixin]
|
17
17
|
test_files = %w[]
|
18
18
|
spec_files = %w[minitest dir_monitor set_ext]
|
19
19
|
other_files = %w[spec/spec.opts spec/spec_helper.rb]
|
data/spec/minitest_spec.rb
CHANGED
@@ -2,4 +2,27 @@ require File.join(File.dirname(__FILE__),'spec_helper')
|
|
2
2
|
require 'minitest'
|
3
3
|
|
4
4
|
describe Minitest do
|
5
|
+
describe "#check" do
|
6
|
+
describe 'run existing specs and tests', :shared => true do
|
7
|
+
it 'should run its associated spec'
|
8
|
+
it 'should run its associated test'
|
9
|
+
it 'should skip non-existent specs'
|
10
|
+
it 'should skip non-existent tests'
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '(when a new file is created)' do
|
14
|
+
it_should_behave_like 'run existing specs and tests'
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '(when a file is changed)' do
|
18
|
+
it_should_behave_like 'run existing specs and tests'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#start" do
|
23
|
+
it 'should run #check periodically'
|
24
|
+
describe "(when interrupted)" do
|
25
|
+
it 'should run rcov on known specs and tests'
|
26
|
+
end
|
27
|
+
end
|
5
28
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Narnach-minitest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wes Oldenbeuving
|
@@ -53,6 +53,8 @@ files:
|
|
53
53
|
- lib/minitest.rb
|
54
54
|
- lib/dir_monitor.rb
|
55
55
|
- lib/set_ext.rb
|
56
|
+
- lib/mixins/rcov_mixin.rb
|
57
|
+
- lib/mixins/rspec_mixin.rb
|
56
58
|
has_rdoc: true
|
57
59
|
homepage: http://www.github.com/Narnach/minitest
|
58
60
|
post_install_message:
|