respec 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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.