respec 0.0.1

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/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /*.gem
data/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ == 0.0.1 2012-05-17
2
+
3
+ * Hi.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) George Ogata
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,63 @@
1
+ ## Respec
2
+
3
+ Provides a command, `respec`, which wraps `rspec`, and records your
4
+ failing examples for easy rerunning.
5
+
6
+ ## How?
7
+
8
+ Run your specs:
9
+
10
+ respec
11
+
12
+ 3 fail. Rerun just the 3 failures like this:
13
+
14
+ respec f
15
+
16
+ Need to debug failure #1? Pop a `debugger` in your code, and rerun it
17
+ like this:
18
+
19
+ respec 1
20
+
21
+ This will just rerun failure 1. Once it's passing, rerun the 3 failing
22
+ examples again:
23
+
24
+ respec f
25
+
26
+ 1 is now fixed, but 2 and 3 are still failing - `respec f` will now
27
+ only run failures 2 and 3 again.
28
+
29
+ ## How it works
30
+
31
+ All that's happening is the list of failed examples is being recorded
32
+ in a file (`.respec_failures`). The `f` argument means "run these
33
+ recorded failures only." A numeric argument like `1` means "just run
34
+ that failure."
35
+
36
+ The list of failed examples is always updated _except_ when selecting
37
+ which failures to rerun with a number (more than one number can also
38
+ be given, incidentally).
39
+
40
+ ## Other tricks
41
+
42
+ You can pass `respec` file or directory names, just like
43
+ `rspec`. However, you can also just specify example names on the
44
+ command line:
45
+
46
+ respec 'My example name'
47
+
48
+ If the argument doesn't name an existing file, it's assumed to be an
49
+ example name.
50
+
51
+ There are a few other shortcuts. Do `respec --help` to see them all.
52
+
53
+ ## Contributing
54
+
55
+ * [Bug reports](https://github.com/oggy/respec/issues)
56
+ * [Source](https://github.com/oggy/respec)
57
+ * Patches: Fork on Github, send pull request.
58
+ * Include tests where practical.
59
+ * Leave the version alone, or bump it in a separate commit.
60
+
61
+ ## Copyright
62
+
63
+ Copyright (c) George Ogata. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'ritual'
data/bin/respec ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'respec'
4
+
5
+ app = Respec::App.new(*ARGV)
6
+ if app.help_only?
7
+ STDERR.puts app.help
8
+ else
9
+ STDERR.puts "++ #{app.command.join(' ')}"
10
+ exec *app.command
11
+ end
data/lib/respec.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Respec
2
+ autoload :VERSION, 'respec/version'
3
+ autoload :App, 'respec/app'
4
+ autoload :Formatter, 'respec/formatter'
5
+ end
data/lib/respec/app.rb ADDED
@@ -0,0 +1,117 @@
1
+ module Respec
2
+ class App
3
+ def initialize(*args)
4
+ if (i = args.index('--'))
5
+ @args = args.slice!(0...i)
6
+ @raw_args = args[1..-1]
7
+ else
8
+ @args = args
9
+ @raw_args = []
10
+ end
11
+ @formatter = 'progress'
12
+ @output_failures = true
13
+ process_args
14
+ end
15
+
16
+ def command
17
+ @command ||= ['rspec'] + formatter_args + generated_args + raw_args
18
+ end
19
+
20
+ def formatter_args
21
+ if @output_failures
22
+ formatter_path = File.expand_path('formatter.rb', File.dirname(__FILE__))
23
+ ['--require', formatter_path, '--format', 'Respec::Formatter', '--out', failures_path, '--format', @formatter]
24
+ else
25
+ []
26
+ end
27
+ end
28
+
29
+ attr_reader :generated_args, :raw_args
30
+
31
+ class << self
32
+ attr_accessor :failures_path
33
+ end
34
+ self.failures_path = ENV['RESPEC_FAILURES'] || File.expand_path("~/.respec_failures")
35
+
36
+ def help_only?
37
+ @help_only
38
+ end
39
+
40
+ def help
41
+ <<-EOS.gsub(/^ *\|/, '')
42
+ |USAGE: respec RESPEC-ARGS ... [ -- RSPEC-ARGS ... ]
43
+ |
44
+ |Run rspec recording failed examples for easy rerunning later.
45
+ |
46
+ |RESPEC-ARGS may consist of:
47
+ |
48
+ | f Rerun all failed examples
49
+ | <integer> Rerun only the n-th failure
50
+ | s Output specdoc format, instead of progress
51
+ | c Output context diffs
52
+ | <file name> Run specs in these files
53
+ | <other> Run only examples matching this pattern
54
+ | --help This! (Also 'help'.)
55
+ |
56
+ |RSPEC-ARGS may follow a '--' argument, and are passed
57
+ |directly to rspec.
58
+ |
59
+ |More info: http://github.com/oggy/respec
60
+ EOS
61
+ end
62
+
63
+ private
64
+
65
+ def process_args
66
+ args = []
67
+ files = []
68
+ @args.each do |arg|
69
+ if File.exist?(arg)
70
+ files << arg
71
+ elsif arg =~ /\A(--)?help\z/
72
+ @help_only = true
73
+ elsif arg == 'f'
74
+ if File.exist?(failures_path)
75
+ if failures.empty?
76
+ abort "No specs failed!"
77
+ else
78
+ failures.each do |line|
79
+ args << line.strip
80
+ end
81
+ end
82
+ else
83
+ warn "no fail file - ignoring 'f' argument"
84
+ end
85
+ elsif arg == 's'
86
+ @formatter = 'specdoc'
87
+ elsif arg == 'c'
88
+ args << '--diff' << 'context'
89
+ elsif arg =~ /\A\d+\z/
90
+ i = Integer(arg)
91
+ if (failure = failures[i - 1])
92
+ args << failure
93
+ @output_failures = false
94
+ else
95
+ warn "invalid failure: #{i} for (1..#{failures.size})"
96
+ end
97
+ else
98
+ args << '--example' << arg.gsub(/[$]/, '\\\\\\0')
99
+ end
100
+ end
101
+ @generated_args = args + files
102
+ end
103
+
104
+ def failures_path
105
+ self.class.failures_path
106
+ end
107
+
108
+ def failures
109
+ @failures ||=
110
+ if File.exist?(failures_path)
111
+ File.read(failures_path).split(/\n/)
112
+ else
113
+ []
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,11 @@
1
+ require 'rspec/core/formatters/base_formatter'
2
+
3
+ module Respec
4
+ class Formatter < RSpec::Core::Formatters::BaseFormatter
5
+ def start_dump
6
+ @failed_examples.each do |example|
7
+ output.puts example.metadata[:location]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Respec
2
+ VERSION = [0, 0, 1]
3
+
4
+ class << VERSION
5
+ include Comparable
6
+
7
+ def to_s
8
+ join('.')
9
+ end
10
+ end
11
+ end
data/respec.gemspec ADDED
@@ -0,0 +1,17 @@
1
+ $:.unshift File.expand_path('lib', File.dirname(__FILE__))
2
+ require 'respec/version'
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'respec'
6
+ gem.version = Respec::VERSION
7
+ gem.authors = ['George Ogata']
8
+ gem.email = ['george.ogata@gmail.com']
9
+ gem.summary = "Rerun failing RSpec examples easily."
10
+ gem.homepage = 'http://github.com/oggy/respec'
11
+
12
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+
16
+ gem.add_development_dependency 'ritual', '~> 0.4.0'
17
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'spec_helper'
2
+ require 'rbconfig'
3
+
4
+ describe Respec do
5
+ CONFIG = (Object.const_defined?(:RbConfig) ? RbConfig : Config)::CONFIG
6
+ def respec(args)
7
+ ruby = File.join(CONFIG['bindir'], CONFIG['ruby_install_name'])
8
+ respec = "#{ROOT}/bin/respec"
9
+ output = `RESPEC_FAILURES=#{TMP}/failures.txt #{ruby} -I #{ROOT}/lib #{respec} #{args} 2>&1`
10
+ [$?, output]
11
+ end
12
+
13
+ def make_spec(params)
14
+ num_failures = params[:num_failures] or
15
+ raise ArgumentError, "expected :num_failures parameter"
16
+
17
+ source = "describe 'test' do\n"
18
+ (0...2).map do |i|
19
+ if i < num_failures
20
+ source << " it('#{i}') { 1.should == 2 }\n"
21
+ else
22
+ source << " it('#{i}') {}\n"
23
+ end
24
+ end
25
+ source << "end"
26
+ open(spec_path, 'w') { |f| f.puts source }
27
+ end
28
+
29
+ def spec_path
30
+ "#{TMP}/test_spec.rb"
31
+ end
32
+
33
+ it "should let you rerun failing specs until they all pass" do
34
+ make_spec(num_failures: 2)
35
+ status, output = respec(spec_path)
36
+ status.should_not be_success
37
+ output.should include('2 examples, 2 failures')
38
+
39
+ make_spec(num_failures: 1)
40
+ status, output = respec("#{spec_path} f")
41
+ status.should_not be_success
42
+ output.should include('2 examples, 1 failure')
43
+
44
+ make_spec(num_failures: 0)
45
+ status, output = respec("#{spec_path} f")
46
+ status.should be_success
47
+ output.should include('1 example, 0 failures')
48
+ end
49
+ end
@@ -0,0 +1,91 @@
1
+ require_relative '../spec_helper'
2
+
3
+ require 'fileutils'
4
+
5
+ describe Respec::App do
6
+ FORMATTER_PATH = File.expand_path("#{ROOT}/lib/respec/formatter.rb", File.dirname(__FILE__))
7
+ FAIL_PATH = "#{TMP}/failures.txt"
8
+
9
+ Respec::App.failures_path = FAIL_PATH
10
+
11
+ def make_failures_file(*examples)
12
+ open Respec::App.failures_path, 'w' do |file|
13
+ examples.each do |example|
14
+ file.puts example
15
+ end
16
+ end
17
+ end
18
+
19
+ describe "#generated_args" do
20
+ it "should run with --context if 'c' is given" do
21
+ app = Respec::App.new('c')
22
+ app.generated_args.should == ['--diff', 'context']
23
+ end
24
+
25
+ it "should run all failures if 'f' is given" do
26
+ make_failures_file 'a.rb:1', 'b.rb:2'
27
+ app = Respec::App.new('f')
28
+ app.generated_args.should == ['a.rb:1', 'b.rb:2']
29
+ end
30
+
31
+ it "should run the n-th failure if a numeric argument 'n' is given" do
32
+ make_failures_file 'a.rb:1', 'b.rb:2'
33
+ app = Respec::App.new('2')
34
+ app.generated_args.should == ['b.rb:2']
35
+ end
36
+
37
+ it "should interpret existing file names as file name arguments" do
38
+ FileUtils.touch "#{TMP}/existing.rb"
39
+ app = Respec::App.new("#{TMP}/existing.rb")
40
+ app.generated_args.should == ["#{TMP}/existing.rb"]
41
+ end
42
+
43
+ it "should treat other arguments as example names" do
44
+ FileUtils.touch "#{TMP}/FILE"
45
+ app = Respec::App.new("#{TMP}/FILE")
46
+ app.generated_args.should == ["#{TMP}/FILE"]
47
+ end
48
+ end
49
+
50
+ describe "#formatter_args" do
51
+ it "should include the respec and progress formatters by default" do
52
+ app = Respec::App.new
53
+ app.formatter_args.should == ['--require', FORMATTER_PATH, '--format', 'Respec::Formatter', '--out', FAIL_PATH, '--format', 'progress']
54
+ end
55
+
56
+ it "should include '--format specdoc' if an 's' argument is given" do
57
+ app = Respec::App.new('s')
58
+ app.formatter_args.should == ['--require', FORMATTER_PATH, '--format', 'Respec::Formatter', '--out', FAIL_PATH, '--format', 'specdoc']
59
+ end
60
+
61
+ it "should update the stored failures if no args are given" do
62
+ app = Respec::App.new
63
+ app.formatter_args.should == ['--require', FORMATTER_PATH, '--format', 'Respec::Formatter', '--out', FAIL_PATH, '--format', 'progress']
64
+ end
65
+
66
+ it "should update the stored failures if 'f' is used" do
67
+ app = Respec::App.new('f')
68
+ app.formatter_args.should == ['--require', FORMATTER_PATH, '--format', 'Respec::Formatter', '--out', FAIL_PATH, '--format', 'progress']
69
+ end
70
+
71
+ it "should not update the stored failures if a numeric argument is given" do
72
+ app = Respec::App.new('1')
73
+ app.formatter_args.should == []
74
+ end
75
+ end
76
+
77
+ describe "#raw_args" do
78
+ it "should pass arguments after '--' directly to rspec" do
79
+ app = Respec::App.new('--', '--blah')
80
+ app.raw_args.should == ['--blah']
81
+ end
82
+ end
83
+
84
+ describe "#command" do
85
+ it "should combine all the args" do
86
+ make_failures_file 'a.rb:1'
87
+ app = Respec::App.new('f', '--', '-t', 'TAG')
88
+ app.command.should == ['rspec', '--require', FORMATTER_PATH, '--format', 'Respec::Formatter', '--out', FAIL_PATH, '--format', 'progress', 'a.rb:1', '-t', 'TAG']
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift File.expand_path('../lib', File.dirname(__FILE__))
2
+ require 'respec'
3
+ require 'tmpdir'
4
+
5
+ ROOT = File.expand_path('..', File.dirname(__FILE__))
6
+ TMP = Dir.tmpdir
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: respec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - George Ogata
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ritual
16
+ requirement: &70131397136780 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.4.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70131397136780
25
+ description:
26
+ email:
27
+ - george.ogata@gmail.com
28
+ executables:
29
+ - respec
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - CHANGELOG
35
+ - Gemfile
36
+ - LICENSE
37
+ - README.markdown
38
+ - Rakefile
39
+ - bin/respec
40
+ - lib/respec.rb
41
+ - lib/respec/app.rb
42
+ - lib/respec/formatter.rb
43
+ - lib/respec/version.rb
44
+ - respec.gemspec
45
+ - spec/integration_spec.rb
46
+ - spec/respec/app_spec.rb
47
+ - spec/spec_helper.rb
48
+ homepage: http://github.com/oggy/respec
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 1.8.10
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Rerun failing RSpec examples easily.
72
+ test_files:
73
+ - spec/integration_spec.rb
74
+ - spec/respec/app_spec.rb
75
+ - spec/spec_helper.rb
76
+ has_rdoc: