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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88fe45587c743f490177b20ef35c1a6372c56b22e631ca8d5bf24fb5836448bc
4
- data.tar.gz: 23bd0531b2836fb9d3d6d86a462fe65b4f9ddde3b2671db608f1b76fbaf7989b
3
+ metadata.gz: 4e56b91e4f1d28feae7da156d8e4f3ddec5aeffe5847f0ecf6c28150f9f2ac1d
4
+ data.tar.gz: 9b88b87a123b207b1478413b0e963bee0a25255163977cd2982cd8d9a0d21742
5
5
  SHA512:
6
- metadata.gz: a066316a818ebaf46096e655d5e20c87280ae47863aeae564e275b066647b004afad528e40e0cc4dbe56935f6bd3c9275541302893b2fbd77c2eb01c84cdbf9c
7
- data.tar.gz: 45d608d8bf7524a575bf833be24bcd13ec3ea6d2612da9ef40d7da5f9366fb43474eb078ab56c88f61c45d67143515a140d9d8de094e418906895cb277393386
6
+ metadata.gz: a5acd4df05e27db03f66f66f96f9cc43692485abbfe04ee5e680589689c274bde396f07c893b2138cea6db745a4fcc2b9a127caaf7a8c0ccb7c5a2acedd60b6e
7
+ data.tar.gz: 534a6ba41f06820271a60a5844fc72e19bb92730067bda01d84ad791fd5c99ce35b4f94b60badb862a7f5de183dbc5a799bfb8280f07162660e99a1b186d74d1
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ ruby '3.0.0'
4
+
3
5
  source "https://rubygems.org"
4
6
 
5
7
  gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-interactive (0.5.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
- An Pry console capable of running specs.
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
- See more examples below.
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 spec/rspec_interactive.rb
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
+ ```
@@ -1,14 +1,20 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'optparse'
3
4
  require 'rspec-interactive'
4
5
 
5
- if ARGV.size == 0
6
- RSpec::Interactive.start
7
- elsif ARGV.size == 1
8
- RSpec::Interactive.start(config_file: ARGV[0])
9
- else
10
- STDERR.puts "expected 0 or 1 argument, got: #{args.join(', ')}"
11
- STDERR.puts ''
12
- STDOUT.puts 'usage: rspec-interactive [config-file]'
13
- exit 1
14
- end
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])
@@ -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, removed|
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.rspec(args)
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 "modified: #{filename}"
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module Interactive
5
- VERSION = "0.5.0"
5
+ VERSION = "0.7.2"
6
6
  end
7
7
  end
@@ -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)"
@@ -7,7 +7,11 @@ examples = Tempfile.new('examples')
7
7
 
8
8
  config = Tempfile.new('config')
9
9
  config.write <<~EOF
10
- RSpec.configuration.example_status_persistence_file_path = "#{examples.path}"
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.configuration.example_status_persistence_file_path = "#{examples.path}"
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.5.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-20 00:00:00.000000000 Z
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
- - run-with-local-dep.sh
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