rspec-search-and-destroy 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ script: cucumber
data/bin/rspec-sad CHANGED
@@ -3,6 +3,10 @@
3
3
  $LOAD_PATH << "$PWD/../lib/"
4
4
  require 'rspec-sad'
5
5
 
6
+ require 'rspec-search-and-destroy/binary_chop_example_selector'
7
+ require 'rspec-search-and-destroy/rspec_driver'
8
+ require 'rspec-search-and-destroy/bisector'
9
+
6
10
  include RSpecSearchAndDestroy
7
11
 
8
12
  class TTYOutput
@@ -0,0 +1,41 @@
1
+ Feature: `before(:all)` blocks are disabled when all of the examples are also disabled
2
+
3
+ Scenario: Run it
4
+ Given a file named "spec/spec_helper.rb" with:
5
+ """ruby
6
+ require 'rspec-sad'
7
+
8
+ RSpec.configure do |config|
9
+ RSpecSearchAndDestroy.configure(config)
10
+ end
11
+ """
12
+ And a file named "spec/before_all_spec.rb" with:
13
+ """ruby
14
+ require 'spec_helper'
15
+
16
+ describe 'Tests that have before :all' do
17
+ context do
18
+ before(:all) { puts 'example 1 - before :all' }
19
+ it 'leaves bad global state' do
20
+ $global_state = true
21
+ expect($global_state).to be true
22
+ end
23
+ end
24
+
25
+ context do
26
+ before(:all) { puts 'example 2 - before :all' }
27
+ it do
28
+ expect(true).to be true
29
+ end
30
+ end
31
+
32
+ context do
33
+ before(:all) { puts 'example 3 - before :all' }
34
+ it 'relies on global state' do
35
+ expect($global_state).to be false
36
+ end
37
+ end
38
+ end
39
+ """
40
+ When I run `rspec-sad`
41
+ Then the output should contain "example 2 - before :all" 1 time
@@ -0,0 +1,34 @@
1
+ Feature: Bisecting a single file
2
+
3
+ Scenario: Run it
4
+ Given a file named "spec/spec_helper.rb" with:
5
+ """ruby
6
+ require 'rspec-sad'
7
+
8
+ RSpec.configure do |config|
9
+ RSpecSearchAndDestroy.configure(config)
10
+ end
11
+ """
12
+ And a file named "spec/single_file_spec.rb" with:
13
+ """ruby
14
+ require 'spec_helper'
15
+
16
+ describe "Tests that fail when run in a specific order" do
17
+ it "leaves bad global state" do
18
+ $global_state = true
19
+ expect($global_state).to be true
20
+ end
21
+
22
+ it "just takes up space" do
23
+ expect(true).to be true
24
+ end
25
+
26
+ it "fails when run last" do
27
+ expect($global_state).to be false
28
+ end
29
+ end
30
+ """
31
+ When I run `rspec-sad`
32
+ Then the output should contain "Culprit found"
33
+ And the output should contain "Run ./spec/single_file_spec.rb:4"
34
+ And the output should contain "Before ./spec/single_file_spec.rb:13"
@@ -0,0 +1,46 @@
1
+ Feature: Bisecting multiple files
2
+
3
+ Scenario: Run it
4
+ Given a file named "spec/spec_helper.rb" with:
5
+ """ruby
6
+ require 'rspec-sad'
7
+
8
+ RSpec.configure do |config|
9
+ RSpecSearchAndDestroy.configure(config)
10
+ end
11
+ """
12
+ And a file named "spec/file_1_spec.rb" with:
13
+ """ruby
14
+ require 'spec_helper'
15
+
16
+ describe 'group 1' do
17
+ it '1 - sets bad global state' do
18
+ $global_state = true
19
+ expect($global_state).to be_true
20
+ end
21
+ end
22
+ """
23
+ And a file named "spec/file_2_spec.rb" with:
24
+ """ruby
25
+ require 'spec_helper'
26
+
27
+ describe 'group 2' do
28
+ it '2 - just takes up space' do
29
+ expect(true).to be_true
30
+ end
31
+ end
32
+ """
33
+ And a file named "spec/file_3_spec.rb" with:
34
+ """ruby
35
+ require 'spec_helper'
36
+
37
+ describe 'group 3' do
38
+ it '3 - fails because of global state' do
39
+ expect($global_state).to be_false
40
+ end
41
+ end
42
+ """
43
+ When I run `rspec-sad`
44
+ Then the output should contain "Culprit found"
45
+ And the output should contain "Run ./spec/file_1_spec.rb:4"
46
+ And the output should contain "Before ./spec/file_3_spec.rb:4"
@@ -0,0 +1 @@
1
+ require 'aruba/cucumber'
@@ -0,0 +1,4 @@
1
+ Then(/^the output should contain "(.*?)" (\d+) times?$/) do |expected_output, expected_count|
2
+ actual_count = all_output.scan(expected_output).length
3
+ expect(actual_count).to eql expected_count.to_i
4
+ end
data/lib/rspec-sad.rb CHANGED
@@ -1,9 +1,8 @@
1
- require "rspec-search-and-destroy/version"
2
- require "rspec-search-and-destroy/bisector"
3
- require "rspec-search-and-destroy/binary_chop_example_selector"
1
+ require 'rspec-search-and-destroy/version'
4
2
 
5
- require 'rspec'
6
- require 'rspec/core/formatters/base_formatter'
3
+ require 'rspec-search-and-destroy/order_formatter'
4
+ require 'rspec-search-and-destroy/location_source'
5
+ require 'rspec-search-and-destroy/reorder_and_filter'
7
6
 
8
7
  module RSpecSearchAndDestroy
9
8
  def self.configure(config)
@@ -12,146 +11,9 @@ module RSpecSearchAndDestroy
12
11
  source = LocationSource.new
13
12
  if source.enabled?
14
13
  ordering = ReorderAndFilter.new(source)
15
- config.order_examples(&ordering.block)
16
- end
17
- end
18
-
19
- class OrderFormatter < RSpec::Core::Formatters::BaseFormatter
20
- def stop
21
- File.open(filename, 'wb') do |f|
22
- Marshal.dump(results, f)
23
- end
24
-
25
- super
26
- end
27
-
28
- private
29
-
30
- def filename
31
- ENV['RSPEC_SAD_RESULTS'] or raise "No result filename provided"
32
- end
33
-
34
- def results
35
- examples.map do |e|
36
- {
37
- location: e.location,
38
- failed: !!e.exception
39
- }
40
- end
41
- end
42
- end
43
-
44
- class LocationSource
45
- def enabled?
46
- filename && File.exist?(filename)
47
- end
48
-
49
- def example_locations_to_run
50
- raise "LocationSource is not currently enabled" unless enabled?
51
-
52
- File.open(filename, 'rb') do |f|
53
- Marshal.load(f)
54
- end
55
- end
56
-
57
- private
58
-
59
- def filename
60
- ENV['RSPEC_SAD_EXAMPLES']
61
- end
62
- end
63
-
64
- class ReorderAndFilter
65
- attr_reader :source
66
-
67
- def initialize(source)
68
- @source = source
69
- end
70
-
71
- def block
72
- lambda do |examples|
73
- locations = source.example_locations_to_run
74
-
75
- enabled_examples = examples.select do |e|
76
- locations.include? e.location
77
- end
78
-
79
- enabled_examples.sort_by do |e|
80
- locations.index(e.location)
81
- end
82
- end
83
- end
84
- end
85
14
 
86
- class RSpecResults
87
- attr_reader :results
88
-
89
- def initialize(results)
90
- @results = results
91
- end
92
-
93
- def causal_examples
94
- results.slice(0, failure_index)
95
- end
96
-
97
- def failed_example
98
- results[failure_index]
99
- end
100
-
101
- def failed?
102
- results.find {|result| result[:failed] }
103
- end
104
-
105
- private
106
-
107
- def failure_index
108
- @failure_index ||= results.find_index { |r| r[:failed] }
109
- end
110
- end
111
-
112
- class RSpecDriver
113
- RESULT_FILE = '/tmp/example-results'
114
- EXAMPLE_FILE = '/tmp/examples-to-run'
115
-
116
- def load_run_results
117
- File.open(RESULT_FILE, 'rb') do |f|
118
- RSpecResults.new(Marshal.load(f))
119
- end
120
- end
121
-
122
- def initial_run
123
- cleanup
124
- run_rspec
125
- end
126
-
127
- def run_examples(examples)
128
- locations = examples.map {|x| x[:location]}
129
-
130
- File.open(EXAMPLE_FILE, 'wb') do |f|
131
- Marshal.dump(locations, f)
132
- end
133
-
134
- run_rspec
135
- end
136
-
137
- def cleanup
138
- [EXAMPLE_FILE, RESULT_FILE].each do |fname|
139
- File.delete(fname) if File.exist? fname
140
- end
141
- end
142
-
143
- private
144
-
145
- def run_rspec
146
- env = {
147
- "RSPEC_SAD_EXAMPLES" => EXAMPLE_FILE,
148
- "RSPEC_SAD_RESULTS" => RESULT_FILE
149
- }
150
- cmd = "rspec"
151
-
152
- success = system(env, cmd)
153
-
154
- raise "unable to run command: #{cmd}" if success.nil?
15
+ config.files_or_directories_to_run = source.example_locations_to_run
16
+ config.order_examples(&ordering.block)
155
17
  end
156
18
  end
157
19
  end
@@ -0,0 +1,21 @@
1
+ module RSpecSearchAndDestroy
2
+ class LocationSource
3
+ def enabled?
4
+ filename && File.exist?(filename)
5
+ end
6
+
7
+ def example_locations_to_run
8
+ raise "LocationSource is not currently enabled" unless enabled?
9
+
10
+ File.open(filename, 'rb') do |f|
11
+ Marshal.load(f)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def filename
18
+ ENV['RSPEC_SAD_EXAMPLES']
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,28 @@
1
+ require 'rspec/core/formatters/base_formatter'
2
+
3
+ module RSpecSearchAndDestroy
4
+ class OrderFormatter < RSpec::Core::Formatters::BaseFormatter
5
+ def stop
6
+ File.open(filename, 'wb') do |f|
7
+ Marshal.dump(results, f)
8
+ end
9
+
10
+ super
11
+ end
12
+
13
+ private
14
+
15
+ def filename
16
+ ENV['RSPEC_SAD_RESULTS'] or raise "No result filename provided"
17
+ end
18
+
19
+ def results
20
+ examples.map do |e|
21
+ {
22
+ location: e.location,
23
+ failed: !!e.exception
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ module RSpecSearchAndDestroy
2
+ class ReorderAndFilter
3
+ attr_reader :source
4
+
5
+ def initialize(source)
6
+ @source = source
7
+ end
8
+
9
+ def block
10
+ lambda do |examples|
11
+ locations = source.example_locations_to_run
12
+
13
+ enabled_examples = examples.select do |e|
14
+ locations.include? e.location
15
+ end
16
+
17
+ enabled_examples.sort_by do |e|
18
+ locations.index(e.location)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,56 @@
1
+ require_relative 'rspec_results'
2
+
3
+ module RSpecSearchAndDestroy
4
+ class RSpecDriver
5
+ RESULT_FILE = '/tmp/example-results'
6
+ EXAMPLE_FILE = '/tmp/examples-to-run'
7
+
8
+ def load_run_results
9
+ unless File.exist? RESULT_FILE
10
+ raise <<ERR
11
+ The RSpec result file was not created. Please ensure that SAD is
12
+ added to your RSpec configuration.
13
+ ERR
14
+ end
15
+
16
+ File.open(RESULT_FILE, 'rb') do |f|
17
+ RSpecResults.new(Marshal.load(f))
18
+ end
19
+ end
20
+
21
+ def initial_run
22
+ cleanup
23
+ run_rspec
24
+ end
25
+
26
+ def run_examples(examples)
27
+ locations = examples.map {|x| x[:location]}
28
+
29
+ File.open(EXAMPLE_FILE, 'wb') do |f|
30
+ Marshal.dump(locations, f)
31
+ end
32
+
33
+ run_rspec
34
+ end
35
+
36
+ def cleanup
37
+ [EXAMPLE_FILE, RESULT_FILE].each do |fname|
38
+ File.delete(fname) if File.exist? fname
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def run_rspec
45
+ env = {
46
+ "RSPEC_SAD_EXAMPLES" => EXAMPLE_FILE,
47
+ "RSPEC_SAD_RESULTS" => RESULT_FILE
48
+ }
49
+ cmd = "rspec"
50
+
51
+ success = system(env, cmd)
52
+
53
+ raise "unable to run command: #{cmd}" if success.nil?
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,27 @@
1
+ module RSpecSearchAndDestroy
2
+ class RSpecResults
3
+ attr_reader :results
4
+
5
+ def initialize(results)
6
+ @results = results
7
+ end
8
+
9
+ def causal_examples
10
+ results.slice(0, failure_index)
11
+ end
12
+
13
+ def failed_example
14
+ results[failure_index]
15
+ end
16
+
17
+ def failed?
18
+ results.find {|result| result[:failed] }
19
+ end
20
+
21
+ private
22
+
23
+ def failure_index
24
+ @failure_index ||= results.find_index { |r| r[:failed] }
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module RSpecSearchAndDestroy
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -5,6 +5,7 @@ require 'rspec-search-and-destroy/version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "rspec-search-and-destroy"
8
+ gem.license = 'MIT'
8
9
  gem.version = RSpecSearchAndDestroy::VERSION
9
10
  gem.authors = ["Jake Goulding"]
10
11
  gem.email = ["jake.goulding@gmail.com"]
@@ -17,5 +18,8 @@ Gem::Specification.new do |gem|
17
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
19
  gem.require_paths = ["lib"]
19
20
 
20
- gem.add_dependency('rspec', '>= 2.14.0')
21
+ gem.add_dependency('rspec', '~> 2.12')
22
+
23
+ gem.add_development_dependency('rspec', '~> 2.14')
24
+ gem.add_development_dependency('aruba')
21
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-search-and-destroy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,56 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-24 00:00:00.000000000 Z
12
+ date: 2013-09-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ! '>='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 2.14.0
21
+ version: '2.12'
22
22
  type: :runtime
23
23
  prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.12'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.14'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.14'
46
+ - !ruby/object:Gem::Dependency
47
+ name: aruba
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
24
56
  version_requirements: !ruby/object:Gem::Requirement
25
57
  none: false
26
58
  requirements:
27
59
  - - ! '>='
28
60
  - !ruby/object:Gem::Version
29
- version: 2.14.0
61
+ version: '0'
30
62
  description: ! 'Finds RSpec test ordering bugs '
31
63
  email:
32
64
  - jake.goulding@gmail.com
@@ -37,16 +69,25 @@ extra_rdoc_files: []
37
69
  files:
38
70
  - .gitignore
39
71
  - .rspec
72
+ - .travis.yml
40
73
  - Gemfile
41
74
  - LICENSE.txt
42
75
  - README.md
43
76
  - Rakefile
44
77
  - bin/rspec-sad
45
- - examples/spec/bad_ordering_spec.rb
46
- - examples/spec/spec_helper.rb
78
+ - features/before_all_blocks_are_disabled.feature
79
+ - features/bisecting_a_single_file.feature
80
+ - features/bisecting_multiple_files.feature
81
+ - features/support/env.rb
82
+ - features/support/steps.rb
47
83
  - lib/rspec-sad.rb
48
84
  - lib/rspec-search-and-destroy/binary_chop_example_selector.rb
49
85
  - lib/rspec-search-and-destroy/bisector.rb
86
+ - lib/rspec-search-and-destroy/location_source.rb
87
+ - lib/rspec-search-and-destroy/order_formatter.rb
88
+ - lib/rspec-search-and-destroy/reorder_and_filter.rb
89
+ - lib/rspec-search-and-destroy/rspec_driver.rb
90
+ - lib/rspec-search-and-destroy/rspec_results.rb
50
91
  - lib/rspec-search-and-destroy/version.rb
51
92
  - rspec-search-and-destroy.gemspec
52
93
  - spec/binary_chop_example_selector_spec.rb
@@ -54,7 +95,8 @@ files:
54
95
  - spec/rspec_example_ordering_spec.rb
55
96
  - spec/spec_helper.rb
56
97
  homepage: https://github.com/shepmaster/rspec-search-and-destroy
57
- licenses: []
98
+ licenses:
99
+ - MIT
58
100
  post_install_message:
59
101
  rdoc_options: []
60
102
  require_paths:
@@ -78,6 +120,11 @@ signing_key:
78
120
  specification_version: 3
79
121
  summary: Finds RSpec test ordering bugs
80
122
  test_files:
123
+ - features/before_all_blocks_are_disabled.feature
124
+ - features/bisecting_a_single_file.feature
125
+ - features/bisecting_multiple_files.feature
126
+ - features/support/env.rb
127
+ - features/support/steps.rb
81
128
  - spec/binary_chop_example_selector_spec.rb
82
129
  - spec/bisector_spec.rb
83
130
  - spec/rspec_example_ordering_spec.rb
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Tests that fail when run in a specific order" do
4
- it "leaves bad global state" do
5
- $fail_next = true
6
- expect($fail_next).to be_true
7
- end
8
-
9
- it "just takes up space" do
10
- expect(true).to be_true
11
- end
12
-
13
- it "fails when run last" do
14
- expect($fail_next).to be_false
15
- end
16
- end
@@ -1,15 +0,0 @@
1
- require 'rspec-sad'
2
-
3
- RSpec.configure do |config|
4
- config.treat_symbols_as_metadata_keys_with_true_values = true
5
- config.run_all_when_everything_filtered = true
6
- config.filter_run :focus
7
-
8
- config.color = true
9
- config.formatter = 'documentation'
10
-
11
- # For this example, run in an order that is guaranteed to be bad
12
- config.order = 'default'
13
-
14
- RSpecSearchAndDestroy.configure(config)
15
- end