specjour 0.7.0 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/History.markdown +12 -0
  3. data/README.markdown +24 -1
  4. data/Rakefile +12 -12
  5. data/bin/specjour +3 -1
  6. data/lib/specjour/cli.rb +86 -110
  7. data/lib/specjour/colors.rb +23 -0
  8. data/lib/specjour/configuration.rb +47 -91
  9. data/lib/specjour/connection.rb +69 -20
  10. data/lib/specjour/cpu.rb +4 -0
  11. data/lib/specjour/fork.rb +1 -1
  12. data/lib/specjour/formatter.rb +153 -0
  13. data/lib/specjour/listener.rb +181 -0
  14. data/lib/specjour/loader.rb +55 -119
  15. data/lib/specjour/logger.rb +34 -0
  16. data/lib/specjour/plugin/base.rb +61 -0
  17. data/lib/specjour/plugin/manager.rb +28 -0
  18. data/lib/specjour/plugin/rails.rb +47 -0
  19. data/lib/specjour/plugin/rails_v3.rb +23 -0
  20. data/lib/specjour/plugin/rails_v4.rb +25 -0
  21. data/lib/specjour/plugin/rspec.rb +160 -0
  22. data/lib/specjour/plugin/rspec_v2.rb +53 -0
  23. data/lib/specjour/plugin/rspec_v3.rb +59 -0
  24. data/lib/specjour/plugin/ssh.rb +24 -0
  25. data/lib/specjour/plugin.rb +4 -0
  26. data/lib/specjour/printer.rb +235 -67
  27. data/lib/specjour/protocol.rb +13 -6
  28. data/lib/specjour/rspec_formatter.rb +17 -0
  29. data/lib/specjour/rsync_daemon.rb +6 -3
  30. data/lib/specjour/socket_helper.rb +26 -10
  31. data/lib/specjour/worker.rb +36 -62
  32. data/lib/specjour.rb +50 -24
  33. data/lib/specjour_plugin.rb +5 -0
  34. metadata +52 -84
  35. data/lib/specjour/cucumber/distributed_formatter.rb +0 -82
  36. data/lib/specjour/cucumber/final_report.rb +0 -83
  37. data/lib/specjour/cucumber/preloader.rb +0 -22
  38. data/lib/specjour/cucumber/runner.rb +0 -15
  39. data/lib/specjour/cucumber.rb +0 -16
  40. data/lib/specjour/db_scrub.rb +0 -56
  41. data/lib/specjour/dispatcher.rb +0 -170
  42. data/lib/specjour/manager.rb +0 -174
  43. data/lib/specjour/rspec/distributed_formatter.rb +0 -50
  44. data/lib/specjour/rspec/final_report.rb +0 -73
  45. data/lib/specjour/rspec/marshalable_exception.rb +0 -19
  46. data/lib/specjour/rspec/preloader.rb +0 -15
  47. data/lib/specjour/rspec/runner.rb +0 -14
  48. data/lib/specjour/rspec/shared_example_group_ext.rb +0 -9
  49. 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
@@ -0,0 +1,4 @@
1
+ module Specjour::Plugin
2
+ autoload :Manager, "specjour/plugin/manager"
3
+ autoload :Base, "specjour/plugin/base"
4
+ end