nestor 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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}/, ""))
@@ -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 = if failure.respond_to?(:location) then
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
- test_files.each do |tf|
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
@@ -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
- # +Test::Unit+ case, this means <tt>Dir["test/**/*_test.rb"]</tt>.
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.0
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-29 00:00:00 -04:00
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