specjour 0.1.18 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.markdown ADDED
@@ -0,0 +1,8 @@
1
+ History
2
+ =======
3
+
4
+ 0.2.0
5
+ -----
6
+ *2010-04-20*
7
+
8
+ * [added] Cucumber support. `rake specjour:cucumber`
data/README.markdown CHANGED
@@ -31,6 +31,11 @@ Run the rake task to distribute the specs among the managers you started.
31
31
 
32
32
  $ rake specjour
33
33
 
34
+ ## Distribute the features
35
+ Run the rake task to distribute the features among the managers you started.
36
+
37
+ $ rake specjour:cucumber
38
+
34
39
  ## Rails
35
40
  Edit your config/environment.rb
36
41
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.18
1
+ 0.2.0
data/bin/specjour CHANGED
@@ -2,12 +2,12 @@
2
2
  require 'optparse'
3
3
  require 'specjour'
4
4
 
5
- options = {:worker_size => 1, :batch_size => 1}
5
+ options = {:batch_size => 1}
6
6
 
7
7
  optparse = OptionParser.new do |opts|
8
8
  opts.banner = "Usage: specjour [options]"
9
9
 
10
- opts.on('-w', '--workers WORKERS', Numeric, "Number of WORKERS to spin up, defaults to #{options[:worker_size]}") do |n|
10
+ opts.on('-w', '--workers WORKERS', Numeric, "Number of WORKERS to spin up, defaults to available cores") do |n|
11
11
  options[:worker_size] = n
12
12
  end
13
13
 
@@ -46,5 +46,6 @@ if options[:worker_args]
46
46
  options[:worker_args] << options[:batch_size]
47
47
  Specjour::Worker.new(*options[:worker_args]).run
48
48
  else
49
+ options[:worker_size] ||= Specjour::CPU.cores
49
50
  Specjour::Manager.new(options).start
50
51
  end
@@ -6,7 +6,7 @@ module Specjour
6
6
  attr_reader :uri
7
7
  attr_writer :socket
8
8
 
9
- def_delegators :socket, :flush, :closed?, :close, :gets, :each
9
+ def_delegators :socket, :flush, :closed?, :gets, :each
10
10
 
11
11
  def self.wrap(established_connection)
12
12
  host, port = established_connection.peeraddr.values_at(3,1)
@@ -19,16 +19,22 @@ module Specjour
19
19
  @uri = uri
20
20
  end
21
21
 
22
+ alias to_str to_s
23
+
22
24
  def connect
23
25
  timeout { connect_socket }
24
26
  end
25
27
 
28
+ def disconnect
29
+ socket.close
30
+ end
31
+
26
32
  def socket
27
33
  @socket ||= connect
28
34
  end
29
35
 
30
36
  def timeout(&block)
31
- Timeout.timeout(5, &block)
37
+ Timeout.timeout(2, &block)
32
38
  rescue Timeout::Error
33
39
  raise Error, "Connection to dispatcher timed out"
34
40
  end
@@ -0,0 +1,13 @@
1
+ module Specjour
2
+ module CPU
3
+ # inspired by github.com/grosser/parallel
4
+ def self.cores
5
+ case RUBY_PLATFORM
6
+ when /darwin/
7
+ `hwprefs cpu_count`.to_i
8
+ when /linux/
9
+ `grep --count processor /proc/cpuinfo`.to_i
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ module Specjour
2
+ module Cucumber
3
+ class Dispatcher < ::Specjour::Dispatcher
4
+
5
+ protected
6
+
7
+ def all_specs
8
+ @all_specs ||= Dir.chdir(project_path) do
9
+ Dir["features/**/*.feature"]
10
+ end
11
+ end
12
+
13
+ def printer
14
+ @printer ||= Printer.start(all_specs)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,55 @@
1
+ module Specjour::Cucumber
2
+ class DistributedFormatter < ::Cucumber::Formatter::Progress
3
+ class << self
4
+ attr_accessor :batch_size
5
+ end
6
+ @batch_size = 1
7
+
8
+ def initialize(step_mother, io, options)
9
+ @step_mother = step_mother
10
+ @io = io
11
+ @options = options
12
+ @failing_scenarios = []
13
+ end
14
+
15
+ def after_features(features)
16
+ print_summary
17
+ step_mother.scenarios.clear
18
+ step_mother.steps.clear
19
+ end
20
+
21
+ def prepare_failures
22
+ @failures = step_mother.scenarios(:failed).select { |s| s.is_a?(Cucumber::Ast::Scenario) }
23
+
24
+ if !@failures.empty?
25
+ @failures.each do |failure|
26
+ failure_message = ''
27
+ failure_message += format_string("cucumber " + failure.file_colon_line, :failed) +
28
+ failure_message += format_string(" # Scenario: " + failure.name, :comment)
29
+ @failing_scenarios << failure_message
30
+ end
31
+ end
32
+ end
33
+
34
+ def print_summary
35
+ prepare_failures
36
+
37
+ @io.send_message(:worker_summary=, to_hash)
38
+ end
39
+
40
+ OUTCOMES = [:failed, :skipped, :undefined, :pending, :passed]
41
+
42
+ def to_hash
43
+ hash = {}
44
+ [:scenarios, :steps].each do |type|
45
+ hash[type] = {}
46
+ OUTCOMES.each do |outcome|
47
+ hash[type][outcome] = step_mother.send(type, outcome).size
48
+ end
49
+ end
50
+ hash.merge!(:failing_scenarios => @failing_scenarios)
51
+ hash
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,73 @@
1
+ module Specjour
2
+ module Cucumber
3
+ class Summarizer
4
+ attr_reader :duration, :failing_scenarios
5
+ def initialize
6
+ @duration = 0.0
7
+ @failing_scenarios = []
8
+ @scenarios = Hash.new(0)
9
+ @steps = Hash.new(0)
10
+ end
11
+
12
+ def increment(category, type, count)
13
+ current = instance_variable_get("@#{category}")
14
+ current[type] += count
15
+ end
16
+
17
+ def add(stats)
18
+ stats.each do |category, hash|
19
+ if category == :failing_scenarios
20
+ @failing_scenarios += hash
21
+ elsif category == :duration
22
+ @duration = hash.to_f if duration < hash.to_f
23
+ else
24
+ hash.each do |type, count|
25
+ increment(category, type, count)
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def scenarios(status=nil)
32
+ require 'ostruct'
33
+ length = status ? @scenarios[status] : @scenarios.inject(0) {|h,(k,v)| h += v}
34
+ any = @scenarios[status] > 0 if status
35
+ OpenStruct.new(:length => length , :any? => any)
36
+ end
37
+
38
+ def steps(status=nil)
39
+ require 'ostruct'
40
+ length = status ? @steps[status] : @steps.inject(0) {|h,(k,v)| h += v}
41
+ any = @steps[status] > 0 if status
42
+ OpenStruct.new(:length => length , :any? => any)
43
+ end
44
+ end
45
+
46
+ class FinalReport
47
+ include ::Cucumber::Formatter::Console
48
+ def initialize
49
+ @features = []
50
+ @summarizer = Summarizer.new
51
+ end
52
+
53
+ def add(stats)
54
+ @summarizer.add(stats)
55
+ end
56
+
57
+ def summarize
58
+ if @summarizer.failing_scenarios.any?
59
+ puts
60
+ puts
61
+ puts format_string("Failing Scenarios:", :failed)
62
+ @summarizer.failing_scenarios.each {|f| puts f }
63
+ end
64
+
65
+ default_format = lambda {|status_count, status| format_string(status_count, status)}
66
+ puts
67
+ puts scenario_summary(@summarizer, &default_format)
68
+ puts step_summary(@summarizer, &default_format)
69
+ puts format_duration(@summarizer.duration) if @summarizer.duration
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,9 @@
1
+ module Specjour
2
+ module Cucumber
3
+ class Printer < ::Specjour::Printer
4
+ def report
5
+ @report ||= FinalReport.new
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module Specjour
2
+ module Cucumber
3
+ begin
4
+ require 'cucumber'
5
+ require 'cucumber/formatter/progress'
6
+
7
+ require 'specjour/cucumber/dispatcher'
8
+ require 'specjour/cucumber/distributed_formatter'
9
+ require 'specjour/cucumber/final_report'
10
+ require 'specjour/cucumber/printer'
11
+ rescue LoadError
12
+ end
13
+ end
14
+ end
@@ -41,7 +41,7 @@ module Specjour
41
41
  end
42
42
 
43
43
  def fetch_manager(uri)
44
- Timeout.timeout(1) do
44
+ Timeout.timeout(8) do
45
45
  manager = DRbObject.new_with_uri(uri.to_s)
46
46
  if !managers.include?(manager) && manager.available_for?(project_name)
47
47
  set_up_manager(manager, uri)
@@ -75,11 +75,7 @@ module Specjour
75
75
  end
76
76
 
77
77
  def printer
78
- @printer ||= begin
79
- p = Printer.new
80
- p.specs_to_run = all_specs
81
- p.start
82
- end
78
+ @printer ||= Printer.start(all_specs)
83
79
  end
84
80
 
85
81
  def project_name
@@ -48,6 +48,7 @@ module Specjour
48
48
  end
49
49
 
50
50
  def dispatch_workers
51
+ GC.copy_on_write_friendly = true if GC.respond_to?(:copy_on_write_friendly=)
51
52
  (1..worker_size).each do |index|
52
53
  worker_pids << fork do
53
54
  exec("specjour --batch-size #{batch_size} #{'--log' if Specjour.log?} --do-work #{project_path},#{dispatcher_uri},#{index}")
@@ -3,9 +3,13 @@ module Specjour
3
3
  include Protocol
4
4
  RANDOM_PORT = 0
5
5
 
6
- attr_accessor :worker_size, :specs_to_run, :completed_workers
6
+ def self.start(specs_to_run)
7
+ new(specs_to_run).start
8
+ end
9
+
10
+ attr_accessor :worker_size, :specs_to_run, :completed_workers, :disconnections
7
11
 
8
- def initialize
12
+ def initialize(specs_to_run)
9
13
  super(
10
14
  port = RANDOM_PORT,
11
15
  host = "0.0.0.0",
@@ -15,6 +19,8 @@ module Specjour
15
19
  debug = true
16
20
  )
17
21
  @completed_workers = 0
22
+ @disconnections = 0
23
+ self.specs_to_run = specs_to_run
18
24
  end
19
25
 
20
26
  def serve(client)
@@ -40,7 +46,8 @@ module Specjour
40
46
  protected
41
47
 
42
48
  def disconnecting(client_port)
43
- if completed_workers == worker_size
49
+ self.disconnections += 1
50
+ if disconnections == worker_size
44
51
  stop
45
52
  end
46
53
  end
@@ -59,11 +66,16 @@ module Specjour
59
66
  end
60
67
 
61
68
  def report
62
- @report ||= FinalReport.new
69
+ @report ||= Rspec::FinalReport.new
63
70
  end
64
71
 
65
72
  def stopping
66
73
  report.summarize
74
+ if disconnections != completed_workers
75
+ puts "*" * 63
76
+ puts "* ERROR: NOT ALL WORKERS COMPLETED PROPERLY, RE-RUN THE SUITE *"
77
+ puts "*" * 63
78
+ end
67
79
  end
68
80
  end
69
81
  end
@@ -1,6 +1,6 @@
1
- module Specjour
1
+ module Specjour::Rspec
2
2
  class DistributedFormatter < Spec::Runner::Formatter::BaseTextFormatter
3
- require 'specjour/marshalable_rspec_failure'
3
+ require 'specjour/rspec/marshalable_rspec_failure'
4
4
 
5
5
  class << self
6
6
  attr_accessor :batch_size
@@ -0,0 +1,62 @@
1
+ module Specjour
2
+ module Rspec
3
+ class FinalReport
4
+ require 'specjour/rspec/marshalable_rspec_failure'
5
+ attr_reader :duration, :example_count, :failure_count, :pending_count, :pending_examples, :failing_examples
6
+
7
+ def initialize
8
+ @duration = 0.0
9
+ @example_count = 0
10
+ @failure_count = 0
11
+ @pending_count = 0
12
+ @pending_examples = []
13
+ @failing_examples = []
14
+ end
15
+
16
+ def add(stats)
17
+ stats.each do |key, value|
18
+ if key == :duration
19
+ @duration = value.to_f if duration < value.to_f
20
+ else
21
+ increment(key, value)
22
+ end
23
+ end
24
+ end
25
+
26
+ def increment(key, value)
27
+ current = instance_variable_get("@#{key}")
28
+ instance_variable_set("@#{key}", current + value)
29
+ end
30
+
31
+ def formatter_options
32
+ @formatter_options ||= OpenStruct.new(
33
+ :colour => true,
34
+ :autospec => false,
35
+ :dry_run => false
36
+ )
37
+ end
38
+
39
+ def formatter
40
+ @formatter ||= begin
41
+ f = MarshalableFailureFormatter.new(formatter_options, $stdout)
42
+ f.instance_variable_set(:@pending_examples, pending_examples)
43
+ f
44
+ end
45
+ end
46
+
47
+ def summarize
48
+ if example_count > 0
49
+ formatter.dump_pending
50
+ dump_failures
51
+ formatter.dump_summary(duration, example_count, failure_count, pending_count)
52
+ end
53
+ end
54
+
55
+ def dump_failures
56
+ failing_examples.each_with_index do |failure, index|
57
+ formatter.dump_failure index + 1, failure
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,4 +1,4 @@
1
- module Specjour
1
+ module Specjour::Rspec
2
2
  class MarshalableFailureFormatter < Spec::Runner::Formatter::BaseTextFormatter
3
3
  def dump_failure(counter, failure)
4
4
  @output.puts
@@ -1,4 +1,4 @@
1
- module Specjour
1
+ module Specjour::Rspec
2
2
  class Spec::Runner::Reporter::Failure
3
3
  attr_reader :backtrace, :message, :header, :exception_class_name
4
4
 
@@ -0,0 +1,10 @@
1
+ module Specjour
2
+ module Rspec
3
+ require 'spec'
4
+ require 'spec/runner/formatter/base_text_formatter'
5
+
6
+ autoload :DistributedFormatter, 'specjour/rspec/distributed_formatter'
7
+ autoload :FinalReport, 'specjour/rspec/final_report'
8
+ autoload :MarshalableFailureFormatter, 'specjour/rspec/marshalable_failure_formatter'
9
+ end
10
+ end
@@ -15,7 +15,7 @@ module Specjour
15
15
  def start
16
16
  write_config
17
17
  system("rsync", "--daemon", "--config=#{config_file}", "--port=8989")
18
- at_exit { puts 'shutting down rsync'; stop }
18
+ at_exit { stop }
19
19
  end
20
20
 
21
21
  def stop
@@ -5,6 +5,16 @@ namespace :specjour do
5
5
  args.with_defaults :project_path => Rake.original_dir
6
6
  Specjour::Dispatcher.new(args.project_path).start
7
7
  end
8
+
9
+ namespace :cucumber do
10
+ task :dispatch, [:project_path] do |task, args|
11
+ args.with_defaults :project_path => Rake.original_dir
12
+ Specjour::Cucumber::Dispatcher.new(args.project_path).start
13
+ end
14
+ end
15
+
16
+ desc "Dispatch the project to listening managers"
17
+ task :cucumber => "cucumber:dispatch"
8
18
  end
9
19
 
10
20
  desc "Dispatch the project to listening managers"
@@ -1,4 +1,6 @@
1
1
  module Specjour
2
+ require 'specjour/cucumber'
3
+
2
4
  class Worker
3
5
  include Protocol
4
6
  include SocketHelpers
@@ -11,8 +13,7 @@ module Specjour
11
13
  @number = number.to_i
12
14
  @batch_size = batch_size.to_i
13
15
  self.printer_uri = printer_uri
14
- GC.copy_on_write_friendly = true if GC.respond_to?(:copy_on_write_friendly=)
15
- DistributedFormatter.batch_size = batch_size
16
+ Rspec::DistributedFormatter.batch_size = batch_size
16
17
  set_env_variables
17
18
  end
18
19
 
@@ -25,16 +26,16 @@ module Specjour
25
26
  run_time = 0
26
27
  Dir.chdir(project_path)
27
28
  while !printer.closed? && data = printer.gets(TERMINATOR)
28
- spec = load_object(data)
29
- if spec
29
+ test = load_object(data)
30
+ if test
30
31
  run_time += Benchmark.realtime do
31
- run_spec spec
32
+ run_test test
32
33
  end
33
34
  printer.send_message(:ready)
34
35
  else
35
- printer.send_message(:done)
36
36
  printer.send_message(:worker_summary=, {:duration => sprintf("%6f", run_time)})
37
- printer.close
37
+ printer.send_message(:done)
38
+ printer.disconnect
38
39
  end
39
40
  end
40
41
  end
@@ -49,12 +50,26 @@ module Specjour
49
50
  Connection.new printer_uri
50
51
  end
51
52
 
53
+ def run_test(test)
54
+ puts "Running #{test}"
55
+ if test =~ /\.feature$/
56
+ run_feature test
57
+ else
58
+ run_spec test
59
+ end
60
+ end
61
+
62
+ def run_feature(feature)
63
+ set_up_cucumber
64
+ cli = ::Cucumber::Cli::Main.new(['--format', 'Specjour::Cucumber::DistributedFormatter', feature], printer)
65
+ cli.execute!(::Cucumber::Cli::Main.step_mother)
66
+ end
67
+
52
68
  def run_spec(spec)
53
- puts "Running #{spec}"
54
69
  options = Spec::Runner::OptionParser.parse(
55
- ['--format=Specjour::DistributedFormatter', spec],
70
+ ['--format=Specjour::Rspec::DistributedFormatter', spec],
56
71
  $stderr,
57
- printer_connection
72
+ printer
58
73
  )
59
74
  Spec::Runner.use options
60
75
  options.run_examples
@@ -65,5 +80,13 @@ module Specjour
65
80
  ENV['RSPEC_COLOR'] = 'true'
66
81
  ENV['TEST_ENV_NUMBER'] = number.to_s
67
82
  end
83
+
84
+ def set_up_cucumber
85
+ unless @cucumber_loaded
86
+ Cucumber::DistributedFormatter.batch_size = batch_size
87
+ ::Cucumber::Cli::Options.class_eval { def print_profile_information; end }
88
+ @cucumber_loaded = true
89
+ end
90
+ end
68
91
  end
69
92
  end
data/lib/specjour.rb CHANGED
@@ -1,10 +1,6 @@
1
- require 'spec'
2
- require 'spec/runner/formatter/base_text_formatter'
3
- require 'specjour/protocol'
4
- require 'specjour/core_ext/array'
1
+ require 'drb'
5
2
 
6
3
  autoload :URI, 'uri'
7
- autoload :DRb, 'drb'
8
4
  autoload :Forwardable, 'forwardable'
9
5
  autoload :GServer, 'gserver'
10
6
  autoload :Timeout, 'timeout'
@@ -13,18 +9,20 @@ autoload :Logger, 'logger'
13
9
  autoload :Socket, 'socket'
14
10
 
15
11
  module Specjour
12
+ autoload :CPU, 'specjour/cpu'
16
13
  autoload :Connection, 'specjour/connection'
17
14
  autoload :Dispatcher, 'specjour/dispatcher'
18
- autoload :DistributedFormatter, 'specjour/distributed_formatter'
19
- autoload :FinalReport, 'specjour/final_report'
20
15
  autoload :Manager, 'specjour/manager'
21
- autoload :MarshalableFailureFormatter, 'specjour/marshalable_failure_formatter'
22
16
  autoload :Printer, 'specjour/printer'
17
+ autoload :Protocol, 'specjour/protocol'
23
18
  autoload :RsyncDaemon, 'specjour/rsync_daemon'
24
19
  autoload :SocketHelpers, 'specjour/socket_helpers'
25
20
  autoload :Worker, 'specjour/worker'
26
21
 
27
- VERSION = "0.1.18".freeze
22
+ autoload :Cucumber, 'specjour/cucumber'
23
+ autoload :Rspec, 'specjour/rspec'
24
+
25
+ VERSION = "0.2.0".freeze
28
26
 
29
27
  class Error < StandardError; end
30
28
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 18
9
- version: 0.1.18
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Sandro Turriate
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-16 00:00:00 -04:00
17
+ date: 2010-04-20 00:00:00 -04:00
18
18
  default_executable: specjour
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -82,6 +82,7 @@ extra_rdoc_files:
82
82
  files:
83
83
  - .document
84
84
  - .gitignore
85
+ - History.markdown
85
86
  - MIT_LICENSE
86
87
  - README.markdown
87
88
  - Rakefile
@@ -89,23 +90,28 @@ files:
89
90
  - bin/specjour
90
91
  - lib/specjour.rb
91
92
  - lib/specjour/connection.rb
92
- - lib/specjour/core_ext/array.rb
93
+ - lib/specjour/cpu.rb
94
+ - lib/specjour/cucumber.rb
95
+ - lib/specjour/cucumber/dispatcher.rb
96
+ - lib/specjour/cucumber/distributed_formatter.rb
97
+ - lib/specjour/cucumber/final_report.rb
98
+ - lib/specjour/cucumber/printer.rb
93
99
  - lib/specjour/db_scrub.rb
94
100
  - lib/specjour/dispatcher.rb
95
- - lib/specjour/distributed_formatter.rb
96
- - lib/specjour/final_report.rb
97
101
  - lib/specjour/manager.rb
98
- - lib/specjour/marshalable_failure_formatter.rb
99
- - lib/specjour/marshalable_rspec_failure.rb
100
102
  - lib/specjour/printer.rb
101
103
  - lib/specjour/protocol.rb
104
+ - lib/specjour/rspec.rb
105
+ - lib/specjour/rspec/distributed_formatter.rb
106
+ - lib/specjour/rspec/final_report.rb
107
+ - lib/specjour/rspec/marshalable_failure_formatter.rb
108
+ - lib/specjour/rspec/marshalable_rspec_failure.rb
102
109
  - lib/specjour/rsync_daemon.rb
103
110
  - lib/specjour/socket_helpers.rb
104
111
  - lib/specjour/tasks/dispatch.rake
105
112
  - lib/specjour/tasks/specjour.rb
106
113
  - lib/specjour/worker.rb
107
114
  - rails/init.rb
108
- - spec/lib/specjour/core_ext/array_spec.rb
109
115
  - spec/lib/specjour/worker_spec.rb
110
116
  - spec/spec.opts
111
117
  - spec/spec_helper.rb
@@ -141,8 +147,6 @@ signing_key:
141
147
  specification_version: 3
142
148
  summary: Distribute your spec suite amongst your LAN via Bonjour.
143
149
  test_files:
144
- - spec/lib/specjour/connection_spec.rb
145
- - spec/lib/specjour/core_ext/array_spec.rb
146
150
  - spec/lib/specjour/worker_spec.rb
147
151
  - spec/spec_helper.rb
148
152
  - spec/specjour_spec.rb
@@ -1,15 +0,0 @@
1
- module Specjour
2
- module Among
3
- def among(group_size)
4
- group_size = 1 if group_size.zero?
5
- groups = Array.new(group_size) { [] }
6
- offset = 0
7
- each do |item|
8
- groups[offset] << item
9
- offset = (offset == group_size - 1) ? 0 : offset + 1
10
- end
11
- groups
12
- end
13
- end
14
- end
15
- ::Array.send(:include, Specjour::Among)
@@ -1,60 +0,0 @@
1
- module Specjour
2
- class FinalReport
3
- require 'specjour/marshalable_rspec_failure'
4
- attr_reader :duration, :example_count, :failure_count, :pending_count, :pending_examples, :failing_examples
5
-
6
- def initialize
7
- @duration = 0.0
8
- @example_count = 0
9
- @failure_count = 0
10
- @pending_count = 0
11
- @pending_examples = []
12
- @failing_examples = []
13
- end
14
-
15
- def add(stats)
16
- stats.each do |key, value|
17
- if key == :duration
18
- @duration = value.to_f if duration < value.to_f
19
- else
20
- increment(key, value)
21
- end
22
- end
23
- end
24
-
25
- def increment(key, value)
26
- current = instance_variable_get("@#{key}")
27
- instance_variable_set("@#{key}", current + value)
28
- end
29
-
30
- def formatter_options
31
- @formatter_options ||= OpenStruct.new(
32
- :colour => true,
33
- :autospec => false,
34
- :dry_run => false
35
- )
36
- end
37
-
38
- def formatter
39
- @formatter ||= begin
40
- f = MarshalableFailureFormatter.new(formatter_options, $stdout)
41
- f.instance_variable_set(:@pending_examples, pending_examples)
42
- f
43
- end
44
- end
45
-
46
- def summarize
47
- if example_count > 0
48
- formatter.dump_pending
49
- dump_failures
50
- formatter.dump_summary(duration, example_count, failure_count, pending_count)
51
- end
52
- end
53
-
54
- def dump_failures
55
- failing_examples.each_with_index do |failure, index|
56
- formatter.dump_failure index + 1, failure
57
- end
58
- end
59
- end
60
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Specjour::Connection do
4
- require 'stringio'
5
- describe "#print" do
6
- context "connection unavailable" do
7
- let(:connection) do
8
- Specjour::Connection.new(URI.parse("specjour://me.local:12345"))
9
- end
10
-
11
- it "reconnects" do
12
- socket = mock(:closed? => false, :close => true)
13
- socket.stub(:print).and_raise(Errno::EPIPE)
14
- connection.instance_variable_set(:@socket, socket)
15
- new_socket = mock(:print => true)
16
- TCPSocket.stub(:open => new_socket)
17
- connection.print('hi').should be_true
18
- end
19
- end
20
- end
21
- end
@@ -1,31 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Array splitting among many" do
4
- describe "#among" do
5
- let(:array) { [1,2,3,4,5] }
6
-
7
- it "splits among 0" do
8
- array.among(0).should == [[1,2,3,4,5]]
9
- end
10
-
11
- it "splits among by 1" do
12
- array.among(1).should == [[1,2,3,4,5]]
13
- end
14
-
15
- it "splits among by 2" do
16
- array.among(2).should == [[1,3,5],[2,4]]
17
- end
18
-
19
- it "splits among by 3" do
20
- array.among(3).should == [[1,4],[2,5],[3]]
21
- end
22
-
23
- it "splits among by 4" do
24
- array.among(4).should == [[1,5],[2],[3],[4]]
25
- end
26
-
27
- it "splits among by 5" do
28
- array.among(5).should == [[1],[2],[3],[4],[5]]
29
- end
30
- end
31
- end