specjour 0.7.0 → 2.0.0.rc1
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.
- checksums.yaml +7 -0
- data/History.markdown +12 -0
- data/README.markdown +24 -1
- data/Rakefile +12 -12
- data/bin/specjour +3 -1
- data/lib/specjour/cli.rb +86 -110
- data/lib/specjour/colors.rb +23 -0
- data/lib/specjour/configuration.rb +47 -91
- data/lib/specjour/connection.rb +69 -20
- data/lib/specjour/cpu.rb +4 -0
- data/lib/specjour/fork.rb +1 -1
- data/lib/specjour/formatter.rb +153 -0
- data/lib/specjour/listener.rb +181 -0
- data/lib/specjour/loader.rb +55 -119
- data/lib/specjour/logger.rb +34 -0
- data/lib/specjour/plugin/base.rb +61 -0
- data/lib/specjour/plugin/manager.rb +28 -0
- data/lib/specjour/plugin/rails.rb +47 -0
- data/lib/specjour/plugin/rails_v3.rb +23 -0
- data/lib/specjour/plugin/rails_v4.rb +25 -0
- data/lib/specjour/plugin/rspec.rb +160 -0
- data/lib/specjour/plugin/rspec_v2.rb +53 -0
- data/lib/specjour/plugin/rspec_v3.rb +59 -0
- data/lib/specjour/plugin/ssh.rb +24 -0
- data/lib/specjour/plugin.rb +4 -0
- data/lib/specjour/printer.rb +235 -67
- data/lib/specjour/protocol.rb +13 -6
- data/lib/specjour/rspec_formatter.rb +17 -0
- data/lib/specjour/rsync_daemon.rb +6 -3
- data/lib/specjour/socket_helper.rb +26 -10
- data/lib/specjour/worker.rb +36 -62
- data/lib/specjour.rb +50 -24
- data/lib/specjour_plugin.rb +5 -0
- metadata +52 -84
- data/lib/specjour/cucumber/distributed_formatter.rb +0 -82
- data/lib/specjour/cucumber/final_report.rb +0 -83
- data/lib/specjour/cucumber/preloader.rb +0 -22
- data/lib/specjour/cucumber/runner.rb +0 -15
- data/lib/specjour/cucumber.rb +0 -16
- data/lib/specjour/db_scrub.rb +0 -56
- data/lib/specjour/dispatcher.rb +0 -170
- data/lib/specjour/manager.rb +0 -174
- data/lib/specjour/rspec/distributed_formatter.rb +0 -50
- data/lib/specjour/rspec/final_report.rb +0 -73
- data/lib/specjour/rspec/marshalable_exception.rb +0 -19
- data/lib/specjour/rspec/preloader.rb +0 -15
- data/lib/specjour/rspec/runner.rb +0 -14
- data/lib/specjour/rspec/shared_example_group_ext.rb +0 -9
- data/lib/specjour/rspec.rb +0 -17
@@ -0,0 +1,47 @@
|
|
1
|
+
module Specjour::Plugin
|
2
|
+
|
3
|
+
class Rails < Base
|
4
|
+
|
5
|
+
def load_application
|
6
|
+
log "Loading rails plugin"
|
7
|
+
if File.exists?("./config/application.rb")
|
8
|
+
bundle_install
|
9
|
+
ENV["RAILS_ENV"] ||= "test"
|
10
|
+
require File.expand_path("config/application", Dir.pwd)
|
11
|
+
# require File.expand_path("config/environment", Dir.pwd)
|
12
|
+
@rails_loaded = true
|
13
|
+
Specjour.load_plugins
|
14
|
+
if ::Rails.version =~ /^4/
|
15
|
+
require "specjour/plugin/rails_v4.rb"
|
16
|
+
extend RailsV4
|
17
|
+
else
|
18
|
+
require "specjour/plugin/rails_v3.rb"
|
19
|
+
extend RailsV3
|
20
|
+
end
|
21
|
+
versioned_load_application
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def before_worker_fork
|
26
|
+
return unless @rails_loaded
|
27
|
+
ActiveRecord::Base.remove_connection
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def force_task(task)
|
33
|
+
Rake::Task[task].invoke
|
34
|
+
rescue StandardError
|
35
|
+
end
|
36
|
+
|
37
|
+
def bundle_install
|
38
|
+
if system('which bundle')
|
39
|
+
system('bundle check') || system('bundle install')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def system(cmd)
|
44
|
+
Kernel.system("#{cmd} > /dev/null")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Specjour
|
2
|
+
module Plugin
|
3
|
+
module RailsV3
|
4
|
+
|
5
|
+
def versioned_load_application
|
6
|
+
load "active_record/railties/databases.rake"
|
7
|
+
Rake::Task.define_task(:environment) unless Rake::Task.task_defined?(:environment)
|
8
|
+
Rake::Task.define_task(:rails_env) unless Rake::Task.task_defined?(:rails_env)
|
9
|
+
end
|
10
|
+
|
11
|
+
def after_worker_fork
|
12
|
+
return unless (defined?(::Rails) && defined?(::ActiveRecord::Base))
|
13
|
+
force_task('db:drop')
|
14
|
+
force_task('db:create')
|
15
|
+
Rake::Task[{ :sql => "db:test:load_structure", :ruby => "db:test:load" }[ActiveRecord::Base.schema_format]].invoke
|
16
|
+
ActiveRecord::Base.establish_connection
|
17
|
+
ActiveRecord::Base.connection.schema_cache.clear!
|
18
|
+
ActiveRecord::Base.descendants.each {|m| m.reset_column_information}
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Specjour
|
2
|
+
module Plugin
|
3
|
+
module RailsV4
|
4
|
+
|
5
|
+
def versioned_load_application
|
6
|
+
# require File.expand_path("config/environment", Dir.pwd)
|
7
|
+
load "active_record/railties/databases.rake"
|
8
|
+
ActiveRecord::Tasks::DatabaseTasks.database_configuration = ::Rails.application.config.database_configuration
|
9
|
+
require "rails/tasks"
|
10
|
+
end
|
11
|
+
|
12
|
+
def after_worker_fork
|
13
|
+
return unless (defined?(::Rails) && defined?(::ActiveRecord::Base))
|
14
|
+
ActiveRecord::Tasks::DatabaseTasks.database_configuration = ::Rails.application.config.database_configuration
|
15
|
+
ActiveRecord::Base.establish_connection
|
16
|
+
force_task('db:drop')
|
17
|
+
force_task('db:create')
|
18
|
+
Rake::Task[{ :sql => "db:structure:load", :ruby => "db:schema:load" }[ActiveRecord::Base.schema_format]].invoke
|
19
|
+
ActiveRecord::Base.connection.schema_cache.clear!
|
20
|
+
ActiveRecord::Base.descendants.each {|m| m.reset_column_information}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module Specjour
|
2
|
+
module Plugin
|
3
|
+
class RSpec < Base
|
4
|
+
|
5
|
+
|
6
|
+
FILE_RE = /_spec\.rb/
|
7
|
+
|
8
|
+
Specjour::Configuration.make_option(:rspec_rerun)
|
9
|
+
Specjour.configuration.rspec_rerun = true
|
10
|
+
|
11
|
+
attr_reader :rerunner
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@all_specs = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def interrupted!
|
18
|
+
if defined?(::RSpec)
|
19
|
+
::RSpec.world.wants_to_quit = true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_application
|
24
|
+
log "application loading from RSpec plugin #{Dir.pwd}"
|
25
|
+
require "rspec/core"
|
26
|
+
|
27
|
+
::RSpec::Core::Runner.disable_autorun!
|
28
|
+
@output = connection
|
29
|
+
::RSpec.configuration.error_stream = $stderr
|
30
|
+
::RSpec.configuration.output_stream = @output
|
31
|
+
|
32
|
+
if ::RSpec::Core::Version::STRING =~ /^3\./
|
33
|
+
require "specjour/plugin/rspec_v3"
|
34
|
+
extend Specjour::Plugin::RSpecV3
|
35
|
+
else
|
36
|
+
require "specjour/plugin/rspec_v2"
|
37
|
+
extend Specjour::Plugin::RSpecV2
|
38
|
+
end
|
39
|
+
|
40
|
+
versioned_load_application
|
41
|
+
end
|
42
|
+
|
43
|
+
def register_tests_with_printer
|
44
|
+
connection.register_tests rspec_examples
|
45
|
+
end
|
46
|
+
|
47
|
+
def run_test(test)
|
48
|
+
run(test) if FILE_RE === test
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
def after_print_summary(formatter)
|
53
|
+
if formatter.failures.any? && !Specjour.interrupted?
|
54
|
+
@rerunner = ReRunner.new(formatter)
|
55
|
+
rerunner.start
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def exit_status(formatter)
|
60
|
+
if formatter.failures.any?
|
61
|
+
rerunner.exit_status
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
|
67
|
+
def find_example(all_examples)
|
68
|
+
::RSpec.configuration.filter_manager.prune all_examples
|
69
|
+
end
|
70
|
+
|
71
|
+
def rspec_examples
|
72
|
+
if spec_files.any?
|
73
|
+
file_names_with_location
|
74
|
+
else
|
75
|
+
[]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def spec_files
|
80
|
+
return @spec_files if instance_variable_defined?(:@spec_files)
|
81
|
+
if Specjour.configuration.test_paths.empty?
|
82
|
+
@spec_files = Dir["spec/**/*_spec.rb"]
|
83
|
+
else
|
84
|
+
@spec_files = Specjour.configuration.test_paths.map do |test_path|
|
85
|
+
if File.basename(test_path) != Specjour.configuration.project_path
|
86
|
+
if File.directory?(test_path)
|
87
|
+
Dir["#{test_path}/**/*_spec.rb"]
|
88
|
+
else
|
89
|
+
test_path
|
90
|
+
end
|
91
|
+
# Dir[test_path, "#{test_path}/**/*_spec.rb"]
|
92
|
+
end
|
93
|
+
end.flatten.compact.uniq
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def file_names_with_location
|
98
|
+
executables = gather_groups(::RSpec.world.example_groups)
|
99
|
+
locations = executables.map do |e|
|
100
|
+
if e.respond_to?(:examples)
|
101
|
+
e.metadata[:example_group][:location]
|
102
|
+
else
|
103
|
+
if e.example_group.metadata[:shared_group_name]
|
104
|
+
e.metadata[:example_group][:location]
|
105
|
+
else
|
106
|
+
e.metadata[:location]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
locations.map.with_index do |location, i|
|
111
|
+
@all_specs[location] ||= []
|
112
|
+
executable = executables[i]
|
113
|
+
@all_specs[location] << executable
|
114
|
+
end
|
115
|
+
locations
|
116
|
+
end
|
117
|
+
|
118
|
+
class ReRunner
|
119
|
+
|
120
|
+
include Colors
|
121
|
+
|
122
|
+
attr_reader :formatter, :exit_status
|
123
|
+
|
124
|
+
def initialize(formatter)
|
125
|
+
@formatter = formatter
|
126
|
+
@exit_status = false
|
127
|
+
end
|
128
|
+
|
129
|
+
def start
|
130
|
+
if Specjour.configuration.rspec_rerun
|
131
|
+
rerun
|
132
|
+
else
|
133
|
+
print_rerun
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def rerun
|
138
|
+
command = "rake db:test:prepare && #{rerun_command}"
|
139
|
+
output.puts("Rerunning failing tests with following command:\n#{command}")
|
140
|
+
@exit_status = system(command)
|
141
|
+
end
|
142
|
+
|
143
|
+
def print_rerun
|
144
|
+
cmd = colorize(rerun_command, :red)
|
145
|
+
output.puts "Rerun failures with this command:\n\n#{cmd}"
|
146
|
+
end
|
147
|
+
|
148
|
+
def rerun_command
|
149
|
+
"rspec #{formatter.failing_test_paths.select {|t| RSpec::FILE_RE === t}.join(" ")}"
|
150
|
+
end
|
151
|
+
|
152
|
+
def output
|
153
|
+
formatter.output
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Specjour
|
2
|
+
module Plugin
|
3
|
+
module RSpecV2
|
4
|
+
|
5
|
+
def versioned_load_application
|
6
|
+
@configuration_options = ::RSpec::Core::ConfigurationOptions.new([spec_files])
|
7
|
+
@configuration_options.parse_options
|
8
|
+
@configuration_options.configure ::RSpec.configuration
|
9
|
+
::RSpec.configuration.load_spec_files
|
10
|
+
end
|
11
|
+
|
12
|
+
def before_suite
|
13
|
+
::RSpec.configuration.run_hook(:before, :suite)
|
14
|
+
end
|
15
|
+
|
16
|
+
def after_suite
|
17
|
+
::RSpec.configuration.run_hook(:after, :suite)
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(test)
|
21
|
+
::RSpec.configuration.reset
|
22
|
+
::RSpec.configuration.add_formatter(Specjour::RspecFormatter)
|
23
|
+
::RSpec.configuration.reporter.report(1, nil) do |reporter|
|
24
|
+
examples_or_groups = @all_specs[test]
|
25
|
+
examples_or_groups.each do |example_or_group|
|
26
|
+
if example_or_group.respond_to?(:example_group)
|
27
|
+
example = example_or_group
|
28
|
+
instance = example.example_group.new
|
29
|
+
example.run instance, reporter
|
30
|
+
else
|
31
|
+
example_or_group.run(reporter)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# recursively gather groups containing a before(:all) hook, and examples
|
38
|
+
def gather_groups(groups)
|
39
|
+
groups.map do |g|
|
40
|
+
before_all_hooks = g.send(:find_hook, :before, :all, nil, nil)
|
41
|
+
if g.metadata.has_key?(:shared_group_name)
|
42
|
+
g
|
43
|
+
elsif before_all_hooks.any?
|
44
|
+
g
|
45
|
+
else
|
46
|
+
(g.filtered_examples || []) + gather_groups(g.children)
|
47
|
+
end
|
48
|
+
end.compact.flatten
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Specjour
|
2
|
+
module Plugin
|
3
|
+
module RSpecV3
|
4
|
+
|
5
|
+
::RSpec::Core::Formatters.register Specjour::RspecFormatter, :message, :dump_summary, :dump_profile, :stop, :close
|
6
|
+
|
7
|
+
def versioned_load_application
|
8
|
+
# require File.expand_path("spec/rails_helper", Dir.pwd)
|
9
|
+
@configuration_options = ::RSpec::Core::ConfigurationOptions.new([spec_files])
|
10
|
+
@configuration_options.configure ::RSpec.configuration
|
11
|
+
::RSpec.configuration.load_spec_files
|
12
|
+
end
|
13
|
+
|
14
|
+
def before_suite
|
15
|
+
::RSpec.configuration.instance_eval do
|
16
|
+
run_hooks_with(@before_suite_hooks, ::RSpec::Core::SuiteHookContext.new)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def after_suite
|
21
|
+
::RSpec.configuration.instance_eval do
|
22
|
+
run_hooks_with(@after_suite_hooks, ::RSpec::Core::SuiteHookContext.new)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def run(test)
|
27
|
+
::RSpec.configuration.reset
|
28
|
+
::RSpec.configuration.default_formatter = Specjour::RspecFormatter
|
29
|
+
::RSpec.configuration.reporter.report(1) do |reporter|
|
30
|
+
examples_or_groups = @all_specs[test]
|
31
|
+
examples_or_groups.each do |example_or_group|
|
32
|
+
if example_or_group.respond_to?(:example_group_instance)
|
33
|
+
example = example_or_group
|
34
|
+
instance = example.example_group.new
|
35
|
+
example.run instance, reporter
|
36
|
+
else
|
37
|
+
example_or_group.run(reporter)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# recursively gather groups containing a before(:all) hook, and examples
|
44
|
+
def gather_groups(groups)
|
45
|
+
groups.map do |g|
|
46
|
+
before_all_hooks = g.hooks.send(:matching_hooks_for, :before, :all, g)
|
47
|
+
if g.metadata.has_key?(:shared_group_name)
|
48
|
+
g
|
49
|
+
elsif before_all_hooks.any?
|
50
|
+
g
|
51
|
+
else
|
52
|
+
(g.filtered_examples || []) + gather_groups(g.children)
|
53
|
+
end
|
54
|
+
end.compact.flatten
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Specjour
|
2
|
+
module Plugin
|
3
|
+
class SSH < Base
|
4
|
+
def initialize
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
def after_loader_fork
|
9
|
+
# hosts.each do |host|
|
10
|
+
# host.connect
|
11
|
+
# host.rsync
|
12
|
+
# host.load_plugins
|
13
|
+
# host.load_application
|
14
|
+
# host.launch_workers
|
15
|
+
# host.proxy_tests!
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# ssh host specjour launch an ssh loader
|
19
|
+
# specjour loader -h localhost:2000
|
20
|
+
#
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|