Narnach-minitest 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|