specjour 0.1.18 → 0.2.0

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/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