rspec-interactive 0.2.0 → 0.6.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 +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
|