rspec-interactive 0.5.0 → 0.7.2
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 +2 -0
- data/Gemfile.lock +4 -1
- data/README.md +48 -7
- data/bin/rspec-interactive +16 -10
- data/lib/rspec-interactive.rb +39 -16
- data/lib/rspec-interactive/config.rb +7 -1
- data/lib/rspec-interactive/refresh_command.rb +22 -0
- data/lib/rspec-interactive/version.rb +1 -1
- data/scripts/release.sh +28 -0
- data/{run-with-local-dep.sh → scripts/run-with-local-dep.sh} +0 -0
- data/tests/example_file_test.rb +5 -1
- data/tests/rerun_failed_specs_test.rb +6 -2
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e56b91e4f1d28feae7da156d8e4f3ddec5aeffe5847f0ecf6c28150f9f2ac1d
|
4
|
+
data.tar.gz: 9b88b87a123b207b1478413b0e963bee0a25255163977cd2982cd8d9a0d21742
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5acd4df05e27db03f66f66f96f9cc43692485abbfe04ee5e680589689c274bde396f07c893b2138cea6db745a4fcc2b9a127caaf7a8c0ccb7c5a2acedd60b6e
|
7
|
+
data.tar.gz: 534a6ba41f06820271a60a5844fc72e19bb92730067bda01d84ad791fd5c99ce35b4f94b60badb862a7f5de183dbc5a799bfb8280f07162660e99a1b186d74d1
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rspec-interactive (0.
|
4
|
+
rspec-interactive (0.7.1)
|
5
5
|
listen
|
6
6
|
pry
|
7
7
|
rspec-core
|
@@ -36,5 +36,8 @@ DEPENDENCIES
|
|
36
36
|
rspec-expectations
|
37
37
|
rspec-interactive!
|
38
38
|
|
39
|
+
RUBY VERSION
|
40
|
+
ruby 3.0.0p0
|
41
|
+
|
39
42
|
BUNDLED WITH
|
40
43
|
2.2.17
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# RSpec Interactive
|
2
2
|
|
3
|
-
|
3
|
+
A Pry console capable of running specs.
|
4
4
|
|
5
5
|
## Installation & Configuration
|
6
6
|
|
@@ -13,13 +13,11 @@ gem 'rspec-interactive'
|
|
13
13
|
Add a config file which configures RSpec and RSpec::Interactive, for example `spec/rspec_interactive.rb`:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
load 'spec/spec_helper.rb'
|
17
|
-
|
18
16
|
RSpec::Interactive.configure do |config|
|
19
17
|
# Directories to watch for file changes. When a file changes, it will be reloaded like `load 'path/to/file'`.
|
20
18
|
config.watch_dirs += ["app", "lib", "config"]
|
21
19
|
|
22
|
-
# This block is invoked on startup. RSpec configuration must happen here so that it can be reloaded before each test run.
|
20
|
+
# This block is invoked on startup. RSpec configuration must happen here so that it can be cached and reloaded before each test run.
|
23
21
|
config.configure_rspec do
|
24
22
|
require './spec/spec_helper.rb'
|
25
23
|
end
|
@@ -28,6 +26,13 @@ RSpec::Interactive.configure do |config|
|
|
28
26
|
config.on_class_load do |clazz|
|
29
27
|
clazz.clear_validators! if clazz < ApplicationRecord
|
30
28
|
end
|
29
|
+
|
30
|
+
# Invoked before each invocation of RSpec. Can also be manually invoked by typing `refresh` in the console.
|
31
|
+
# Any modified/added files will be loaded via `load` before invoking.
|
32
|
+
config.refresh do
|
33
|
+
FactoryBot.reload
|
34
|
+
Rails.application.reloader.reload!
|
35
|
+
end
|
31
36
|
end
|
32
37
|
```
|
33
38
|
|
@@ -37,12 +42,37 @@ Update `.gitignore`
|
|
37
42
|
echo '.rspec_interactive_history' >> .gitignore
|
38
43
|
```
|
39
44
|
|
45
|
+
### A Note About FactoryBot
|
46
|
+
|
47
|
+
It is not possible to reload a file containing FactoryBot factory definitions via `load` because FactoryBot does not allow factories to be redefined. Be carefule not to add any directories to `watch_dirs` which contain factory definitions. Instead, you should configure the location of your factories like the following in your `spec_helper.rb`:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
FactoryBot.definition_file_paths = %w(spec/factories)
|
51
|
+
FactoryBot.find_definitions # Only if not using Rails
|
52
|
+
```
|
53
|
+
|
54
|
+
Then add the following to your RSpec Interactive config
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
RSpec::Interactive.configure do |config|
|
58
|
+
config.refresh do
|
59
|
+
FactoryBot.reload
|
60
|
+
end
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
This will cause factories to be reloaded before each test run and also whenever the `refresh` command is invoked in the console.
|
65
|
+
|
66
|
+
See: https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#configure-your-test-suite
|
67
|
+
|
68
|
+
See: https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#rails-preloaders-and-rspec
|
69
|
+
|
40
70
|
## Usage
|
41
71
|
|
42
|
-
|
72
|
+
Optionally, specify a config file with `--config <config-file>`. Optionally, specify arguments to an initial RSpec invocation with `--initial-rspec-args <initial-rspec-args>`.
|
43
73
|
|
44
74
|
```shell
|
45
|
-
bundle exec rspec-interactive
|
75
|
+
bundle exec rspec-interactive [--config <config-file>] [--initial-rspec-args <initial-rspec-args>]
|
46
76
|
```
|
47
77
|
|
48
78
|
## Example Usage In This Repo
|
@@ -53,6 +83,12 @@ Start:
|
|
53
83
|
bundle exec rspec-interactive
|
54
84
|
```
|
55
85
|
|
86
|
+
Start with an initial RSpec invocation:
|
87
|
+
|
88
|
+
```shell
|
89
|
+
bundle exec rspec-interactive --initial-rspec-args examples/passing_spec.rb
|
90
|
+
```
|
91
|
+
|
56
92
|
Run a passing spec:
|
57
93
|
|
58
94
|
```shell
|
@@ -76,7 +112,6 @@ Run multiple specs:
|
|
76
112
|
```shell
|
77
113
|
[6] pry(main)> rspec examples/passing_spec.rb examples/failing_spec.rb
|
78
114
|
```
|
79
|
-
|
80
115
|
Debug a spec (use `exit` to resume while debugging):
|
81
116
|
|
82
117
|
```shell
|
@@ -100,3 +135,9 @@ Exit:
|
|
100
135
|
```shell
|
101
136
|
bundle exec bin/test
|
102
137
|
```
|
138
|
+
|
139
|
+
## Releasing
|
140
|
+
|
141
|
+
```shell
|
142
|
+
./scripts/release.sh <version>
|
143
|
+
```
|
data/bin/rspec-interactive
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require 'optparse'
|
3
4
|
require 'rspec-interactive'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
@options = {}
|
7
|
+
parser = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Starts an interactive RSpec shell.\n\n"\
|
9
|
+
"Usage: bundle exec rspec-interactive [-c config-file] <initial-rspec-args>"
|
10
|
+
|
11
|
+
opts.on("-c", "--config <config-file>", String, "Optional. Path to the RSpec Interactive config file.") do |config_file|
|
12
|
+
@options[:config_file] = config_file
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on("-r", "--initial-rspec-args <initial-rspec-args>", String, "Optional. Arguments to pass to an initial invocation of RSpec.") do |initial_rspec_args|
|
16
|
+
@options[:initial_rspec_args] = initial_rspec_args
|
17
|
+
end
|
18
|
+
end.parse!
|
19
|
+
|
20
|
+
RSpec::Interactive.start(config_file: @options[:config_file], initial_rspec_args: @options[:initial_rspec_args])
|
data/lib/rspec-interactive.rb
CHANGED
@@ -3,11 +3,13 @@ require 'listen'
|
|
3
3
|
require 'pry'
|
4
4
|
require 'readline'
|
5
5
|
require 'rspec/core'
|
6
|
+
require 'shellwords'
|
6
7
|
|
7
8
|
require 'rspec-interactive/runner'
|
8
9
|
require 'rspec-interactive/config'
|
9
10
|
require 'rspec-interactive/rspec_config_cache'
|
10
11
|
require 'rspec-interactive/input_completer'
|
12
|
+
require 'rspec-interactive/refresh_command'
|
11
13
|
require 'rspec-interactive/rspec_command'
|
12
14
|
|
13
15
|
module RSpec
|
@@ -23,7 +25,7 @@ module RSpec
|
|
23
25
|
block.call(@configuration)
|
24
26
|
end
|
25
27
|
|
26
|
-
def self.start(config_file: nil, history_file: DEFAULT_HISTORY_FILE, input_stream: STDIN, output_stream: STDOUT, error_stream: STDERR)
|
28
|
+
def self.start(config_file: nil, initial_rspec_args: nil, history_file: DEFAULT_HISTORY_FILE, input_stream: STDIN, output_stream: STDOUT, error_stream: STDERR)
|
27
29
|
@history_file = history_file
|
28
30
|
@updated_files = []
|
29
31
|
@stty_save = %x`stty -g`.chomp
|
@@ -36,13 +38,20 @@ module RSpec
|
|
36
38
|
@configuration = Configuration.new
|
37
39
|
load config_file if config_file
|
38
40
|
|
39
|
-
@config_cache.record_configuration { @configuration.configure_rspec.call }
|
40
|
-
|
41
41
|
check_rails
|
42
|
-
start_file_watcher
|
43
42
|
trap_interrupt
|
44
43
|
configure_pry
|
45
44
|
|
45
|
+
@init_thread = Thread.start {
|
46
|
+
@config_cache.record_configuration { @configuration.configure_rspec.call }
|
47
|
+
start_file_watcher
|
48
|
+
}
|
49
|
+
|
50
|
+
if initial_rspec_args
|
51
|
+
open(@history_file, 'a') { |f| f.puts "rspec #{initial_rspec_args.strip}" }
|
52
|
+
rspec Shellwords.split(initial_rspec_args)
|
53
|
+
end
|
54
|
+
|
46
55
|
Pry.start
|
47
56
|
@listener.stop if @listener
|
48
57
|
0
|
@@ -80,7 +89,7 @@ module RSpec
|
|
80
89
|
return if @configuration.watch_dirs.empty?
|
81
90
|
|
82
91
|
# Only polling seems to work in Docker.
|
83
|
-
@listener = Listen.to(*@configuration.watch_dirs, only: /\.rb$/, force_polling: true) do |modified, added
|
92
|
+
@listener = Listen.to(*@configuration.watch_dirs, only: /\.rb$/, force_polling: true) do |modified, added|
|
84
93
|
@mutex.synchronize do
|
85
94
|
@updated_files.concat(added + modified)
|
86
95
|
end
|
@@ -104,19 +113,10 @@ module RSpec
|
|
104
113
|
Pry.config.history_file = @history_file
|
105
114
|
end
|
106
115
|
|
107
|
-
def self.
|
108
|
-
parsed_args = args.flat_map do |arg|
|
109
|
-
if arg.match(/[\*\?\[]/)
|
110
|
-
glob = Dir.glob(arg)
|
111
|
-
glob.empty? ? [arg] : glob
|
112
|
-
else
|
113
|
-
[arg]
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
116
|
+
def self.refresh
|
117
117
|
@mutex.synchronize do
|
118
118
|
@updated_files.uniq.each do |filename|
|
119
|
-
@output_stream.puts "
|
119
|
+
@output_stream.puts "changed: #{filename}"
|
120
120
|
trace = TracePoint.new(:class) do |tp|
|
121
121
|
@configuration.on_class_load.call(tp.self)
|
122
122
|
end
|
@@ -127,9 +127,30 @@ module RSpec
|
|
127
127
|
end
|
128
128
|
@updated_files.clear
|
129
129
|
end
|
130
|
+
@configuration.refresh.call
|
131
|
+
end
|
130
132
|
|
133
|
+
def self.rspec(args)
|
134
|
+
parsed_args = args.flat_map do |arg|
|
135
|
+
if arg.match(/[\*\?\[]/)
|
136
|
+
glob = Dir.glob(arg)
|
137
|
+
glob.empty? ? [arg] : glob
|
138
|
+
else
|
139
|
+
[arg]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Initialize the runner before waiting for the init thread so that the interrupt
|
144
|
+
# handler will cancel the RSpec invocation rather than kill the app.
|
131
145
|
@runner = RSpec::Interactive::Runner.new(parsed_args)
|
132
146
|
|
147
|
+
if @init_thread&.alive?
|
148
|
+
@init_thread.join
|
149
|
+
@init_thread = nil
|
150
|
+
end
|
151
|
+
|
152
|
+
refresh
|
153
|
+
|
133
154
|
# Stop saving history in case a new Pry session is started for debugging.
|
134
155
|
Pry.config.history_save = false
|
135
156
|
|
@@ -147,6 +168,8 @@ module RSpec
|
|
147
168
|
RSpec.clear_examples
|
148
169
|
RSpec.reset
|
149
170
|
@config_cache.replay_configuration
|
171
|
+
ensure
|
172
|
+
@runner = nil
|
150
173
|
end
|
151
174
|
end
|
152
175
|
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Interactive
|
3
3
|
class Configuration
|
4
|
-
attr_accessor :watch_dirs, :configure_rspec, :on_class_load
|
4
|
+
attr_accessor :watch_dirs, :configure_rspec, :on_class_load, :refresh
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
@watch_dirs = []
|
8
8
|
@configure_rspec = proc {}
|
9
9
|
@on_class_load = proc {}
|
10
|
+
@refresh = proc {}
|
10
11
|
end
|
11
12
|
|
12
13
|
def configure_rspec(&block)
|
@@ -18,6 +19,11 @@ module RSpec
|
|
18
19
|
return @on_class_load unless block
|
19
20
|
@on_class_load = block
|
20
21
|
end
|
22
|
+
|
23
|
+
def refresh(&block)
|
24
|
+
return @refresh unless block
|
25
|
+
@refresh = block
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
23
29
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec::Interactive
|
4
|
+
class RefreshCommand < Pry::ClassCommand
|
5
|
+
match 'refresh'
|
6
|
+
description "Load any files in watched directories which have changed since the last refresh or rspec invocation."
|
7
|
+
|
8
|
+
banner <<-BANNER
|
9
|
+
Usage: refresh
|
10
|
+
BANNER
|
11
|
+
|
12
|
+
command_options(
|
13
|
+
:keep_retval => false
|
14
|
+
)
|
15
|
+
|
16
|
+
def process
|
17
|
+
RSpec::Interactive.refresh
|
18
|
+
end
|
19
|
+
|
20
|
+
Pry::Commands.add_command(::RSpec::Interactive::RefreshCommand)
|
21
|
+
end
|
22
|
+
end
|
data/scripts/release.sh
ADDED
@@ -0,0 +1,28 @@
|
|
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
|
+
bundle exec bin/test
|
19
|
+
|
20
|
+
echo "Updating from v$CURRENT_VERSION to v$NEW_VERSION. Press enter to continue."
|
21
|
+
read
|
22
|
+
|
23
|
+
sed -E -i '' "s/VERSION = \"[^\"]+\"/VERSION = \"$NEW_VERSION\"/g" lib/rspec-interactive/version.rb
|
24
|
+
gem build
|
25
|
+
gem push rspec-interactive-$NEW_VERSION.gem
|
26
|
+
bundle install
|
27
|
+
git commit -a -m "v$NEW_VERSION Release"
|
28
|
+
open "https://github.com/nicholasdower/rspec-interactive/releases/new?title=v$NEW_VERSION%20Release&tag=v$NEW_VERSION&target=$(git rev-parse HEAD)"
|
File without changes
|
data/tests/example_file_test.rb
CHANGED
@@ -7,7 +7,11 @@ examples = Tempfile.new('examples')
|
|
7
7
|
|
8
8
|
config = Tempfile.new('config')
|
9
9
|
config.write <<~EOF
|
10
|
-
RSpec.
|
10
|
+
RSpec::Interactive.configure do |config|
|
11
|
+
config.configure_rspec do
|
12
|
+
RSpec.configuration.example_status_persistence_file_path = "#{examples.path}"
|
13
|
+
end
|
14
|
+
end
|
11
15
|
EOF
|
12
16
|
config.rewind
|
13
17
|
|
@@ -4,11 +4,15 @@ examples = Tempfile.new('examples')
|
|
4
4
|
|
5
5
|
config = Tempfile.new('config')
|
6
6
|
config.write <<~EOF
|
7
|
-
RSpec.
|
7
|
+
RSpec::Interactive.configure do |config|
|
8
|
+
config.configure_rspec do
|
9
|
+
RSpec.configuration.example_status_persistence_file_path = "#{examples.path}"
|
10
|
+
end
|
11
|
+
end
|
8
12
|
EOF
|
9
13
|
config.rewind
|
10
14
|
|
11
|
-
Test.test "failing spec with example file", config_path: config.path do
|
15
|
+
Test.test "rerun failing spec with example file", config_path: config.path do
|
12
16
|
await_prompt
|
13
17
|
|
14
18
|
RSpec.configuration.backtrace_exclusion_patterns = [ /.*/ ]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-interactive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Dower
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec-core
|
@@ -78,12 +78,14 @@ files:
|
|
78
78
|
- lib/rspec-interactive.rb
|
79
79
|
- lib/rspec-interactive/config.rb
|
80
80
|
- lib/rspec-interactive/input_completer.rb
|
81
|
+
- lib/rspec-interactive/refresh_command.rb
|
81
82
|
- lib/rspec-interactive/rspec_command.rb
|
82
83
|
- lib/rspec-interactive/rspec_config_cache.rb
|
83
84
|
- lib/rspec-interactive/runner.rb
|
84
85
|
- lib/rspec-interactive/version.rb
|
85
86
|
- rspec-interactive.gemspec
|
86
|
-
-
|
87
|
+
- scripts/release.sh
|
88
|
+
- scripts/run-with-local-dep.sh
|
87
89
|
- tests/debugged_spec_test.rb
|
88
90
|
- tests/eof_test.rb
|
89
91
|
- tests/example_file_test.rb
|