Narnach-minitest 0.2.2 → 0.3.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.
data/README.rdoc CHANGED
@@ -2,6 +2,10 @@
2
2
  Minitest is a simple autotester intended to be used with rSpec and rCov.
3
3
  It can be used with 'plain' ruby projects and Ruby on Rails.
4
4
 
5
+ == Recent changes
6
+ Version 0.3.0 switched to a new file monitoring backend, DirMonitor.
7
+ The 'recent' feature was removed.
8
+
5
9
  == Installation
6
10
  === From gem
7
11
  Use gem to install minitest. The gem is located on github.
@@ -15,14 +19,12 @@ This will build the gem and install it for you.
15
19
 
16
20
  == Usage
17
21
  Minitest has the following command line options:
18
- recent:: Only specs for files modified within the last hour are executed on the first run. All files are still monitored for changes, though.
19
22
  profile:: Force rspec output format to 'profile', combined with coloured output and unified diffs.
23
+ drb:: Use a spec server to execute specs, speeding up their execution.
20
24
 
21
25
  == Examples
22
26
  When you start working on a codebase, it makes sense to run all specs:
23
27
  minitest
24
- When you resume work on a codebase you recently worked on, it might be useful skip running the specs for unchanged files on the first run:
25
- minitest recent
26
28
  When you want to see which specs are slow and could use optimizing:
27
29
  minitest profile
28
30
  You can also combine options:
data/Rakefile CHANGED
@@ -26,19 +26,3 @@ desc 'Package and install the gem for the current version'
26
26
  task :install => :gem do
27
27
  system "sudo gem install -l pkg/minitest-%s.gem" % spec.version
28
28
  end
29
-
30
- namespace :gem do
31
- desc 'Re-generate the gemspec'
32
- task :gemspec do
33
- files = Dir["*.rdoc"] + %w( Rakefile MIT-LICENSE ) + Dir["{spec,lib,bin}/**/*"]
34
- tests = Dir["spec/**/*"]
35
- data = File.read('minitest.gemspec.template')
36
- files_string = "[%s]" % files.sort.uniq.map{|f| "'%s'" % f}.join(", ")
37
- tests_string = "[%s]" % tests.sort.uniq.map{|f| "'%s'" % f}.join(", ")
38
- data.gsub!(':FILES:', files_string)
39
- data.gsub!(':TEST_FILES:', tests_string)
40
- File.open('minitest.gemspec','wb') { |f| f.puts(data) }
41
- puts data
42
- end
43
- end
44
-
data/bin/minitest CHANGED
@@ -3,7 +3,6 @@ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__),'..','lib')
3
3
  require 'minitest'
4
4
 
5
5
  minitest = Minitest.new
6
- minitest.recent = (ARGV.include? "recent")
7
6
  custom_spec_opts = ''
8
7
  custom_spec_opts << " --drb" if ARGV.include? "drb"
9
8
  custom_spec_opts << " --format profile --colour --diff unified" if ARGV.include? "profile"
data/lib/dir_monitor.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  # - Link these files to their specs, so Minitest can run the specs.
6
6
  class DirMonitor
7
7
  attr_reader :known_files, :dirs, :last_mtime
8
-
8
+
9
9
  # Setup a new DirMonitor.
10
10
  # Directories can be provided in a number of ways:
11
11
  # DirMonitor.new 'lib', 'app'
@@ -17,7 +17,7 @@ class DirMonitor
17
17
  @known_files = []
18
18
  @last_mtime = {}
19
19
  end
20
-
20
+
21
21
  # Scan for all files in the directories and their sub-directories.
22
22
  # The results are stored as a single array in @known_files.
23
23
  def scan
@@ -28,7 +28,7 @@ class DirMonitor
28
28
  end
29
29
  @known_files = results
30
30
  end
31
-
31
+
32
32
  # Scan for changes in the known files.
33
33
  # Yields the name of the changed files.
34
34
  # Stores the mtime for all changed files.
@@ -41,7 +41,7 @@ class DirMonitor
41
41
  end
42
42
  end
43
43
  end
44
-
44
+
45
45
  # Scans for changed known files, using #scan_changed. Yields the name of both the file and its associated spec.
46
46
  # spec_for is used to determine what the name of the file's spec _should_ be.
47
47
  # Does not yield a file/spec name when the spec does not exist.
@@ -51,7 +51,7 @@ class DirMonitor
51
51
  block.call(file, spec) if File.exists?(spec)
52
52
  end
53
53
  end
54
-
54
+
55
55
  # Scan for new files.
56
56
  # All new file names are yielded.
57
57
  def scan_new(&block) # :yields: file
@@ -62,7 +62,7 @@ class DirMonitor
62
62
  block.call(new_file)
63
63
  end
64
64
  end
65
-
65
+
66
66
  # Scan for new files and check for changed known files.
67
67
  # Only yields a file once per call.
68
68
  def scan_new_or_changed_with_spec(&block) # :yields: file, spec
@@ -73,9 +73,9 @@ class DirMonitor
73
73
  yielded_files[file]=nil
74
74
  end
75
75
  scan_new_with_spec(&yield_once_block)
76
- scan_changed_with_spec(&yield_once_block)
76
+ scan_changed_with_spec(&yield_once_block)
77
77
  end
78
-
78
+
79
79
  # Scans for new files, like scan_new does, but yields the name of both the file and spec.
80
80
  # spec_for is used to determine what the name of the file's spec _should_ be.
81
81
  # Does not yield a file/spec name when the spec does not exist.
@@ -85,7 +85,7 @@ class DirMonitor
85
85
  block.call(file, spec) if File.exists?(spec)
86
86
  end
87
87
  end
88
-
88
+
89
89
  # Find the (theoretical) spec file name for a given file.
90
90
  # The assumptions are:
91
91
  # - All specs reside in the 'spec' directory.
data/lib/minitest.rb CHANGED
@@ -1,69 +1,54 @@
1
+ require 'set'
2
+ require 'dir_monitor'
3
+
4
+ class Set
5
+ def join(*args,&block)
6
+ map.join(*args,&block)
7
+ end
8
+ end
9
+
1
10
  # = Minitest
2
11
  # The default usage of Minitest is this:
3
12
  # minitest = Minitest.new
4
13
  # minitest.start
5
14
  # This will do the following:
6
- # - Lookup all spec files in the spec/ directory.
7
- # - Lookup all possible associated files in the lib/ and app/ directories.
8
- # - Remember the mtimes (last modification times) of all relevant files.
9
- # - Every second, check all known relevant files: if their mtime changes, run rspec on their spec file.
15
+ # - Initialize a DirMonitor
16
+ # - Map all files in source dirs to specs
17
+ # - Frequently check for new or changed files; run rspec on their associated specs
10
18
  # - Run rcov (code coverage tester) on all specs when exiting (Press ctrl-C on send SIGINT to the process)
11
19
  class Minitest
12
- attr_reader :file_mtime
13
- attr_reader :file_spec
14
- attr_accessor :rcov_ignores
15
- attr_accessor :recent
16
- attr_accessor :recent_time
17
20
  attr_accessor :source_dirs
18
- attr_accessor :source_extensions
19
- attr_accessor :spec_cmd
20
- attr_accessor :spec_opts
21
-
21
+ attr_accessor :rcov_ignores
22
+ attr_accessor :spec_cmd, :spec_opts
23
+ attr_reader :need_testing, :known_specs
24
+
22
25
  DEFAULT_RCOV_IGNORES = %w[spec/ db/ plugins/ vendor/ config/]
23
- DEFAULT_RECENT_TIME = 3600
24
- DEFAULT_SOURCE_DIRS = %w[lib app]
25
- DEFAULT_SOURCE_EXTENSIONS = %w[rb haml rhtml erb]
26
-
26
+ DEFAULT_SOURCE_DIRS = %w[lib app spec test]
27
+
27
28
  def initialize
28
- @file_spec = {} # Map files to their specs
29
- @file_mtime = {} # Map files to their mtimes
30
- @need_testing = [] # Specs that need testing
31
- @first_run = true
32
29
  @active = false
30
+ @known_specs = Set.new
31
+ @need_testing = Set.new
33
32
  end
34
33
 
35
34
  def active?
36
35
  @active == true
37
36
  end
38
37
 
39
- def first_run?
40
- @first_run == true
41
- end
42
-
43
38
  # Partial filepaths to exclude from rcov output
44
39
  def rcov_ignores
45
- ignores = @rcov_ignores || DEFAULT_RCOV_IGNORES
40
+ ignores = (@rcov_ignores || DEFAULT_RCOV_IGNORES).dup
46
41
  ignores << spec_cmd
47
42
  ignores.join(",")
48
43
  end
49
44
 
50
45
  # Command line string to run rcov for all monitored specs.
51
46
  def rcov
52
- "#{rcov_cmd} -T --exclude \"#{rcov_ignores}\" -Ilib #{spec_cmd} -- " + self.unique_specs.join(" ")
53
- end
54
-
55
- def recent?
56
- @recent == true
57
- end
58
-
59
- # Maximum amount of seconds since a file has been changed for it to count as
60
- # recently changed.
61
- def recent_time
62
- @recent_time || DEFAULT_RECENT_TIME
47
+ "#{rcov_cmd} -T --exclude \"#{rcov_ignores}\" -Ilib #{spec_cmd} -- " + known_specs.join(" ")
63
48
  end
64
49
 
65
50
  # Command line string to run rspec for an array of specs. Defaults to all specs.
66
- def rspec(specs=self.unique_specs)
51
+ def rspec(specs=known_specs)
67
52
  "#{spec_cmd} #{specs.join(" ")} #{spec_opts}"
68
53
  end
69
54
 
@@ -71,10 +56,6 @@ class Minitest
71
56
  @source_dirs || DEFAULT_SOURCE_DIRS
72
57
  end
73
58
 
74
- def source_extensions
75
- @source_extensions || DEFAULT_SOURCE_EXTENSIONS
76
- end
77
-
78
59
  def rcov_cmd
79
60
  @rcov_cmd ||= find_rcov_cmd
80
61
  end
@@ -90,23 +71,19 @@ class Minitest
90
71
 
91
72
  def start
92
73
  @active = true
93
- find_specs
94
-
95
- if self.file_spec.values.uniq.size == 0
96
- puts "There are no specs to run."
97
- return
98
- end
99
-
100
- need_testing = find_first_run_specs
101
-
74
+ @dir_monitor = DirMonitor.new(source_dirs)
102
75
  trap_int_for_rcov
103
76
  while active? do
77
+ reset_need_testing
78
+ @dir_monitor.scan_new_or_changed_with_spec do |file, spec|
79
+ known_specs << spec
80
+ need_testing << spec
81
+ end
104
82
  if need_testing.size > 0
105
83
  print "\nTesting files: #{need_testing.join(" ")}\n"
106
84
  system rspec(need_testing)
107
85
  end
108
86
  sleep 1
109
- need_testing = find_specs_to_check
110
87
  end
111
88
  end
112
89
 
@@ -119,86 +96,17 @@ class Minitest
119
96
  end
120
97
  end
121
98
 
122
- def unique_specs
123
- self.file_spec.values.uniq.sort
124
- end
99
+ private
125
100
 
126
- private
127
-
128
- def find_first_run_specs
129
- need_checking = self.file_mtime.keys.dup
130
- specs_to_check = []
131
- if first_run? and recent?
132
- need_checking.reject! { |file| @file_mtime[file] < ( Time.now - recent_time ) }
133
- if need_checking.size > 0
134
- puts "This first run will only test files changed in the last hour. All other files are still monitored."
135
- else
136
- puts "No files were changed in the last hour, so no files are tested for the first run."
137
- end
138
- end
139
- specs_to_check = need_checking.map {|f| @file_spec[f]}
140
- specs_to_check.uniq!
141
- specs_to_check.sort!
142
- @first_run = false
143
- return specs_to_check
144
- end
145
-
146
- def find_sources_for_spec(spec)
147
- found_files = []
148
- for dir in self.source_dirs
149
- next unless spec[0,4]=='spec'
150
-
151
- file = spec.dup
152
- file[0,4]=dir
153
- file.gsub!("_spec.",".")
154
- candidates = self.source_extensions.map { |ext| file.gsub(/[^.]+\Z/, ext)}
155
- candidates = candidates.select { |f| File.exist?(f) }
156
- found_files += candidates
157
- end
158
- found_files.uniq!
159
- return found_files
160
- end
161
-
162
101
  def find_rcov_cmd
163
102
  `which rcov`.strip
164
103
  end
165
-
104
+
166
105
  def find_spec_cmd
167
106
  `which spec`.strip
168
107
  end
169
108
 
170
- def find_specs
171
- Dir.glob("spec/**/*_spec.rb").each do |spec|
172
- # If a spec changes, run it again.
173
- map_file_to_spec(spec,spec)
174
- for file in find_sources_for_spec(spec)
175
- map_file_to_spec(file,spec)
176
- end
177
- end
178
- end
179
-
180
- def find_specs_to_check
181
- specs = []
182
- @file_mtime.each do |file, old_mtime|
183
- current_mtime = File.mtime(file)
184
- if current_mtime != old_mtime
185
- specs << @file_spec[file]
186
- store_mtime file
187
- end
188
- end
189
- specs.uniq!
190
- specs.sort!
191
- return specs
192
- end
193
-
194
- def map_file_to_spec(file,spec)
195
- return if @file_mtime.has_key? file
196
- @file_spec[file.dup]=spec.dup
197
- store_mtime file
198
- store_mtime spec
199
- end
200
-
201
- def store_mtime(file)
202
- @file_mtime[file.dup] = File.mtime(file)
109
+ def reset_need_testing
110
+ @need_testing = Set.new
203
111
  end
204
112
  end
@@ -11,7 +11,7 @@ describe DirMonitor, ".new" do
11
11
  dm = DirMonitor.new(%w[lib app])
12
12
  dm.dirs.should == ['lib','app']
13
13
  end
14
-
14
+
15
15
  it "should have no known files" do
16
16
  dm = DirMonitor.new('lib')
17
17
  dm.known_files.should == []
@@ -36,7 +36,7 @@ describe DirMonitor, "#scan_new" do
36
36
  Dir.stub!(:glob).with('lib/**/*').and_return(@known_files)
37
37
  @dm = DirMonitor.new 'lib'
38
38
  end
39
-
39
+
40
40
  it "should yield the names of all new files" do
41
41
  yield_results = []
42
42
  @dm.scan_new do |file|
@@ -44,7 +44,7 @@ describe DirMonitor, "#scan_new" do
44
44
  end
45
45
  yield_results.should == @known_files
46
46
  end
47
-
47
+
48
48
  it "should not yield known file names" do
49
49
  known_files2 = %w[lib/minitest.rb lib/dir_monitor2.rb]
50
50
  Dir.stub!(:glob).with('lib/**/*').and_return(@known_files, known_files2)
@@ -64,7 +64,7 @@ describe DirMonitor, "#scan_new_with_spec" do
64
64
  Dir.stub!(:glob).with('lib/**/*').and_return([@file])
65
65
  @dm = DirMonitor.new 'lib'
66
66
  end
67
-
67
+
68
68
  it "should yield new files and their specs" do
69
69
  File.should_receive(:exists?).with(@spec).and_return(true)
70
70
  results = []
@@ -73,7 +73,7 @@ describe DirMonitor, "#scan_new_with_spec" do
73
73
  end
74
74
  results.should == [{@file=>@spec}]
75
75
  end
76
-
76
+
77
77
  it "should not yield files with non-existent specs" do
78
78
  File.should_receive(:exists?).with(@spec).and_return(false)
79
79
  results = []
@@ -93,7 +93,7 @@ describe DirMonitor, "#scan_changed" do
93
93
  @dm = DirMonitor.new 'lib'
94
94
  @dm.scan
95
95
  end
96
-
96
+
97
97
  it "should yield the names of changed known files" do
98
98
  changes = []
99
99
  @dm.scan_changed do |changed_file|
@@ -101,7 +101,7 @@ describe DirMonitor, "#scan_changed" do
101
101
  end
102
102
  changes.should == [@file]
103
103
  end
104
-
104
+
105
105
  it "should not yield the names of files which did not change since last scan" do
106
106
  @dm.scan_changed { |f| }
107
107
  changes = []
@@ -134,7 +134,7 @@ describe DirMonitor, "scan_changed_with_spec" do
134
134
  @dm = DirMonitor.new 'lib'
135
135
  @dm.scan
136
136
  end
137
-
137
+
138
138
  it "should yield the file name and spec name of changed files with an existing spec" do
139
139
  File.should_receive(:exists?).with(@spec).and_return(true)
140
140
  changes = []
@@ -163,7 +163,7 @@ describe DirMonitor, "scan_new_or_changed_with_spec" do
163
163
  File.stub!(:mtime).with(@file).and_return(@time)
164
164
  @dm = DirMonitor.new 'lib'
165
165
  end
166
-
166
+
167
167
  it "should yield a file and spec when a file is new" do
168
168
  results = []
169
169
  @dm.scan_new_or_changed_with_spec do |file, spec|
@@ -171,7 +171,7 @@ describe DirMonitor, "scan_new_or_changed_with_spec" do
171
171
  end
172
172
  results.should == [{@file=>@spec}]
173
173
  end
174
-
174
+
175
175
  it "should yield a file and spec when a file is not new but has changed" do
176
176
  @dm.scan
177
177
  @dm.scan_changed {|f|}
@@ -182,7 +182,7 @@ describe DirMonitor, "scan_new_or_changed_with_spec" do
182
182
  end
183
183
  results.should == [{@file=>@spec}]
184
184
  end
185
-
185
+
186
186
  it "should not yield a file and spec when a file is not new and has not changed" do
187
187
  @dm.scan
188
188
  @dm.scan_changed {|f|}
@@ -198,19 +198,19 @@ describe DirMonitor, "#spec_for" do
198
198
  before(:each) do
199
199
  @dm = DirMonitor.new
200
200
  end
201
-
201
+
202
202
  it "should find the spec for a given file" do
203
203
  file = 'lib/dir_monitor.rb'
204
204
  spec = 'spec/dir_monitor_spec.rb'
205
205
  @dm.spec_for(file).should == spec
206
206
  end
207
-
207
+
208
208
  it "should find the spec for non-ruby files" do
209
209
  file = 'app/views/posts/post.html.haml'
210
210
  spec = 'spec/views/posts/post.html.haml_spec.rb'
211
211
  @dm.spec_for(file).should == spec
212
212
  end
213
-
213
+
214
214
  it "should map specs to themselves" do
215
215
  spec = 'spec/dir_monitor_spec.rb'
216
216
  @dm.spec_for(spec).should == spec
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.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wes Oldenbeuving
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-21 00:00:00 -07:00
12
+ date: 2008-08-14 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency