respec 0.7.0 → 0.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d53d945527eec47f8756eb05b37d6d4728b79814
4
- data.tar.gz: 20d763a3e804d9d1562b3dfa7589cda2eb0238ea
3
+ metadata.gz: dfad27bdd03eab8d26196cec1c56ab386f313fb1
4
+ data.tar.gz: 6e6a4223f0caa56a7233fcc97816f720d0710268
5
5
  SHA512:
6
- metadata.gz: c10f7f2a4e072f67d0e692183c4f39678182cab17f97b823320335a70b58b64ccab93399d836a91abfe362d11332cc358c271c836f792e74d1bd4503064c5091
7
- data.tar.gz: d5faf4f588bf784f1aad11cce08a743f7d8a1cadb77b0cb121bcaec5239be5a04e3bfc001c878e06b127dc8f5933e9b4298e0c5f364646e03757305e25169806
6
+ metadata.gz: 7e139c64ecb48d92d2d44bd37be6c13d25cdf3a5e4bcac1f664a0b7e1c5e78990c2539883807a972a4ebe437545b86a054d7e7a3c40473d17f7175e05bbf84f7
7
+ data.tar.gz: fdf8cd1a0ad2d9713a15a6020a296956e822b5c9750f1f024aaa73178848a57ed3bdd1945fae847177f476e266aa8927b89a203c758eda9087429e9514f7a4f5
@@ -2,8 +2,12 @@ language: ruby
2
2
  bundler_args: --without dev
3
3
  script: bundle exec rake ci
4
4
  rvm:
5
- - 1.8.7
6
- - 1.9.2
7
- - 1.9.3
8
- - jruby-19mode
9
- - rbx-19mode
5
+ - 2.0.0
6
+ - 2.1.5
7
+ - 2.2.0
8
+ - jruby-1.7.9
9
+ - rbx-2.4.1
10
+ env:
11
+ - RESPEC_RSPEC_VERSION='~> 2.11.0'
12
+ - RESPEC_RSPEC_VERSION='~> 2.14.0'
13
+ - RESPEC_RSPEC_VERSION='~> 3'
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ == 0.8.0 2015-02-02
2
+
3
+ * Support RSpec 3.
4
+ * Record failing example names, not locations. Requires rspec 2.11 or above.
5
+ * Wait until end of test suite before updating failure file.
6
+ * Use rspec binstub if present.
7
+
1
8
  == 0.7.0 2014-04-16
2
9
 
3
10
  * Allow setting failure file via argument. Useful under CI with parallel_tests.
data/Gemfile CHANGED
@@ -1,2 +1,13 @@
1
1
  source 'https://rubygems.org/'
2
2
  gemspec
3
+
4
+ gem 'ritual'
5
+ gem 'temporaries'
6
+
7
+ version = ENV['RESPEC_RSPEC_VERSION'] and
8
+ gem 'rspec', version
9
+
10
+ group :dev do
11
+ gem 'byebug'
12
+ gem 'looksee'
13
+ end
@@ -1,4 +1,4 @@
1
- ## Respec
1
+ ## Respec [![Build Status](https://travis-ci.org/oggy/respec.png)](https://travis-ci.org/oggy/respec) [![Gem Version](https://badge.fury.io/rb/respec.svg)](http://badge.fury.io/rb/respec)
2
2
 
3
3
  Provides a command, `respec`, which wraps `rspec`, and records your
4
4
  failing examples for easy rerunning.
@@ -48,7 +48,7 @@ command line:
48
48
  If the argument doesn't name an existing file, it's assumed to be an
49
49
  example name.
50
50
 
51
- It'll even `bundle exec` for you automatically.
51
+ It'll even `bundle exec` for you automatically, or use a binstub if present.
52
52
 
53
53
  There are a few other shortcuts. `respec --help` to see them all.
54
54
 
data/bin/respec CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ ROOT = File.expand_path('..', File.dirname(__FILE__))
4
+ $:.unshift "#{ROOT}/lib"
3
5
  require 'respec'
4
6
 
5
7
  app = Respec::App.new(*ARGV)
@@ -11,7 +11,6 @@ module Respec
11
11
  @raw_args = []
12
12
  end
13
13
  @failures_path = self.class.default_failures_path
14
- @selected_failures = false
15
14
  @update_failures = true
16
15
  process_args
17
16
  end
@@ -19,14 +18,16 @@ module Respec
19
18
  attr_accessor :failures_path
20
19
 
21
20
  def command
22
- @command ||= bundler_args + ['rspec'] + generated_args + raw_args + formatter_args
21
+ @command ||= program_args + generated_args + raw_args + formatter_args
23
22
  end
24
23
 
25
- def bundler_args
26
- if File.exist?(ENV['BUNDLE_GEMFILE'] || 'Gemfile')
27
- ['bundle', 'exec']
24
+ def program_args
25
+ if File.exist?('bin/rspec')
26
+ ['bin/rspec']
27
+ elsif File.exist?(ENV['BUNDLE_GEMFILE'] || 'Gemfile')
28
+ ['bundle', 'exec', 'rspec']
28
29
  else
29
- []
30
+ ['rspec']
30
31
  end
31
32
  end
32
33
 
@@ -100,8 +101,7 @@ module Respec
100
101
  STDERR.puts "No specs failed!"
101
102
  []
102
103
  else
103
- @selected_failures = true
104
- failures
104
+ failures.flat_map { |f| ['-e', f] }
105
105
  end
106
106
  else
107
107
  warn "no fail file - ignoring 'f' argument"
@@ -111,14 +111,13 @@ module Respec
111
111
  elsif arg =~ /\A\d+\z/
112
112
  i = Integer(arg)
113
113
  if (failure = failures[i - 1])
114
- args << failure
115
- @selected_failures = true
114
+ args << '-e' << failure
116
115
  @update_failures = false
117
116
  else
118
117
  warn "invalid failure: #{i} for (1..#{failures.size})"
119
118
  end
120
119
  else
121
- args << '--example' << arg.gsub(/[$]/, '\\\\\\0')
120
+ args << '-e' << arg.gsub(/[$]/, '\\\\\\0')
122
121
  end
123
122
  end
124
123
 
@@ -138,7 +137,7 @@ module Respec
138
137
  # If we selected individual failures to rerun, don't give the files to
139
138
  # rspec, as those files will be run in their entirety.
140
139
  @generated_args = expanded
141
- @generated_args.concat(files) unless @selected_failures
140
+ @generated_args.concat(files)
142
141
  end
143
142
 
144
143
  def failures
@@ -1,32 +1,50 @@
1
1
  require 'rspec/core/formatters/base_formatter'
2
+ require 'rspec/core/version'
2
3
 
3
4
  module Respec
4
- class Formatter < RSpec::Core::Formatters::BaseFormatter
5
- def start_dump
6
- @failed_examples.each do |example|
7
- output.puts self.class.extract_spec_location(example.metadata)
5
+ def self.failures_path
6
+ ENV['RESPEC_FAILURES'] || File.expand_path(".respec_failures")
7
+ end
8
+
9
+ if (RSpec::Core::Version::STRING.scan(/\d+/).map { |s| s.to_i } <=> [3]) < 0
10
+
11
+ class Formatter < RSpec::Core::Formatters::BaseFormatter
12
+ def initialize(output=nil)
13
+ super(output)
8
14
  end
9
- end
10
15
 
11
- def self.extract_spec_location(metadata)
12
- root_metadata = metadata
13
- until spec_path?(metadata[:location])
14
- metadata = metadata[:example_group]
15
- if !metadata
16
- warn "no spec file found for #{root_metadata[:location]}"
17
- return root_metadata[:location]
16
+ def start_dump
17
+ open(Respec.failures_path, 'w') do |file|
18
+ @failed_examples.each do |example|
19
+ file.puts example.metadata[:full_description]
20
+ end
18
21
  end
19
22
  end
20
- metadata[:location]
21
23
  end
22
24
 
23
- def self.spec_path?(path)
24
- flags = File::FNM_PATHNAME | File::FNM_DOTMATCH
25
- if File.const_defined?(:FNM_EXTGLOB) # ruby >= 2
26
- flags |= File::FNM_EXTGLOB
25
+ else
26
+
27
+ class Formatter < RSpec::Core::Formatters::BaseFormatter
28
+ def initialize(output=nil)
29
+ @respec_failures = []
30
+ super(output)
31
+ end
32
+
33
+ def example_failed(notification)
34
+ @respec_failures << notification.example.full_description
35
+ end
36
+
37
+ def start_dump(notification)
38
+ open(Respec.failures_path, 'w') do |file|
39
+ @respec_failures.each do |failure|
40
+ file.puts failure
41
+ end
42
+ end
27
43
  end
28
- File.fnmatch(RSpec.configuration.pattern, path.sub(/:\d+\z/, ''), flags)
44
+
45
+ RSpec::Core::Formatters.register self, :example_failed, :start_dump
29
46
  end
47
+
30
48
  end
31
49
  end
32
50
 
@@ -35,5 +53,5 @@ end
35
53
  # option.
36
54
  RSpec.configure do |config|
37
55
  config.add_formatter 'progress' if config.formatters.empty?
38
- config.add_formatter Respec::Formatter, ENV['RESPEC_FAILURES'] || File.expand_path(".respec_failures")
56
+ config.add_formatter Respec::Formatter
39
57
  end
@@ -1,5 +1,5 @@
1
1
  module Respec
2
- VERSION = [0, 7, 0]
2
+ VERSION = [0, 8, 0]
3
3
 
4
4
  class << VERSION
5
5
  include Comparable
@@ -14,7 +14,5 @@ Gem::Specification.new do |gem|
14
14
  gem.files = `git ls-files`.split("\n")
15
15
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
16
 
17
- gem.add_runtime_dependency 'rspec', '>= 2.0'
18
- gem.add_development_dependency 'ritual', '~> 0.4'
19
- gem.add_development_dependency 'temporaries', '~> 0.4'
17
+ gem.add_runtime_dependency 'rspec', '>= 2.11'
20
18
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path('spec_helper', File.dirname(__FILE__))
1
+ require_relative 'spec_helper'
2
2
  require 'rbconfig'
3
3
 
4
4
  describe Respec do
@@ -9,10 +9,6 @@ describe Respec::App do
9
9
 
10
10
  Respec::App.default_failures_path = FAIL_PATH
11
11
 
12
- def write_file(path, content)
13
- open(path, 'w') { |f| f.print content }
14
- end
15
-
16
12
  def make_failures_file(*examples)
17
13
  options = examples.last.is_a?(Hash) ? examples.pop : {}
18
14
  path = options[:path] || Respec::App.default_failures_path
@@ -35,12 +31,21 @@ describe Respec::App do
35
31
  end
36
32
  end
37
33
 
38
- describe "#bundler_args" do
39
- it "should run through bundler if a Gemfile is present" do
34
+ describe "#program_args" do
35
+ it "should run through a binstub if present" do
36
+ FileUtils.mkdir "#{tmp}/bin"
37
+ FileUtils.touch "#{tmp}/bin/rspec"
38
+ Dir.chdir tmp do
39
+ app = Respec::App.new
40
+ expect(app.program_args).to eq ['bin/rspec']
41
+ end
42
+ end
43
+
44
+ it "should otherwise run through bundler if a Gemfile is present" do
40
45
  FileUtils.touch "#{tmp}/Gemfile"
41
46
  Dir.chdir tmp do
42
47
  app = Respec::App.new
43
- expect(app.bundler_args).to eq ['bundle', 'exec']
48
+ expect(app.program_args).to eq ['bundle', 'exec', 'rspec']
44
49
  end
45
50
  end
46
51
 
@@ -49,7 +54,7 @@ describe Respec::App do
49
54
  FileUtils.touch "#{tmp}/custom_gemfile"
50
55
  Dir.chdir tmp do
51
56
  app = Respec::App.new
52
- expect(app.bundler_args).to eq ['bundle', 'exec']
57
+ expect(app.program_args).to eq ['bundle', 'exec', 'rspec']
53
58
  end
54
59
  end
55
60
  end
@@ -58,7 +63,7 @@ describe Respec::App do
58
63
  with_hash_value ENV, 'BUNDLE_GEMFILE', nil do
59
64
  Dir.chdir tmp do
60
65
  app = Respec::App.new
61
- expect(app.bundler_args).to eq []
66
+ expect(app.program_args).to eq ['rspec']
62
67
  end
63
68
  end
64
69
  end
@@ -71,13 +76,13 @@ describe Respec::App do
71
76
  end
72
77
 
73
78
  it "should update the stored failures if 'f' is used" do
74
- make_failures_file 'a.rb:1'
79
+ make_failures_file 'a'
75
80
  app = Respec::App.new('f')
76
81
  expect(app.formatter_args).to eq [FORMATTER_PATH]
77
82
  end
78
83
 
79
84
  it "should not update the stored failures if a numeric argument is given" do
80
- make_failures_file 'a.rb:1'
85
+ make_failures_file 'a'
81
86
  app = Respec::App.new('1')
82
87
  expect(app.formatter_args).to eq []
83
88
  end
@@ -96,21 +101,27 @@ describe Respec::App do
96
101
  end
97
102
 
98
103
  it "should run all failures if 'f' is given" do
99
- make_failures_file 'a.rb:1', 'b.rb:2'
104
+ make_failures_file 'a', 'b'
100
105
  app = Respec::App.new('f')
101
- expect(app.generated_args).to eq ['a.rb:1', 'b.rb:2']
106
+ expect(app.generated_args).to eq ['-e', 'a', '-e', 'b', 'spec']
107
+ end
108
+
109
+ it "should pass failures with spaces in them as a single argument" do
110
+ make_failures_file 'a a'
111
+ app = Respec::App.new('f')
112
+ expect(app.generated_args).to eq ['-e', 'a a', 'spec']
102
113
  end
103
114
 
104
115
  it "should find the right failures if the failures file is overridden after the 'f'" do
105
- make_failures_file 'a.rb:1', 'b.rb:2', path: "#{FAIL_PATH}-overridden"
116
+ make_failures_file 'a', 'b', path: "#{FAIL_PATH}-overridden"
106
117
  app = Respec::App.new('f', "FAILURES=#{FAIL_PATH}-overridden")
107
- expect(app.generated_args).to eq ['a.rb:1', 'b.rb:2']
118
+ expect(app.generated_args).to eq ['-e', 'a', '-e', 'b', 'spec']
108
119
  end
109
120
 
110
121
  it "should run the n-th failure if a numeric argument 'n' is given" do
111
- make_failures_file 'a.rb:1', 'b.rb:2'
122
+ make_failures_file 'a', 'b'
112
123
  app = Respec::App.new('2')
113
- expect(app.generated_args).to eq ['b.rb:2']
124
+ expect(app.generated_args).to eq ['-e', 'b', 'spec']
114
125
  end
115
126
 
116
127
  it "should interpret existing file names as file name arguments" do
@@ -126,23 +137,22 @@ describe Respec::App do
126
137
  end
127
138
 
128
139
  it "should treat other arguments as example names" do
129
- FileUtils.touch "#{tmp}/FILE"
130
- app = Respec::App.new("#{tmp}/FILE")
131
- expect(app.generated_args).to eq ["#{tmp}/FILE"]
140
+ app = Respec::App.new('a', 'b')
141
+ expect(app.generated_args).to eq ['-e', 'a', '-e', 'b', 'spec']
132
142
  end
133
143
 
134
- it "should not include named files if a numeric argument is given" do
144
+ it "should include named files when a numeric argument is given" do
135
145
  FileUtils.touch "#{tmp}/FILE"
136
- make_failures_file 'a.rb:1'
146
+ make_failures_file 'a'
137
147
  app = Respec::App.new("#{tmp}/FILE", '1')
138
- expect(app.generated_args).to eq ['a.rb:1']
148
+ expect(app.generated_args).to eq ['-e', 'a', "#{tmp}/FILE"]
139
149
  end
140
150
 
141
- it "should not include named files if an 'f' argument is given" do
151
+ it "should include named files when an 'f' argument is given" do
142
152
  FileUtils.touch "#{tmp}/FILE"
143
- make_failures_file 'a.rb:1'
153
+ make_failures_file 'a'
144
154
  app = Respec::App.new("#{tmp}/FILE", 'f')
145
- expect(app.generated_args).to eq ['a.rb:1']
155
+ expect(app.generated_args).to eq ['-e', 'a', "#{tmp}/FILE"]
146
156
  end
147
157
 
148
158
  it "should explicitly add the spec directory if no files are given or errors to rerun" do
@@ -156,16 +166,16 @@ describe Respec::App do
156
166
  expect(app.generated_args).to eq ["#{tmp}/FILE"]
157
167
  end
158
168
 
159
- it "should not add the spec directory if a numeric argument is given" do
160
- make_failures_file 'a.rb:1'
169
+ it "should add the spec directory if a numeric argument is given without explicit files" do
170
+ make_failures_file 'a'
161
171
  app = Respec::App.new('1')
162
- expect(app.generated_args).to eq ["a.rb:1"]
172
+ expect(app.generated_args).to eq ['-e', 'a', 'spec']
163
173
  end
164
174
 
165
- it "should not add the spec directory if an 'f' argument is given" do
166
- make_failures_file 'a.rb:1'
175
+ it "should add the spec directory when an 'f' argument is given without explicit files" do
176
+ make_failures_file 'a'
167
177
  app = Respec::App.new('f')
168
- expect(app.generated_args).to eq ["a.rb:1"]
178
+ expect(app.generated_args).to eq ['-e', 'a', 'spec']
169
179
  end
170
180
  end
171
181
 
@@ -1,29 +1,57 @@
1
- require File.expand_path('../spec_helper', File.dirname(__FILE__))
1
+ require_relative '../spec_helper'
2
+ require 'rspec/version'
2
3
 
3
4
  describe Respec::Formatter do
4
- describe ".extract_spec_location" do
5
- use_attribute_value RSpec.configuration, :pattern, "**/*_spec.rb"
5
+ use_temporary_directory TMP
6
+ let(:formatter) { Respec::Formatter.new }
6
7
 
7
- it "should find the spec file for normal examples" do
8
- metadata = {:location => './spec/models/user_spec.rb:47'}
9
- expect(described_class.extract_spec_location(metadata)).
10
- to eq './spec/models/user_spec.rb:47'
11
- end
8
+ def failures
9
+ File.read("#{TMP}/failures.txt")
10
+ end
12
11
 
13
- it "should find the spec file for shared examples" do
14
- metadata = {
15
- :location => './spec/support/breadcrumbs.rb:75',
16
- :example_group => {:location => './spec/requests/breadcrumbs_spec.rb:218'},
17
- }
18
- expect(described_class.extract_spec_location(metadata)).
19
- to eq './spec/requests/breadcrumbs_spec.rb:218'
20
- end
12
+ describe Respec::Formatter do
13
+ if (RSpec::Core::Version::STRING.scan(/\d+/).map { |s| s.to_i } <=> [3]) < 0
14
+
15
+ before { Respec.stub(failures_path: "#{TMP}/failures.txt") }
16
+
17
+ def make_failing_example(description)
18
+ metadata = {full_description: description}
19
+ mock(RSpec::Core::Example.allocate, metadata: metadata)
20
+ end
21
+
22
+ it "records failed example names and dumps them at the end" do
23
+ failed_examples = [make_failing_example('example 1'), make_failing_example('example 2')]
24
+ formatter.instance_variable_set(:@failed_examples, failed_examples)
25
+ formatter.start_dump
26
+ expect(failures).to eq "example 1\nexample 2\n"
27
+ end
28
+
29
+ it "empties the failure file if no examples failed" do
30
+ formatter.start_dump
31
+ expect(failures).to eq ''
32
+ end
33
+
34
+ else
35
+
36
+ before { allow(Respec).to receive(:failures_path).and_return("#{TMP}/failures.txt") }
37
+
38
+ def make_failure_notification(description)
39
+ example = double(RSpec::Core::Example.allocate, full_description: description)
40
+ RSpec::Core::Notifications::FailedExampleNotification.new(example)
41
+ end
42
+
43
+ it "records failed example names and dumps them at the end" do
44
+ formatter.example_failed(make_failure_notification('example 1'))
45
+ formatter.example_failed(make_failure_notification('example 2'))
46
+ formatter.start_dump(RSpec::Core::Notifications::NullNotification)
47
+ expect(failures).to eq "example 1\nexample 2\n"
48
+ end
49
+
50
+ it "empties the failure file if no examples failed" do
51
+ formatter.start_dump(RSpec::Core::Notifications::NullNotification)
52
+ expect(failures).to eq ''
53
+ end
21
54
 
22
- it "should warn when no spec file is found, and return the root location" do
23
- Respec::Formatter.should_receive(:warn)
24
- metadata = {:location => './spec/models/user.rb:47'}
25
- expect(described_class.extract_spec_location(metadata)).
26
- to eq './spec/models/user.rb:47'
27
55
  end
28
56
  end
29
57
  end
@@ -1,6 +1,6 @@
1
- $:.unshift File.expand_path('../lib', File.dirname(__FILE__))
2
- require 'respec'
3
- require 'temporaries'
4
-
5
1
  ROOT = File.expand_path('..', File.dirname(__FILE__))
6
2
  TMP = "#{ROOT}/spec/tmp"
3
+
4
+ $:.unshift "#{ROOT}/lib"
5
+ require 'respec'
6
+ require 'temporaries'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: respec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - George Ogata
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-16 00:00:00.000000000 Z
11
+ date: 2015-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -16,42 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '2.11'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '2.0'
27
- - !ruby/object:Gem::Dependency
28
- name: ritual
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0.4'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '0.4'
41
- - !ruby/object:Gem::Dependency
42
- name: temporaries
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.4'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.4'
26
+ version: '2.11'
55
27
  description:
56
28
  email:
57
29
  - george.ogata@gmail.com
@@ -97,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
69
  version: '0'
98
70
  requirements: []
99
71
  rubyforge_project:
100
- rubygems_version: 2.2.2
72
+ rubygems_version: 2.4.5
101
73
  signing_key:
102
74
  specification_version: 4
103
75
  summary: Rerun failing RSpec examples easily.