rspactor 0.5.4 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/.rspactor +0 -0
- data/LICENSE +1 -1
- data/README.rdoc +18 -0
- data/Rakefile +41 -48
- data/VERSION +1 -0
- data/bin/rspactor +1 -2
- data/lib/cucumber_growler.rb +8 -8
- data/lib/rspactor/inspector.rb +19 -11
- data/lib/rspactor/interactor.rb +21 -5
- data/lib/rspactor/listener.rb +26 -59
- data/lib/rspactor/runner.rb +24 -19
- data/lib/rspactor/spork.rb +46 -11
- data/lib/rspactor.rb +0 -3
- data/rspactor.gemspec +73 -0
- data/spec/inspector_spec.rb +7 -7
- data/spec/listener_spec.rb +1 -9
- data/spec/runner_spec.rb +3 -1
- metadata +47 -21
- data/lib/rspactor/celerity.rb +0 -29
data/.gitignore
ADDED
data/.rspactor
ADDED
File without changes
|
data/LICENSE
CHANGED
data/README.rdoc
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
=== Install
|
2
|
+
|
3
|
+
git clone git://github.com/guillaumegentil/rspactor.git
|
4
|
+
cd rspactor
|
5
|
+
rake install
|
6
|
+
|
7
|
+
=== Usage
|
8
|
+
|
9
|
+
cd /path/to/rails/root/
|
10
|
+
rspactor
|
11
|
+
|
12
|
+
=== Command Line Options
|
13
|
+
|
14
|
+
* <code> --coral </code>
|
15
|
+
* <code> --drb </code>
|
16
|
+
* <code> --view </code>
|
17
|
+
* <code> --clear </code>
|
18
|
+
* <code> --run_in </code>
|
data/Rakefile
CHANGED
@@ -1,58 +1,51 @@
|
|
1
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
|
-
desc "generates .gemspec file"
|
9
|
-
task :gemspec => "version:read" do
|
10
|
-
spec = Gem::Specification.new do |gem|
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
11
7
|
gem.name = "rspactor"
|
12
|
-
gem.summary = "RSpactor is a command line tool to automatically run your changed specs & cucumber features
|
13
|
-
gem.description = "
|
14
|
-
gem.email = "
|
15
|
-
gem.homepage = "http://github.com/
|
8
|
+
gem.summary = "RSpactor is a command line tool to automatically run your changed specs & cucumber features."
|
9
|
+
gem.description = "RSpactor is a command line tool to automatically run your changed specs & cucumber features (much like autotest)."
|
10
|
+
gem.email = "thibaud@thibaud.me"
|
11
|
+
gem.homepage = "http://github.com/thibaudgg/rspactor"
|
16
12
|
gem.authors = ["Mislav Marohnić", "Andreas Wolff", "Pelle Braendgaard", "Thibaud Guillaume-Gentil"]
|
17
|
-
gem.
|
18
|
-
|
19
|
-
gem.
|
20
|
-
gem.files = FileList['Rakefile', '{bin,lib,images,spec}/**/*', 'README*', 'LICENSE*']
|
21
|
-
gem.executables = Dir['bin/*'].map { |f| File.basename(f) }
|
22
|
-
end
|
23
|
-
|
24
|
-
spec_string = spec.to_ruby
|
25
|
-
|
26
|
-
begin
|
27
|
-
Thread.new { eval("$SAFE = 3\n#{spec_string}", binding) }.join
|
28
|
-
rescue
|
29
|
-
abort "unsafe gemspec: #{$!}"
|
30
|
-
else
|
31
|
-
File.open("#{spec.name}.gemspec", 'w') { |file| file.write spec_string }
|
13
|
+
gem.add_dependency "ruby-fsevent", ">= 0.2.1"
|
14
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
32
16
|
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
33
20
|
end
|
34
21
|
|
35
|
-
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
+
end
|
36
27
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
task :bump => :read do
|
45
|
-
if ENV['VERSION']
|
46
|
-
GEM_VERSION.replace ENV['VERSION']
|
47
|
-
else
|
48
|
-
GEM_VERSION.sub!(/\d+$/) { |num| num.to_i + 1 }
|
49
|
-
end
|
50
|
-
|
51
|
-
File.open("VERSION", 'w') { |v| v.write GEM_VERSION }
|
52
|
-
end
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
+
spec.rcov = true
|
53
32
|
end
|
54
33
|
|
55
|
-
|
56
|
-
|
57
|
-
system
|
34
|
+
desc "starts RSpactor"
|
35
|
+
task :rspactor do
|
36
|
+
system "ruby -Ilib bin/rspactor"
|
37
|
+
end
|
38
|
+
|
39
|
+
task :spec => :check_dependencies
|
40
|
+
|
41
|
+
task :default => :rspactor
|
42
|
+
|
43
|
+
require 'rake/rdoctask'
|
44
|
+
Rake::RDocTask.new do |rdoc|
|
45
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
46
|
+
|
47
|
+
rdoc.rdoc_dir = 'rdoc'
|
48
|
+
rdoc.title = "rspactor #{version}"
|
49
|
+
rdoc.rdoc_files.include('README*')
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
58
51
|
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.6.2
|
data/bin/rspactor
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require
|
2
|
+
require 'rspactor/runner'
|
3
3
|
|
4
4
|
RSpactor::Runner.start({
|
5
5
|
:coral => ARGV.delete('--coral'),
|
6
|
-
:celerity => ARGV.delete('--celerity'),
|
7
6
|
:spork => ARGV.delete('--drb'),
|
8
7
|
:view => ARGV.delete('--view'), # by default, rspactor didn't catch specs view
|
9
8
|
:clear => ARGV.delete('--clear'),
|
data/lib/cucumber_growler.rb
CHANGED
@@ -4,13 +4,13 @@ require File.dirname(__FILE__) + '/rspactor/growl'
|
|
4
4
|
|
5
5
|
module CucumberGrowler
|
6
6
|
include RSpactor::Growl
|
7
|
-
|
7
|
+
|
8
8
|
def self.included(base)
|
9
9
|
base.class_eval do
|
10
10
|
alias original_print_stats print_stats
|
11
11
|
include InstanceMethods
|
12
|
-
|
13
|
-
def print_stats(features)
|
12
|
+
|
13
|
+
def print_stats(features, profiles = [])
|
14
14
|
title, icon, messages = '', '', []
|
15
15
|
[:failed, :skipped, :undefined, :pending, :passed].reverse.each do |status|
|
16
16
|
if step_mother.steps(status).any?
|
@@ -19,13 +19,13 @@ module CucumberGrowler
|
|
19
19
|
messages << dump_count(step_mother.steps(status).length, "step", status.to_s)
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
notify "Cucumber Results", messages.reverse.join(", "), icon
|
24
|
-
original_print_stats(features)
|
24
|
+
original_print_stats(features, profiles = [])
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
module InstanceMethods
|
30
30
|
def icon_for(status)
|
31
31
|
case status
|
@@ -37,7 +37,7 @@ module CucumberGrowler
|
|
37
37
|
'failed'
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def title_for(status)
|
42
42
|
case status
|
43
43
|
when :passed
|
@@ -53,7 +53,7 @@ module CucumberGrowler
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
end
|
58
58
|
|
59
59
|
module Cucumber::Formatter::Console
|
data/lib/rspactor/inspector.rb
CHANGED
@@ -16,6 +16,8 @@ module RSpactor
|
|
16
16
|
def determine_files(file)
|
17
17
|
candidates = translate(file)
|
18
18
|
cucumberable = candidates.delete('cucumber')
|
19
|
+
runner.spork.reload if candidates.delete('spork') && runner.spork?
|
20
|
+
|
19
21
|
candidates.reject { |candidate| candidate.index('.') }.each do |dir|
|
20
22
|
candidates.reject! { |candidate| candidate.index("#{dir}/") == 0 }
|
21
23
|
end
|
@@ -38,6 +40,7 @@ module RSpactor
|
|
38
40
|
candidates << file
|
39
41
|
elsif cucumber_file?(file)
|
40
42
|
candidates << 'cucumber'
|
43
|
+
candidates << 'spork' if file =~ /^features\/support\//
|
41
44
|
else
|
42
45
|
spec_file = append_spec_file_extension(file)
|
43
46
|
|
@@ -46,13 +49,18 @@ module RSpactor
|
|
46
49
|
if file =~ %r:^app/controllers/application(_controller)?.rb$:
|
47
50
|
candidates << 'controllers'
|
48
51
|
elsif file == 'app/helpers/application_helper.rb'
|
49
|
-
candidates << 'helpers'
|
50
|
-
|
52
|
+
candidates << 'helpers'
|
53
|
+
candidates << 'views' if runner.options[:view]
|
54
|
+
elsif file.include?("app/views/")
|
55
|
+
if runner.options[:view]
|
56
|
+
candidates << spec_file.sub('app/', '')
|
57
|
+
if file =~ %r:^app/(views/.+\.[a-z]+)\.[a-z]+$:
|
58
|
+
candidates << append_spec_file_extension($1)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
else
|
51
62
|
candidates << spec_file.sub('app/', '')
|
52
|
-
|
53
|
-
if file =~ %r:^app/(views/.+\.[a-z]+)\.[a-z]+$:
|
54
|
-
candidates << append_spec_file_extension($1)
|
55
|
-
elsif file =~ %r:app/helpers/(\w+)_helper.rb:
|
63
|
+
if file =~ %r:app/helpers/(\w+)_helper.rb:
|
56
64
|
candidates << "views/#{$1}"
|
57
65
|
elsif file =~ /_observer.rb$/
|
58
66
|
candidates << candidates.last.sub('_observer', '')
|
@@ -65,16 +73,16 @@ module RSpactor
|
|
65
73
|
# lib/bar_spec.rb -> bar_spec.rb
|
66
74
|
candidates << candidates.last.sub(%r:\w+/:, '') if candidates.last.index('/')
|
67
75
|
when 'config/routes.rb'
|
68
|
-
candidates << 'controllers' << 'helpers' << '
|
76
|
+
candidates << 'controllers' << 'helpers' << 'routing'
|
77
|
+
candidates << 'views' if runner.options[:view]
|
69
78
|
when 'config/database.yml', 'db/schema.rb', 'spec/factories.rb'
|
70
79
|
candidates << 'models'
|
71
80
|
when 'config/boot.rb', 'config/environment.rb', %r:^config/environments/:, %r:^config/initializers/:, %r:^vendor/:, 'spec/spec_helper.rb'
|
72
|
-
|
73
|
-
Celerity.restart if runner.options[:celerity]
|
81
|
+
candidates << 'spork'
|
74
82
|
candidates << 'spec'
|
75
83
|
when %r:^config/:
|
76
84
|
# nothing
|
77
|
-
when %r:^(spec/(spec_helper|shared/.*)|config/(boot|environment(s/test)?))\.rb$:, 'spec/spec.opts', 'spec/
|
85
|
+
when %r:^(spec/(spec_helper|shared/.*)|config/(boot|environment(s/test)?))\.rb$:, 'spec/spec.opts', 'spec/fakewebs.rb'
|
78
86
|
candidates << 'spec'
|
79
87
|
else
|
80
88
|
candidates << spec_file
|
@@ -82,7 +90,7 @@ module RSpactor
|
|
82
90
|
end
|
83
91
|
|
84
92
|
candidates.map do |candidate|
|
85
|
-
if candidate == 'cucumber'
|
93
|
+
if candidate == 'cucumber' || candidate == 'spork'
|
86
94
|
candidate
|
87
95
|
elsif candidate.index('spec') == 0
|
88
96
|
File.join(root, candidate)
|
data/lib/rspactor/interactor.rb
CHANGED
@@ -10,12 +10,26 @@ module RSpactor
|
|
10
10
|
ticker
|
11
11
|
end
|
12
12
|
|
13
|
-
def self.ticker_msg(msg, seconds_to_wait = 3)
|
13
|
+
def self.ticker_msg(msg, seconds_to_wait = 3, &block)
|
14
14
|
$stdout.print msg
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
if block
|
16
|
+
@yielding_ticker = true
|
17
|
+
Thread.new do
|
18
|
+
loop do
|
19
|
+
$stdout.print('.') if @yielding_ticker == true
|
20
|
+
$stdout.flush
|
21
|
+
sleep 1.0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
yield
|
26
|
+
@yielding_ticker = false
|
27
|
+
else
|
28
|
+
seconds_to_wait.times do
|
29
|
+
$stdout.print('.')
|
30
|
+
$stdout.flush
|
31
|
+
sleep 1
|
32
|
+
end
|
19
33
|
end
|
20
34
|
$stdout.puts "\n"
|
21
35
|
end
|
@@ -46,6 +60,8 @@ module RSpactor
|
|
46
60
|
runner.run_cucumber_command
|
47
61
|
when "ca\n" # Cucumber All: ~pending tagged feature
|
48
62
|
runner.run_cucumber_command('~@wip,~@pending')
|
63
|
+
when "r\n"
|
64
|
+
runner.spork.reload if runner.spork
|
49
65
|
else
|
50
66
|
if wait_for_enter_key("** Running all specs... Hit <enter> again to exit RSpactor", 1)
|
51
67
|
@main_thread.exit
|
data/lib/rspactor/listener.rb
CHANGED
@@ -1,76 +1,38 @@
|
|
1
|
-
require '
|
2
|
-
OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
|
1
|
+
require 'fsevent'
|
3
2
|
|
4
3
|
module RSpactor
|
5
|
-
# based on http://
|
6
|
-
class Listener
|
7
|
-
attr_reader :
|
4
|
+
# based on http://github.com/sandro/beholder/commit/2ac026f8fc199b75944b8a2c1a3f80ee277dd81b
|
5
|
+
class Listener < FSEvent
|
6
|
+
attr_reader :last_event, :callback, :valid_extensions, :modified_directories
|
8
7
|
|
9
8
|
def initialize(valid_extensions = nil)
|
10
9
|
@valid_extensions = valid_extensions
|
11
|
-
|
12
|
-
|
13
|
-
@callback = lambda do |stream, ctx, num_events, paths, marks, event_ids|
|
14
|
-
changed_files = extract_changed_files_from_paths(split_paths(paths, num_events))
|
15
|
-
timestamp_checked
|
16
|
-
yield changed_files unless changed_files.empty?
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def run(directories)
|
21
|
-
dirs = Array(directories)
|
22
|
-
stream = OSX::FSEventStreamCreate(OSX::KCFAllocatorDefault, callback, nil, dirs, OSX::KFSEventStreamEventIdSinceNow, 0.5, 0)
|
23
|
-
unless stream
|
24
|
-
$stderr.puts "Failed to create stream"
|
25
|
-
exit(1)
|
26
|
-
end
|
27
|
-
|
28
|
-
OSX::FSEventStreamScheduleWithRunLoop(stream, OSX::CFRunLoopGetCurrent(), OSX::KCFRunLoopDefaultMode)
|
29
|
-
unless OSX::FSEventStreamStart(stream)
|
30
|
-
$stderr.puts "Failed to start stream"
|
31
|
-
exit(1)
|
32
|
-
end
|
33
|
-
|
34
|
-
begin
|
35
|
-
OSX::CFRunLoopRun()
|
36
|
-
rescue Interrupt
|
37
|
-
OSX::FSEventStreamStop(stream)
|
38
|
-
OSX::FSEventStreamInvalidate(stream)
|
39
|
-
OSX::FSEventStreamRelease(stream)
|
40
|
-
end
|
10
|
+
update_last_event
|
11
|
+
super()
|
41
12
|
end
|
42
13
|
|
43
|
-
def
|
44
|
-
@
|
14
|
+
def on_change(directories)
|
15
|
+
@modified_directories = directories
|
16
|
+
callback.call(modified_files)
|
17
|
+
update_last_event
|
45
18
|
end
|
46
19
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
num_events.times { |i| rpaths << paths[i] }
|
51
|
-
rpaths
|
20
|
+
def watch_directories(directories, &block)
|
21
|
+
super(directories)
|
22
|
+
@callback = block
|
52
23
|
end
|
53
24
|
|
54
|
-
def extract_changed_files_from_paths(paths)
|
55
|
-
changed_files = []
|
56
|
-
paths.each do |path|
|
57
|
-
next if ignore_path?(path)
|
58
|
-
Dir.glob(path + "*").each do |file|
|
59
|
-
next if ignore_file?(file)
|
60
|
-
changed_files << file if file_changed?(file)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
changed_files
|
64
|
-
end
|
65
25
|
|
66
|
-
def
|
67
|
-
|
68
|
-
rescue Errno::ENOENT
|
69
|
-
false
|
26
|
+
def potentially_modified_files
|
27
|
+
Dir.glob(modified_directories.map {|dir| File.join(dir, "**", "*")})
|
70
28
|
end
|
71
29
|
|
72
|
-
def
|
73
|
-
|
30
|
+
def modified_files
|
31
|
+
potentially_modified_files.select do |file|
|
32
|
+
next if File.directory?(file)
|
33
|
+
next if ignore_file?(file)
|
34
|
+
File.mtime(file) >= last_event || File.atime(file) >= last_event
|
35
|
+
end
|
74
36
|
end
|
75
37
|
|
76
38
|
def ignore_file?(file)
|
@@ -84,5 +46,10 @@ module RSpactor
|
|
84
46
|
def valid_extension?(file)
|
85
47
|
valid_extensions.nil? or valid_extensions.include?(file_extension(file))
|
86
48
|
end
|
49
|
+
|
50
|
+
def update_last_event
|
51
|
+
@last_event = Time.now
|
52
|
+
end
|
53
|
+
|
87
54
|
end
|
88
55
|
end
|
data/lib/rspactor/runner.rb
CHANGED
@@ -7,26 +7,27 @@ module RSpactor
|
|
7
7
|
new(run_in, options).start
|
8
8
|
end
|
9
9
|
|
10
|
-
attr_reader :dir, :options, :inspector, :interactor
|
10
|
+
attr_reader :dir, :options, :inspector, :interactor, :spork
|
11
11
|
|
12
12
|
def initialize(dir, options = {})
|
13
13
|
@dir = dir
|
14
14
|
@options = options
|
15
|
+
@spork = Spork.new(self) if options[:spork]
|
15
16
|
read_git_head
|
16
17
|
end
|
17
18
|
|
18
19
|
def start
|
19
20
|
load_dotfile
|
20
21
|
puts "** RSpactor, now watching at '#{dir}'"
|
21
|
-
|
22
|
-
Celerity.start(dir) if options[:celerity]
|
22
|
+
spork.start if spork?
|
23
23
|
start_interactor
|
24
24
|
start_listener
|
25
25
|
end
|
26
26
|
|
27
27
|
def start_interactor
|
28
28
|
@interactor = Interactor.new(self)
|
29
|
-
|
29
|
+
message = "** Hit <enter> to skip initial spec #{"& cucumber " if cucumber?}run"
|
30
|
+
aborted = @interactor.wait_for_enter_key(message, 2, false)
|
30
31
|
@interactor.start_termination_handler
|
31
32
|
unless aborted
|
32
33
|
run_all_specs
|
@@ -37,9 +38,12 @@ module RSpactor
|
|
37
38
|
def start_listener
|
38
39
|
@inspector = Inspector.new(self)
|
39
40
|
|
40
|
-
Listener.new(Inspector::EXTENSIONS)
|
41
|
+
@listener = Listener.new(Inspector::EXTENSIONS)
|
42
|
+
@listener.latency = 0.2
|
43
|
+
@listener.watch_directories(dir) do |files|
|
41
44
|
changed_files(files) unless git_head_changed?
|
42
|
-
end
|
45
|
+
end
|
46
|
+
@listener.start
|
43
47
|
end
|
44
48
|
|
45
49
|
def load_dotfile
|
@@ -68,21 +72,27 @@ module RSpactor
|
|
68
72
|
end
|
69
73
|
|
70
74
|
def run_cucumber_command(tags = '@wip:2', clear = @options[:clear])
|
71
|
-
return unless
|
75
|
+
return unless cucumber?
|
72
76
|
|
73
77
|
system("clear;") if clear
|
74
78
|
puts "** Running all #{tags} tagged features..."
|
75
79
|
cmd = [ruby_opts, cucumber_runner, cucumber_opts(tags)].flatten.join(' ')
|
76
80
|
@last_run_failed = run_command(cmd)
|
77
|
-
# Workaround for killing jruby process when used with celerity and spork
|
78
|
-
Celerity.kill_jruby if options[:celerity] && options[:spork]
|
79
81
|
end
|
80
82
|
|
81
83
|
def last_run_failed?
|
82
84
|
@last_run_failed == false
|
83
85
|
end
|
84
86
|
|
85
|
-
|
87
|
+
def cucumber?
|
88
|
+
@cucumber ||= File.exist?(File.join(dir, 'features'))
|
89
|
+
end
|
90
|
+
|
91
|
+
def spork?
|
92
|
+
spork != nil
|
93
|
+
end
|
94
|
+
|
95
|
+
protected
|
86
96
|
|
87
97
|
def run_command(cmd)
|
88
98
|
system(cmd)
|
@@ -116,7 +126,7 @@ module RSpactor
|
|
116
126
|
end
|
117
127
|
end
|
118
128
|
|
119
|
-
|
129
|
+
private
|
120
130
|
|
121
131
|
def spec_opts
|
122
132
|
if File.exist?('spec/spec.opts')
|
@@ -124,21 +134,16 @@ module RSpactor
|
|
124
134
|
else
|
125
135
|
opts = "--color"
|
126
136
|
end
|
127
|
-
|
137
|
+
opts << " --drb" if spork
|
128
138
|
opts << spec_formatter_opts
|
129
139
|
# only add the "progress" formatter unless no other (besides growl) is specified
|
130
140
|
opts << ' -f progress' unless opts.scan(/\s(?:-f|--format)\b/).length > 1
|
131
|
-
|
132
141
|
opts
|
133
142
|
end
|
134
143
|
|
135
144
|
def cucumber_opts(tags)
|
136
|
-
|
137
|
-
|
138
|
-
else
|
139
|
-
opts = "--color --format progress --drb --no-profile"
|
140
|
-
end
|
141
|
-
|
145
|
+
opts = "--profile rspactor"
|
146
|
+
opts << " --drb" if spork
|
142
147
|
opts << " --tags #{tags}"
|
143
148
|
opts << cucumber_formatter_opts
|
144
149
|
opts << " --require features" # because using require option overwrite default require
|
data/lib/rspactor/spork.rb
CHANGED
@@ -1,25 +1,60 @@
|
|
1
1
|
require 'rspactor'
|
2
|
+
require 'socket'
|
2
3
|
|
3
4
|
module RSpactor
|
4
5
|
class Spork
|
6
|
+
RSPEC_PORT = 8989
|
7
|
+
CUCUMBER_PORT = 8990
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
+
attr_accessor :use_cucumber
|
10
|
+
|
11
|
+
def initialize(runner)
|
12
|
+
@use_cucumber = runner.cucumber?
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
execute(:start)
|
9
17
|
end
|
10
18
|
|
11
|
-
def
|
12
|
-
|
13
|
-
Interactor.ticker_msg "** Reloading Spork for rspec & cucumber"
|
19
|
+
def reload
|
20
|
+
execute(:reload)
|
14
21
|
end
|
15
22
|
|
16
23
|
private
|
17
24
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
25
|
+
def execute(start_or_reload)
|
26
|
+
action_message = (start_or_reload == :start) ? "Starting" : "Reloading"
|
27
|
+
message = "** #{action_message} Spork for rspec"
|
28
|
+
message += " & cucumber" if use_cucumber
|
29
|
+
kill_and_launch(message)
|
22
30
|
end
|
23
31
|
|
32
|
+
def kill_and_launch(message)
|
33
|
+
Interactor.ticker_msg message do
|
34
|
+
|
35
|
+
system("kill $(ps aux | awk '/spork/&&!/awk/{print $2;}') >/dev/null 2>&1")
|
36
|
+
|
37
|
+
system("spork >/dev/null 2>&1 < /dev/null &")
|
38
|
+
wait_for('RSpec', RSPEC_PORT)
|
39
|
+
|
40
|
+
if use_cucumber
|
41
|
+
system("spork cu >/dev/null 2>&1 < /dev/null &")
|
42
|
+
wait_for('Cucumber', CUCUMBER_PORT)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def wait_for(sporker, port)
|
48
|
+
15.times do
|
49
|
+
begin
|
50
|
+
TCPSocket.new('localhost', port).close
|
51
|
+
rescue Errno::ECONNREFUSED
|
52
|
+
sleep(1)
|
53
|
+
next
|
54
|
+
end
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
raise "could not load spork for #{sporker}; make sure you can use it manually first"
|
58
|
+
end
|
24
59
|
end
|
25
|
-
end
|
60
|
+
end
|
data/lib/rspactor.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
2
|
-
|
3
1
|
module RSpactor
|
4
2
|
autoload :Interactor, 'rspactor/interactor'
|
5
3
|
autoload :Listener, 'rspactor/listener'
|
@@ -7,5 +5,4 @@ module RSpactor
|
|
7
5
|
autoload :Runner, 'rspactor/runner'
|
8
6
|
autoload :Growl, 'rspactor/growl'
|
9
7
|
autoload :Spork, 'rspactor/spork'
|
10
|
-
autoload :Celerity, 'rspactor/celerity'
|
11
8
|
end
|
data/rspactor.gemspec
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{rspactor}
|
8
|
+
s.version = "0.6.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Mislav Marohni\304\207", "Andreas Wolff", "Pelle Braendgaard", "Thibaud Guillaume-Gentil"]
|
12
|
+
s.date = %q{2010-01-31}
|
13
|
+
s.default_executable = %q{rspactor}
|
14
|
+
s.description = %q{RSpactor is a command line tool to automatically run your changed specs & cucumber features (much like autotest).}
|
15
|
+
s.email = %q{thibaud@thibaud.me}
|
16
|
+
s.executables = ["rspactor"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".gitignore",
|
23
|
+
".rspactor",
|
24
|
+
"LICENSE",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/rspactor",
|
29
|
+
"images/failed.png",
|
30
|
+
"images/pending.png",
|
31
|
+
"images/success.png",
|
32
|
+
"lib/cucumber_growler.rb",
|
33
|
+
"lib/rspactor.rb",
|
34
|
+
"lib/rspactor/growl.rb",
|
35
|
+
"lib/rspactor/inspector.rb",
|
36
|
+
"lib/rspactor/interactor.rb",
|
37
|
+
"lib/rspactor/listener.rb",
|
38
|
+
"lib/rspactor/runner.rb",
|
39
|
+
"lib/rspactor/spork.rb",
|
40
|
+
"lib/rspec_growler.rb",
|
41
|
+
"rspactor.gemspec",
|
42
|
+
"spec/inspector_spec.rb",
|
43
|
+
"spec/listener_spec.rb",
|
44
|
+
"spec/runner_spec.rb"
|
45
|
+
]
|
46
|
+
s.homepage = %q{http://github.com/thibaudgg/rspactor}
|
47
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
48
|
+
s.require_paths = ["lib"]
|
49
|
+
s.rubygems_version = %q{1.3.5}
|
50
|
+
s.summary = %q{RSpactor is a command line tool to automatically run your changed specs & cucumber features.}
|
51
|
+
s.test_files = [
|
52
|
+
"spec/inspector_spec.rb",
|
53
|
+
"spec/listener_spec.rb",
|
54
|
+
"spec/runner_spec.rb"
|
55
|
+
]
|
56
|
+
|
57
|
+
if s.respond_to? :specification_version then
|
58
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
59
|
+
s.specification_version = 3
|
60
|
+
|
61
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
62
|
+
s.add_runtime_dependency(%q<ruby-fsevent>, [">= 0.2.1"])
|
63
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<ruby-fsevent>, [">= 0.2.1"])
|
66
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
67
|
+
end
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<ruby-fsevent>, [">= 0.2.1"])
|
70
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
data/spec/inspector_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'rspactor/inspector'
|
|
2
2
|
|
3
3
|
describe RSpactor::Inspector do
|
4
4
|
before(:all) do
|
5
|
-
options = { :view => true }
|
5
|
+
options = { :view => true, :spork? => false }
|
6
6
|
@inspector = described_class.new(mock('Runner', :dir => '/project', :options => options))
|
7
7
|
end
|
8
8
|
|
@@ -54,7 +54,7 @@ describe RSpactor::Inspector do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
it "should consider all controllers, helpers and views when routes.rb changes" do
|
57
|
-
translate('config/routes.rb').should == ['/project/spec/controllers', '/project/spec/helpers', '/project/spec/
|
57
|
+
translate('config/routes.rb').should == ['/project/spec/controllers', '/project/spec/helpers', '/project/spec/routing', '/project/spec/views']
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should consider all models when config/database.yml changes" do
|
@@ -74,7 +74,7 @@ describe RSpactor::Inspector do
|
|
74
74
|
end
|
75
75
|
|
76
76
|
it "should consider all specs when spec_helper changes" do
|
77
|
-
translate('spec/spec_helper.rb').should == ['/project/spec']
|
77
|
+
translate('spec/spec_helper.rb').should == ['spork', '/project/spec']
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should consider all specs when code under spec/shared/ changes" do
|
@@ -82,15 +82,15 @@ describe RSpactor::Inspector do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
it "should consider all specs when app configuration changes" do
|
85
|
-
translate('config/environment.rb').should == ['/project/spec']
|
86
|
-
translate('config/environments/test.rb').should == ['/project/spec']
|
87
|
-
translate('config/boot.rb').should == ['/project/spec']
|
85
|
+
translate('config/environment.rb').should == ['spork', '/project/spec']
|
86
|
+
translate('config/environments/test.rb').should == ['spork', '/project/spec']
|
87
|
+
translate('config/boot.rb').should == ['spork', '/project/spec']
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should consider cucumber when a features file change" do
|
91
91
|
translate('features/login.feature').should == ['cucumber']
|
92
92
|
translate('features/steps/webrat_steps.rb').should == ['cucumber']
|
93
|
-
translate('features/support/env.rb').should == ['cucumber']
|
93
|
+
translate('features/support/env.rb').should == ['cucumber', 'spork']
|
94
94
|
end
|
95
95
|
|
96
96
|
end
|
data/spec/listener_spec.rb
CHANGED
@@ -6,15 +6,7 @@ describe RSpactor::Listener do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should be timestamped" do
|
9
|
-
@listener.
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should not ignore regular directories" do
|
13
|
-
@listener.ignore_path?('/project/foo/bar').should_not be
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should ignore .git directories" do
|
17
|
-
@listener.ignore_path?('/project/.git/index').should be
|
9
|
+
@listener.last_event.should be_instance_of(Time)
|
18
10
|
end
|
19
11
|
|
20
12
|
it "should ignore dotfiles" do
|
data/spec/runner_spec.rb
CHANGED
@@ -110,7 +110,9 @@ describe RSpactor::Runner do
|
|
110
110
|
end
|
111
111
|
|
112
112
|
it "should run Listener" do
|
113
|
-
@listener.should_receive(:
|
113
|
+
@listener.should_receive(:start)
|
114
|
+
@listener.should_receive(:latency=).with(0.2)
|
115
|
+
@listener.should_receive(:watch_directories).with('/my/path')
|
114
116
|
RSpactor::Listener.should_receive(:new).with(instance_of(Array)).and_return(@listener)
|
115
117
|
setup
|
116
118
|
end
|
metadata
CHANGED
@@ -1,56 +1,80 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspactor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Andreas Wolff
|
8
7
|
- "Mislav Marohni\xC4\x87"
|
8
|
+
- Andreas Wolff
|
9
9
|
- Pelle Braendgaard
|
10
10
|
- Thibaud Guillaume-Gentil
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date:
|
15
|
+
date: 2010-01-31 00:00:00 +01:00
|
16
16
|
default_executable: rspactor
|
17
|
-
dependencies:
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
dependencies:
|
18
|
+
- !ruby/object:Gem::Dependency
|
19
|
+
name: ruby-fsevent
|
20
|
+
type: :runtime
|
21
|
+
version_requirement:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.2.1
|
27
|
+
version:
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rspec
|
30
|
+
type: :development
|
31
|
+
version_requirement:
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.2.9
|
37
|
+
version:
|
38
|
+
description: RSpactor is a command line tool to automatically run your changed specs & cucumber features (much like autotest).
|
39
|
+
email: thibaud@thibaud.me
|
21
40
|
executables:
|
22
41
|
- rspactor
|
23
42
|
extensions: []
|
24
43
|
|
25
|
-
extra_rdoc_files:
|
26
|
-
|
44
|
+
extra_rdoc_files:
|
45
|
+
- LICENSE
|
46
|
+
- README.rdoc
|
27
47
|
files:
|
48
|
+
- .gitignore
|
49
|
+
- .rspactor
|
50
|
+
- LICENSE
|
51
|
+
- README.rdoc
|
28
52
|
- Rakefile
|
53
|
+
- VERSION
|
29
54
|
- bin/rspactor
|
55
|
+
- images/failed.png
|
56
|
+
- images/pending.png
|
57
|
+
- images/success.png
|
30
58
|
- lib/cucumber_growler.rb
|
31
|
-
- lib/rspactor
|
59
|
+
- lib/rspactor.rb
|
32
60
|
- lib/rspactor/growl.rb
|
33
61
|
- lib/rspactor/inspector.rb
|
34
62
|
- lib/rspactor/interactor.rb
|
35
63
|
- lib/rspactor/listener.rb
|
36
64
|
- lib/rspactor/runner.rb
|
37
65
|
- lib/rspactor/spork.rb
|
38
|
-
- lib/rspactor.rb
|
39
66
|
- lib/rspec_growler.rb
|
40
|
-
-
|
41
|
-
- images/pending.png
|
42
|
-
- images/success.png
|
67
|
+
- rspactor.gemspec
|
43
68
|
- spec/inspector_spec.rb
|
44
69
|
- spec/listener_spec.rb
|
45
70
|
- spec/runner_spec.rb
|
46
|
-
- LICENSE
|
47
71
|
has_rdoc: true
|
48
|
-
homepage: http://github.com/
|
72
|
+
homepage: http://github.com/thibaudgg/rspactor
|
49
73
|
licenses: []
|
50
74
|
|
51
75
|
post_install_message:
|
52
|
-
rdoc_options:
|
53
|
-
|
76
|
+
rdoc_options:
|
77
|
+
- --charset=UTF-8
|
54
78
|
require_paths:
|
55
79
|
- lib
|
56
80
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -71,6 +95,8 @@ rubyforge_project:
|
|
71
95
|
rubygems_version: 1.3.5
|
72
96
|
signing_key:
|
73
97
|
specification_version: 3
|
74
|
-
summary: RSpactor is a command line tool to automatically run your changed specs & cucumber features
|
75
|
-
test_files:
|
76
|
-
|
98
|
+
summary: RSpactor is a command line tool to automatically run your changed specs & cucumber features.
|
99
|
+
test_files:
|
100
|
+
- spec/inspector_spec.rb
|
101
|
+
- spec/listener_spec.rb
|
102
|
+
- spec/runner_spec.rb
|
data/lib/rspactor/celerity.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'rspactor'
|
2
|
-
|
3
|
-
module RSpactor
|
4
|
-
class Celerity
|
5
|
-
|
6
|
-
def self.start(dir)
|
7
|
-
pid_path = "#{dir}/tmp/pids/mongrel_celerity.pid"
|
8
|
-
if File.exist?(pid_path)
|
9
|
-
system("kill $(head #{pid_path}) >/dev/null 2>&1")
|
10
|
-
system("rm #{pid_path} >/dev/null 2>&1")
|
11
|
-
end
|
12
|
-
# kill other mongrels
|
13
|
-
system("kill $(ps aux | grep 'mongrel_rails' | grep -v grep | awk '//{print $2;}') >/dev/null 2>&1")
|
14
|
-
system("rake celerity_server:start >/dev/null 2>&1 &")
|
15
|
-
Interactor.ticker_msg "** Starting celerity server"
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.restart
|
19
|
-
system("rake celerity_server:stop >/dev/null 2>&1 && rake celerity_server:start >/dev/null 2>&1 &")
|
20
|
-
Interactor.ticker_msg "** Restarting celerity server"
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.kill_jruby
|
24
|
-
system("kill $(ps aux | grep jruby | grep -v grep | awk '//{print $2;}') >/dev/null 2>&1")
|
25
|
-
true
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|