rspec-interactive 0.2.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +10 -10
- data/README.md +35 -31
- data/bin/rspec-interactive +17 -1
- data/bin/test +2 -0
- data/examples/failing_spec.rb +0 -4
- data/examples/other_passing_spec.rb +11 -0
- data/examples/spec_with_syntax_error.rb +5 -0
- data/lib/rspec-interactive.rb +84 -73
- data/lib/rspec-interactive/config.rb +23 -0
- data/lib/rspec-interactive/rspec_command.rb +2 -45
- data/lib/rspec-interactive/{config_cache.rb → rspec_config_cache.rb} +0 -0
- data/lib/rspec-interactive/runner.rb +37 -45
- data/lib/rspec-interactive/version.rb +1 -1
- data/rspec-interactive.gemspec +3 -3
- data/scripts/release.sh +25 -0
- data/scripts/run-with-local-dep.sh +36 -0
- data/tests/debugged_spec_test.rb +75 -0
- data/tests/eof_test.rb +10 -0
- data/tests/example_file_test.rb +54 -0
- data/tests/failing_spec_test.rb +41 -0
- data/tests/glob_test.rb +18 -0
- data/tests/line_number_test.rb +19 -0
- data/tests/passing_spec_test.rb +18 -0
- data/tests/rerun_failed_specs_test.rb +90 -0
- data/tests/spec_with_syntax_error_test.rb +30 -0
- data/tests/support/ansi.rb +32 -0
- data/tests/support/test_helper.rb +286 -0
- metadata +28 -23
@@ -0,0 +1,23 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Interactive
|
3
|
+
class Configuration
|
4
|
+
attr_accessor :watch_dirs, :configure_rspec, :on_class_load
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@watch_dirs = []
|
8
|
+
@configure_rspec = proc {}
|
9
|
+
@on_class_load = proc {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure_rspec(&block)
|
13
|
+
return @configure_rspec unless block
|
14
|
+
@configure_rspec = block
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_class_load(&block)
|
18
|
+
return @on_class_load unless block
|
19
|
+
@on_class_load = block
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -12,54 +12,11 @@ module RSpec::Interactive
|
|
12
12
|
BANNER
|
13
13
|
|
14
14
|
command_options(
|
15
|
-
:keep_retval =>
|
15
|
+
:keep_retval => false
|
16
16
|
)
|
17
17
|
|
18
18
|
def process
|
19
|
-
|
20
|
-
if arg.match(/[\*\?\[]/)
|
21
|
-
glob = Dir.glob(arg)
|
22
|
-
glob.empty? ? [arg] : glob
|
23
|
-
else
|
24
|
-
[arg]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
RSpec::Interactive.mutex.synchronize do
|
29
|
-
RSpec::Interactive.updated_files.uniq.each do |filename|
|
30
|
-
load filename
|
31
|
-
end
|
32
|
-
RSpec::Interactive.updated_files.clear
|
33
|
-
end
|
34
|
-
|
35
|
-
RSpec::Interactive.runner = RSpec::Interactive::Runner.new(parsed_args)
|
36
|
-
|
37
|
-
# Stop saving history in case a new Pry session is started for debugging.
|
38
|
-
Pry.config.history_save = false
|
39
|
-
|
40
|
-
# Run.
|
41
|
-
result = RSpec::Interactive.runner.run
|
42
|
-
RSpec::Interactive.runner = nil
|
43
|
-
|
44
|
-
# Save results
|
45
|
-
RSpec::Interactive.results << result
|
46
|
-
RSpec::Interactive.result = result
|
47
|
-
|
48
|
-
# Reenable history
|
49
|
-
Pry.config.history_save = true
|
50
|
-
|
51
|
-
# Reset
|
52
|
-
RSpec.clear_examples
|
53
|
-
RSpec.reset
|
54
|
-
RSpec::Interactive.config_cache.replay_configuration
|
55
|
-
|
56
|
-
Object.define_method :results do RSpec::Interactive.results end
|
57
|
-
Object.define_method :result do RSpec::Interactive.result end
|
58
|
-
|
59
|
-
puts "Result available at `result`. Result history available at `results`."
|
60
|
-
puts
|
61
|
-
|
62
|
-
result
|
19
|
+
RSpec::Interactive.rspec(args)
|
63
20
|
end
|
64
21
|
|
65
22
|
Pry::Commands.add_command(::RSpec::Interactive::RSpecCommand)
|
File without changes
|
@@ -2,75 +2,67 @@ require 'rspec/core'
|
|
2
2
|
|
3
3
|
module RSpec
|
4
4
|
module Interactive
|
5
|
-
class ExampleGroupResult
|
6
|
-
attr_accessor :group, :success
|
7
|
-
|
8
|
-
def initialize(group, success)
|
9
|
-
@group = group
|
10
|
-
@success = success
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class Result
|
15
|
-
attr_accessor :groups, :success, :exit_code
|
16
|
-
|
17
|
-
def initialize(groups, success, exit_code)
|
18
|
-
@groups = groups
|
19
|
-
@success = success
|
20
|
-
@exit_code = exit_code
|
21
|
-
end
|
22
|
-
|
23
|
-
def inspect(original = false)
|
24
|
-
original ? super() : "<RSpec::Interactive::Result @success=#{@success}, @groups=[...]>"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
5
|
class Runner
|
29
6
|
def initialize(args)
|
30
|
-
RSpec.world.wants_to_quit = false
|
31
|
-
@options = RSpec::Core::ConfigurationOptions.new(args)
|
7
|
+
::RSpec.world.wants_to_quit = false
|
8
|
+
@options = ::RSpec::Core::ConfigurationOptions.new(args)
|
32
9
|
end
|
33
10
|
|
34
11
|
def run()
|
35
12
|
begin
|
36
|
-
@options.configure(RSpec.configuration)
|
37
|
-
return if RSpec.world.wants_to_quit
|
13
|
+
@options.configure(::RSpec.configuration)
|
14
|
+
return if ::RSpec.world.wants_to_quit
|
38
15
|
|
39
|
-
RSpec.configuration.load_spec_files
|
16
|
+
::RSpec.configuration.load_spec_files
|
40
17
|
ensure
|
41
|
-
RSpec.world.announce_filters
|
18
|
+
::RSpec.world.announce_filters
|
42
19
|
end
|
43
20
|
|
44
|
-
return RSpec.configuration.reporter.exit_early(RSpec.configuration.failure_exit_code) if RSpec.world.wants_to_quit
|
21
|
+
return ::RSpec.configuration.reporter.exit_early(::RSpec.configuration.failure_exit_code) if ::RSpec.world.wants_to_quit
|
45
22
|
|
46
|
-
example_groups = RSpec.world.ordered_example_groups
|
47
|
-
examples_count = RSpec.world.example_count(example_groups)
|
23
|
+
example_groups = ::RSpec.world.ordered_example_groups
|
24
|
+
examples_count = ::RSpec.world.example_count(example_groups)
|
48
25
|
|
49
|
-
|
50
|
-
RSpec.configuration.with_suite_hooks do
|
51
|
-
if examples_count == 0 && RSpec.configuration.fail_if_no_examples
|
52
|
-
return RSpec.configuration.failure_exit_code
|
26
|
+
exit_code = ::RSpec.configuration.reporter.report(examples_count) do |reporter|
|
27
|
+
::RSpec.configuration.with_suite_hooks do
|
28
|
+
if examples_count == 0 && ::RSpec.configuration.fail_if_no_examples
|
29
|
+
return ::RSpec.configuration.failure_exit_code
|
53
30
|
end
|
54
31
|
|
55
|
-
|
56
|
-
|
57
|
-
ExampleGroupResult.new(example_group, group_success)
|
32
|
+
group_results = example_groups.map do |example_group|
|
33
|
+
example_group.run(reporter)
|
58
34
|
end
|
59
35
|
|
60
|
-
success =
|
36
|
+
success = group_results.all?
|
61
37
|
exit_code = success ? 0 : 1
|
62
|
-
if RSpec.world.non_example_failure
|
38
|
+
if ::RSpec.world.non_example_failure
|
63
39
|
success = false
|
64
|
-
exit_code = RSpec.configuration.failure_exit_code
|
40
|
+
exit_code = ::RSpec.configuration.failure_exit_code
|
65
41
|
end
|
66
|
-
|
42
|
+
persist_example_statuses
|
43
|
+
exit_code
|
67
44
|
end
|
68
45
|
end
|
69
|
-
|
46
|
+
|
47
|
+
if exit_code != 0 && ::RSpec.configuration.example_status_persistence_file_path
|
48
|
+
::RSpec.configuration.output_stream.puts "Rerun failures by executing the previous command with --only-failures or --next-failure."
|
49
|
+
::RSpec.configuration.output_stream.puts
|
50
|
+
end
|
51
|
+
|
52
|
+
exit_code
|
70
53
|
end
|
71
54
|
|
72
55
|
def quit
|
73
|
-
RSpec.world.wants_to_quit = true
|
56
|
+
::RSpec.world.wants_to_quit = true
|
57
|
+
end
|
58
|
+
|
59
|
+
def persist_example_statuses
|
60
|
+
return if ::RSpec.configuration.dry_run
|
61
|
+
return unless (path = ::RSpec.configuration.example_status_persistence_file_path)
|
62
|
+
|
63
|
+
::RSpec::Core::ExampleStatusPersister.persist(::RSpec.world.all_examples, path)
|
64
|
+
rescue SystemCallError => e
|
65
|
+
::RSpec.configuration.error_stream.puts "warning: failed to write results to #{path}"
|
74
66
|
end
|
75
67
|
end
|
76
68
|
end
|
data/rspec-interactive.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.executables << 'rspec-interactive'
|
26
26
|
spec.require_paths = ["lib"]
|
27
27
|
|
28
|
-
spec.add_dependency 'rspec-core'
|
29
|
-
spec.add_dependency 'listen'
|
30
|
-
spec.add_dependency 'pry'
|
28
|
+
spec.add_dependency 'rspec-core'
|
29
|
+
spec.add_dependency 'listen'
|
30
|
+
spec.add_dependency 'pry'
|
31
31
|
end
|
data/scripts/release.sh
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
if [ $# -ne 1 ]; then
|
6
|
+
echo "usage: $0 <version>" >&2
|
7
|
+
exit 1
|
8
|
+
fi
|
9
|
+
|
10
|
+
if [ -n "$(git status --porcelain)" ]; then
|
11
|
+
echo "error: stage or commit your changes." >&2
|
12
|
+
exit 1;
|
13
|
+
fi
|
14
|
+
|
15
|
+
NEW_VERSION=$1
|
16
|
+
CURRENT_VERSION=$(grep VERSION lib/rspec-interactive/version.rb | cut -d'"' -f 2)
|
17
|
+
|
18
|
+
echo "Updating from v$CURRENT_VERSION to v$NEW_VERSION. Press enter to continue."
|
19
|
+
read
|
20
|
+
|
21
|
+
sed -E -i '' "s/VERSION = \"[^\"]+\"/VERSION = \"$NEW_VERSION\"/g" lib/rspec-interactive/version.rb
|
22
|
+
gem build
|
23
|
+
gem push rspec-interactive-$NEW_VERSION.gem
|
24
|
+
bundle install
|
25
|
+
git commit -a -m "v$NEW_VERSION Release"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# Used to quickly test a development version of a gem in the current
|
4
|
+
# directory. Adds a local copy of the specified gem, at the specified
|
5
|
+
# path, to the current directory's Gemfile and executes the specified
|
6
|
+
# command. Upon completion, the Gemfile will be returned to its
|
7
|
+
# previous state.
|
8
|
+
|
9
|
+
if [ $# -ne 3 ]; then
|
10
|
+
echo "usage: $0 <gem-name> <path> <command>" >&2
|
11
|
+
exit 1
|
12
|
+
fi
|
13
|
+
|
14
|
+
GEM_NAME=$1
|
15
|
+
GEM_PATH=$2
|
16
|
+
COMMAND=$3
|
17
|
+
|
18
|
+
if [ -d $GEM_NAME ]; then
|
19
|
+
echo "directory exists: $GEM_NAME" >&2
|
20
|
+
exit 1
|
21
|
+
fi
|
22
|
+
|
23
|
+
OLD_DEP=$(grep "'$GEM_NAME'" Gemfile)
|
24
|
+
if [ $? -ne 0 ]; then
|
25
|
+
echo "$GEM_NAME not found in Gemfile" >&2
|
26
|
+
exit 1
|
27
|
+
fi
|
28
|
+
|
29
|
+
cp Gemfile Gemfile.save
|
30
|
+
cp Gemfile.lock Gemfile.lock.save
|
31
|
+
cp -R $GEM_PATH $GEM_NAME
|
32
|
+
sed -i '' -E "s/^( *gem '$GEM_NAME').*/\1, path: '$GEM_NAME'/g" Gemfile
|
33
|
+
$COMMAND
|
34
|
+
rm -rf $GEM_NAME
|
35
|
+
mv Gemfile.lock.save Gemfile.lock
|
36
|
+
mv Gemfile.save Gemfile
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative 'support/test_helper'
|
2
|
+
|
3
|
+
Test.test "debugged spec" do
|
4
|
+
await_prompt
|
5
|
+
input "rspec examples/debugged_spec.rb"
|
6
|
+
await_prompt
|
7
|
+
input "exit"
|
8
|
+
await_prompt
|
9
|
+
input "exit"
|
10
|
+
await_termination
|
11
|
+
expect_output <<~EOF
|
12
|
+
[1] pry(main)> rspec examples/debugged_spec.rb
|
13
|
+
|
14
|
+
From: /Users/nickdower/Development/rspec-interactive/examples/debugged_spec.rb:6 :
|
15
|
+
|
16
|
+
1: require 'rspec/core'
|
17
|
+
2: require 'pry'
|
18
|
+
3:
|
19
|
+
4: describe "example spec" do
|
20
|
+
5: it "gets debugged" do
|
21
|
+
=> 6: binding.pry
|
22
|
+
7: expect(true).to eq(true)
|
23
|
+
8: end
|
24
|
+
9: end
|
25
|
+
|
26
|
+
[1] pry(#<RSpec::ExampleGroups::ExampleSpec>)> exit
|
27
|
+
.
|
28
|
+
|
29
|
+
Finished in 0 seconds (files took 0 seconds to load)
|
30
|
+
1 example, 0 failures
|
31
|
+
|
32
|
+
[2] pry(main)> exit
|
33
|
+
EOF
|
34
|
+
end
|
35
|
+
|
36
|
+
Test.test "debugger does not add to history" do
|
37
|
+
await_prompt
|
38
|
+
input "rspec examples/debugged_spec.rb"
|
39
|
+
await_prompt
|
40
|
+
input '"this should not show up in history"'
|
41
|
+
await_prompt
|
42
|
+
input "exit"
|
43
|
+
await_prompt
|
44
|
+
input "exit"
|
45
|
+
await_termination
|
46
|
+
expect_output <<~EOF
|
47
|
+
[1] pry(main)> rspec examples/debugged_spec.rb
|
48
|
+
|
49
|
+
From: /Users/nickdower/Development/rspec-interactive/examples/debugged_spec.rb:6 :
|
50
|
+
|
51
|
+
1: require 'rspec/core'
|
52
|
+
2: require 'pry'
|
53
|
+
3:
|
54
|
+
4: describe "example spec" do
|
55
|
+
5: it "gets debugged" do
|
56
|
+
=> 6: binding.pry
|
57
|
+
7: expect(true).to eq(true)
|
58
|
+
8: end
|
59
|
+
9: end
|
60
|
+
|
61
|
+
[1] pry(#<RSpec::ExampleGroups::ExampleSpec>)> "this should not show up in history"
|
62
|
+
=> "this should not show up in history"
|
63
|
+
[2] pry(#<RSpec::ExampleGroups::ExampleSpec>)> exit
|
64
|
+
.
|
65
|
+
|
66
|
+
Finished in 0 seconds (files took 0 seconds to load)
|
67
|
+
1 example, 0 failures
|
68
|
+
|
69
|
+
[2] pry(main)> exit
|
70
|
+
EOF
|
71
|
+
|
72
|
+
expect_history <<~EOF
|
73
|
+
rspec examples/debugged_spec.rb
|
74
|
+
EOF
|
75
|
+
end
|
data/tests/eof_test.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative 'support/test_helper'
|
2
|
+
|
3
|
+
Test.test "exiting via ctrl-d" do
|
4
|
+
await_prompt
|
5
|
+
ctrl_d
|
6
|
+
await_termination
|
7
|
+
# No newlines in tests because we return false from tty? in test_helper.rb.
|
8
|
+
# In the real app, Pry will add a newline because tty? is true.
|
9
|
+
expect_output '[1] pry(main)> '
|
10
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative 'support/test_helper'
|
2
|
+
|
3
|
+
RSpec.configuration.backtrace_exclusion_patterns = [ /.*/ ]
|
4
|
+
RSpec.configuration.backtrace_inclusion_patterns = [ /examples\/failing_spec.rb/ ]
|
5
|
+
|
6
|
+
examples = Tempfile.new('examples')
|
7
|
+
|
8
|
+
config = Tempfile.new('config')
|
9
|
+
config.write <<~EOF
|
10
|
+
RSpec.configuration.example_status_persistence_file_path = "#{examples.path}"
|
11
|
+
EOF
|
12
|
+
config.rewind
|
13
|
+
|
14
|
+
Test.test "failing spec with example file", config_path: config.path do
|
15
|
+
await_prompt
|
16
|
+
input "rspec examples/failing_spec.rb"
|
17
|
+
await_prompt
|
18
|
+
input "exit"
|
19
|
+
await_termination
|
20
|
+
expect_output <<~EOF
|
21
|
+
[1] pry(main)> rspec examples/failing_spec.rb
|
22
|
+
F
|
23
|
+
|
24
|
+
Failures:
|
25
|
+
|
26
|
+
1) example spec fails
|
27
|
+
Failure/Error: expect(true).to eq(false)
|
28
|
+
|
29
|
+
expected: false
|
30
|
+
got: true
|
31
|
+
|
32
|
+
(compared using ==)
|
33
|
+
|
34
|
+
Diff:
|
35
|
+
@@ -1 +1 @@
|
36
|
+
-false
|
37
|
+
+true
|
38
|
+
# ./examples/failing_spec.rb:5:in `block (2 levels) in <top (required)>'
|
39
|
+
|
40
|
+
Finished in 0 seconds (files took 0 seconds to load)
|
41
|
+
1 example, 1 failure
|
42
|
+
|
43
|
+
Failed examples:
|
44
|
+
|
45
|
+
rspec ./examples/failing_spec.rb:4 # example spec fails
|
46
|
+
|
47
|
+
Rerun failures by executing the previous command with --only-failures or --next-failure.
|
48
|
+
|
49
|
+
[2] pry(main)> exit
|
50
|
+
EOF
|
51
|
+
end
|
52
|
+
|
53
|
+
config.close
|
54
|
+
examples.close
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative 'support/test_helper'
|
2
|
+
|
3
|
+
RSpec.configuration.backtrace_exclusion_patterns = [ /.*/ ]
|
4
|
+
RSpec.configuration.backtrace_inclusion_patterns = [ /examples\/failing_spec.rb/ ]
|
5
|
+
|
6
|
+
Test.test "failing spec" do
|
7
|
+
await_prompt
|
8
|
+
input "rspec examples/failing_spec.rb"
|
9
|
+
await_prompt
|
10
|
+
input "exit"
|
11
|
+
await_termination
|
12
|
+
expect_output <<~EOF
|
13
|
+
[1] pry(main)> rspec examples/failing_spec.rb
|
14
|
+
F
|
15
|
+
|
16
|
+
Failures:
|
17
|
+
|
18
|
+
1) example spec fails
|
19
|
+
Failure/Error: expect(true).to eq(false)
|
20
|
+
|
21
|
+
expected: false
|
22
|
+
got: true
|
23
|
+
|
24
|
+
(compared using ==)
|
25
|
+
|
26
|
+
Diff:
|
27
|
+
@@ -1 +1 @@
|
28
|
+
-false
|
29
|
+
+true
|
30
|
+
# ./examples/failing_spec.rb:5:in `block (2 levels) in <top (required)>'
|
31
|
+
|
32
|
+
Finished in 0 seconds (files took 0 seconds to load)
|
33
|
+
1 example, 1 failure
|
34
|
+
|
35
|
+
Failed examples:
|
36
|
+
|
37
|
+
rspec ./examples/failing_spec.rb:4 # example spec fails
|
38
|
+
|
39
|
+
[2] pry(main)> exit
|
40
|
+
EOF
|
41
|
+
end
|