rspec-interactive 0.5.0 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
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