nestor 0.1.0 → 0.1.1
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/VERSION +1 -1
- data/doc/state-diagram.graffle +2135 -1855
- data/doc/state-diagram.png +0 -0
- data/lib/nestor/cli.rb +1 -1
- data/lib/nestor/machine.rb +2 -1
- data/lib/nestor/strategies/test/unit.rb +30 -19
- data/lib/nestor/strategies.rb +3 -3
- data/lib/nestor/watchers/rails.rb +3 -3
- data/lib/nestor/watchers/rails_script.rb +7 -1
- data/spec/machine_spec.rb +0 -47
- data/spec/test_unit_strategy_spec.rb +41 -0
- metadata +4 -2
data/doc/state-diagram.png
CHANGED
Binary file
|
data/lib/nestor/cli.rb
CHANGED
@@ -32,7 +32,7 @@ module Nestor
|
|
32
32
|
else
|
33
33
|
puts "Launching..."
|
34
34
|
end
|
35
|
-
Nestor::Watchers::Rails.run(:script => Pathname.new(options[:script]))
|
35
|
+
Nestor::Watchers::Rails.run(:script => options[:script] ? Pathname.new(options[:script]) : nil)
|
36
36
|
end
|
37
37
|
|
38
38
|
desc("customize PATH", <<-EODESC.gsub(/^\s{6}/, ""))
|
data/lib/nestor/machine.rb
CHANGED
@@ -47,7 +47,7 @@ module Nestor
|
|
47
47
|
# The list of failing tests or examples being focused on right now
|
48
48
|
attr_reader :focuses # :nodoc:
|
49
49
|
|
50
|
-
# +strategy+ is required, and must implement a couple of methods. See Nestor::Strategies for the required calls.
|
50
|
+
# +strategy+ is required, and must implement a couple of methods. See {Nestor::Strategies} for the required calls.
|
51
51
|
def initialize(strategy)
|
52
52
|
super() # Have to specify no-args, or else it'll raise an ArgumentError
|
53
53
|
|
@@ -79,6 +79,7 @@ module Nestor
|
|
79
79
|
end
|
80
80
|
|
81
81
|
event :run do
|
82
|
+
transition [:running_all, :running_multi, :running_focused] => same
|
82
83
|
transition :run_focused_pending => :running_focused
|
83
84
|
transition :run_multi_pending => :running_multi
|
84
85
|
end
|
@@ -52,6 +52,33 @@ module Nestor
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
# Utility method to extract data from a Test::Unit failure.
|
56
|
+
#
|
57
|
+
# @param failure [Test::Unit::Failure, Test::Unit::Error] The Test::Unit failure or error from which to extract information.
|
58
|
+
# @param test_files [Array<String>] The list of files that might have generated this failure. This is used to detect the file that caused the failure.
|
59
|
+
#
|
60
|
+
# @return [String, String] Returns the filename and test name as a 2 element Array.
|
61
|
+
def self.parse_failure(failure, test_files)
|
62
|
+
filename = if failure.respond_to?(:location) then
|
63
|
+
failure.location.map do |loc|
|
64
|
+
filename = loc.split(":", 2).first
|
65
|
+
test_files.detect {|tf| filename.include?(tf)}
|
66
|
+
end.compact.first
|
67
|
+
elsif failure.respond_to?(:exception) then
|
68
|
+
failure.exception.backtrace.map do |loc|
|
69
|
+
filename = loc.split(":", 2).first
|
70
|
+
loc = loc[1..-1] if loc[0,1] == "/"
|
71
|
+
test_files.detect {|tf| filename.include?(tf)}
|
72
|
+
end.compact.first
|
73
|
+
else
|
74
|
+
raise "Unknown object type received as failure: #{failure.inspect} doesn't have #exception or #location methods."
|
75
|
+
end
|
76
|
+
|
77
|
+
test_name = failure.test_name.split("(", 2).first.strip.sub(/\.$/, "")
|
78
|
+
|
79
|
+
[filename, test_name]
|
80
|
+
end
|
81
|
+
|
55
82
|
private
|
56
83
|
|
57
84
|
# Since we forked, we can't call into the Machine from the child process. Upstream
|
@@ -61,26 +88,10 @@ module Nestor
|
|
61
88
|
info = {"status" => test_runner.passed? ? "successful" : "failed", "failures" => {}}
|
62
89
|
failures = info["failures"]
|
63
90
|
test_runner.faults.each do |failure|
|
64
|
-
filename =
|
65
|
-
failure.location.detect do |loc|
|
66
|
-
filename = loc.split(":", 2).first
|
67
|
-
test_files.detect {|tf| filename.include?(tf)}
|
68
|
-
end
|
69
|
-
elsif failure.respond_to?(:exception) then
|
70
|
-
failure.exception.backtrace.detect do |loc|
|
71
|
-
filename = loc.split(":", 2).first
|
72
|
-
test_files.detect {|tf| filename.include?(tf)}
|
73
|
-
end
|
74
|
-
else
|
75
|
-
raise "Unknown object type received as failure: #{failure.inspect} doesn't have #exception or #location methods."
|
76
|
-
end
|
77
|
-
|
78
|
-
test_name = failure.test_name.split("(", 2).first.strip
|
91
|
+
filename, test_name = self.class.parse_failure(failure, test_files)
|
79
92
|
if filename.nil? then
|
80
|
-
log("Could not map #{failure.test_name.inspect} to a specific test file: mapping to #{test_files.length}")
|
81
|
-
|
82
|
-
failures[test_name] = tf
|
83
|
-
end
|
93
|
+
log("Could not map #{failure.test_name.inspect} to a specific test file: mapping to #{test_files.length} files")
|
94
|
+
failures[test_name] = test_files
|
84
95
|
else
|
85
96
|
log("Failed #{failure.test_name.inspect} in #{filename.inspect}")
|
86
97
|
failures[test_name] = filename
|
data/lib/nestor/strategies.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module Nestor
|
2
|
-
# Nestor::Cli will require a file named +nestor/strategies/#{strategy_name}+. If you want
|
2
|
+
# {Nestor::Cli} will require a file named +nestor/strategies/#{strategy_name}+. If you want
|
3
3
|
# to provide custom strategies, make it available to Nestor using the correct path.
|
4
4
|
#
|
5
5
|
# Strategies are simple objects that implement the following protocol:
|
6
6
|
#
|
7
7
|
# <tt>log(message)</tt>:: Logs a simple message, either to the console or a logfile.
|
8
|
-
# The Machine will use the +log+ method to notify about it's
|
8
|
+
# The {Nestor::Machine} will use the +log+ method to notify about it's
|
9
9
|
# state transitions.
|
10
10
|
#
|
11
11
|
# <tt>run_all</tt>:: Runs all the tests, no matter what. In the Rails &
|
12
|
-
#
|
12
|
+
# {Nestor::Strategies::Test::Unit} case, this means <tt>Dir["test/**/*_test.rb"]</tt>.
|
13
13
|
#
|
14
14
|
# <tt>run(tests_files, focused_cases=[])</tt>:: Runs only a subset of the tests, maybe
|
15
15
|
# focusing on only a couple of tests / examples.
|
@@ -5,12 +5,12 @@ module Nestor
|
|
5
5
|
module Watchers
|
6
6
|
# Knows how to map file change events from Rails conventions to the corresponding test case.
|
7
7
|
module Rails
|
8
|
-
# Launches a Watchr::Controller to and never returns. The Controller will
|
8
|
+
# Launches a {Watchr::Controller} to and never returns. The Controller will
|
9
9
|
# listen for file change events and trigger appropriate events on the Machine.
|
10
10
|
#
|
11
|
-
# By default, the Rails watcher will use the +Test::Unit+ strategy.
|
11
|
+
# By default, the Rails watcher will use the +{Nestor::Strategies::Test::Unit}+ strategy.
|
12
12
|
#
|
13
|
-
# @option options :strategy [Nestor::Strategies] The strategy to use. Must be an instance of a class that implements the protocol defined in Nestor::Strategies.
|
13
|
+
# @option options :strategy [Nestor::Strategies] ({Nestor::Strategies::Test::Unit}) The strategy to use. Must be an instance of a class that implements the protocol defined in {Nestor::Strategies}.
|
14
14
|
# @option options :script The path to the Watchr script.
|
15
15
|
#
|
16
16
|
# @return Never...
|
@@ -26,6 +26,7 @@ def sendoff(timeout=0.8, path="tmp/nestor-sendoff") #:nodoc:
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def changed!(filename) #:nodoc:
|
29
|
+
return if File.directory?(filename)
|
29
30
|
@machine.changed! filename
|
30
31
|
sendoff
|
31
32
|
end
|
@@ -59,6 +60,11 @@ watch 'test/test_helper\.rb' do |md|
|
|
59
60
|
@machine.reset!
|
60
61
|
end
|
61
62
|
|
63
|
+
watch 'db/schema.rb' do |_|
|
64
|
+
log "Detected changed schema: preparing test DB"
|
65
|
+
system("rake db:test:prepare")
|
66
|
+
end
|
67
|
+
|
62
68
|
watch 'test/(?:unit|functional|integration|performance)/.*' do |md|
|
63
69
|
log "#{md[0].inspect} => #{md[0].inspect}"
|
64
70
|
changed! md[0]
|
@@ -72,7 +78,7 @@ watch 'tmp/nestor-results.yml' do |md|
|
|
72
78
|
info = YAML.load_file(md[0])
|
73
79
|
log "New results in: #{info.inspect}"
|
74
80
|
failures = info["failures"]
|
75
|
-
@machine.send("run_#{info["status"]}!", failures.values.uniq, failures.keys)
|
81
|
+
@machine.send("run_#{info["status"]}!", failures.values.flatten.uniq, failures.keys)
|
76
82
|
end
|
77
83
|
|
78
84
|
watch 'tmp/nestor-sendoff' do |_|
|
data/spec/machine_spec.rb
CHANGED
@@ -7,50 +7,3 @@ describe Nestor::Machine do
|
|
7
7
|
machine.strategy.should be_equal(strategy)
|
8
8
|
end
|
9
9
|
end
|
10
|
-
|
11
|
-
describe Nestor::Machine do
|
12
|
-
before(:each) do
|
13
|
-
@strategy = mock
|
14
|
-
@strategy.stub(:run_all)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should start in the :running_all state" do
|
18
|
-
@machine = Nestor::Machine.new(@strategy)
|
19
|
-
machine.should be_running_all
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should tell the strategy to run all tests" do
|
23
|
-
strategy = mock
|
24
|
-
strategy.should_receive(:run_all).with().once
|
25
|
-
Nestor::Machine.new(strategy)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should transition to :green when calling #successful" do
|
29
|
-
machine.successful
|
30
|
-
machine.should be_green
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should transition to :run_focused when calling #failed" do
|
34
|
-
machine.failed
|
35
|
-
machine.should be_run_focused
|
36
|
-
end
|
37
|
-
|
38
|
-
def machine
|
39
|
-
@machine ||= Nestor::Machine.new(@strategy)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe Nestor::Machine, "when in the run_focused state" do
|
44
|
-
before(:each) do
|
45
|
-
@strategy = mock
|
46
|
-
@strategy.stub(:run_all)
|
47
|
-
@machine = Nestor::Machine.new(@strategy)
|
48
|
-
@machine.failed
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should transition to :running_focused when calling #changed!(filename)" do
|
52
|
-
@strategy.should_receive(:run).with(["spec/machine_spec.rb"])
|
53
|
-
@machine.changed!("spec/machine_spec.rb")
|
54
|
-
@machine.should be_running_focused
|
55
|
-
end
|
56
|
-
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
require "nestor/strategies/test/unit"
|
3
|
+
|
4
|
+
describe Nestor::Strategies::Test::Unit, "#parse_failure" do
|
5
|
+
it "should return the file and test name as reported by a failure" do
|
6
|
+
failure = mock
|
7
|
+
failure.stub(:location).and_return(
|
8
|
+
["/test/functional/api/templates_controller_test.rb:12:in `__bind_1256961206_373905'",
|
9
|
+
"/Library/Ruby/Gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:351:in `call'",
|
10
|
+
"/Library/Ruby/Gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:351:in `test: Api::TemplatesController should flunk. '",
|
11
|
+
"/Users/francois/Projects/nestor/lib/nestor/strategies/test/unit.rb:109:in `run'"])
|
12
|
+
failure.stub(:test_name).and_return("test: Api::TemplatesController should flunk. (Api::TemplatesControllerTest)")
|
13
|
+
|
14
|
+
test_files = ["test/functional/api/templates_controller_test.rb"]
|
15
|
+
|
16
|
+
filename, test_name = Nestor::Strategies::Test::Unit.parse_failure(failure, test_files)
|
17
|
+
|
18
|
+
filename.should == "test/functional/api/templates_controller_test.rb"
|
19
|
+
test_name.should == "test: Api::TemplatesController should flunk"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return the file and test name as reported by an error" do
|
23
|
+
exception = RuntimeError.new("bad")
|
24
|
+
exception.set_backtrace(["./test/functional/api/templates_controller_test.rb:12:in `__bind_1256962198_402597'",
|
25
|
+
"/Library/Ruby/Gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:351:in `call'",
|
26
|
+
"/Library/Ruby/Gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:351:in `test: Api::TemplatesController should flunk. '",
|
27
|
+
"/Library/Ruby/Gems/1.8/gems/activesupport-2.3.4/lib/active_support/testing/setup_and_teardown.rb:62:in `__send__'",
|
28
|
+
"/Library/Ruby/Gems/1.8/gems/activesupport-2.3.4/lib/active_support/testing/setup_and_teardown.rb:62:in `run'"])
|
29
|
+
|
30
|
+
failure = mock
|
31
|
+
failure.stub(:exception).and_return(exception)
|
32
|
+
failure.stub(:test_name).and_return("test: Api::TemplatesController should flunk. (Api::TemplatesControllerTest)")
|
33
|
+
|
34
|
+
test_files = ["test/functional/api/templates_controller_test.rb"]
|
35
|
+
|
36
|
+
filename, test_name = Nestor::Strategies::Test::Unit.parse_failure(failure, test_files)
|
37
|
+
|
38
|
+
filename.should == "test/functional/api/templates_controller_test.rb"
|
39
|
+
test_name.should == "test: Api::TemplatesController should flunk"
|
40
|
+
end
|
41
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nestor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Fran\xC3\xA7ois Beausoleil"
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-31 00:00:00 -04:00
|
13
13
|
default_executable: nestor
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/nestor/watchers/rails_script.rb
|
93
93
|
- spec/machine_spec.rb
|
94
94
|
- spec/spec_helper.rb
|
95
|
+
- spec/test_unit_strategy_spec.rb
|
95
96
|
- vendor/watchr-0.5.7/.gitignore
|
96
97
|
- vendor/watchr-0.5.7/History.txt
|
97
98
|
- vendor/watchr-0.5.7/LICENSE
|
@@ -150,3 +151,4 @@ summary: Nestor keeps the place tidy by running your specs/tests everytime a fil
|
|
150
151
|
test_files:
|
151
152
|
- spec/machine_spec.rb
|
152
153
|
- spec/spec_helper.rb
|
154
|
+
- spec/test_unit_strategy_spec.rb
|