rspactor 0.5.4 → 0.6.2
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/.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
|