rspec-interactive 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cc41d7480a29852c93f700e92b70314e0b6e8fc70f73089ca419eae750f32bc
4
- data.tar.gz: b7b3357dbf44d8dc21beef28a684950f148eac98aa40b4de53e2eb7faa9eb2e9
3
+ metadata.gz: 6034dc7e5c24528799a1fd53510f0eba5f0d2d599b9e9736371a8ee210319d68
4
+ data.tar.gz: 343e1fcaa3d42dbcfbb5b12dbfb8b6c33e7c44e80a2bfafdf22b9934ba63e986
5
5
  SHA512:
6
- metadata.gz: f6413fa767a8c4dd85e6f63129d35b9b341a264ae82183696d5c160f63cada92fe96b17972913246bea85b9fb5217b19d0bfd72c4dc1a0a3152a38861cb011de
7
- data.tar.gz: 9a42fc226690f04ea027d5cf42403164cbd0cd7f3dae80a9eec4383ef1d3c5f36d40e4f9291432366f449e0651b19b91d1b54c88b6b455cd906b73ae2bad2c08
6
+ metadata.gz: 5af0bad059e46cd7933b3d83f48e2ebac13f6005817e5f7aee96ab3c27a153d89b136ba305881a76fd883c70b5f157534327c74608da4eeb28ed1158259f49c3
7
+ data.tar.gz: c2059760cf7053a80f3465f937bd8a69bff7e49740617c82f2663abe474454d7fee8317996b6ed07ea63618ab2b972b79527fab7bfa9f40e191825e3d79481e8
data/.gitignore CHANGED
@@ -1 +1,3 @@
1
1
  rspec-interactive-*.gem
2
+ .rspec_interactive_history
3
+ .rspec_interactive_config
data/Gemfile CHANGED
@@ -4,4 +4,6 @@ source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
6
 
7
- gem 'rspec-core'
7
+ group :test do
8
+ gem 'rspec-expectations'
9
+ end
data/Gemfile.lock CHANGED
@@ -1,29 +1,40 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-console (0.1.0)
5
- listen
4
+ rspec-interactive (0.1.0)
5
+ listen (~> 3.5, >= 3.5.1)
6
+ pry (~> 0.14.1)
7
+ rspec-core (~> 3.10, >= 3.10.1)
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
9
11
  specs:
12
+ coderay (1.1.3)
13
+ diff-lcs (1.4.4)
10
14
  ffi (1.15.0)
11
15
  listen (3.5.1)
12
16
  rb-fsevent (~> 0.10, >= 0.10.3)
13
17
  rb-inotify (~> 0.9, >= 0.9.10)
18
+ method_source (1.0.0)
19
+ pry (0.14.1)
20
+ coderay (~> 1.1)
21
+ method_source (~> 1.0)
14
22
  rb-fsevent (0.11.0)
15
23
  rb-inotify (0.10.1)
16
24
  ffi (~> 1.0)
17
25
  rspec-core (3.10.1)
18
26
  rspec-support (~> 3.10.0)
27
+ rspec-expectations (3.10.1)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.10.0)
19
30
  rspec-support (3.10.2)
20
31
 
21
32
  PLATFORMS
22
33
  x86_64-darwin-20
23
34
 
24
35
  DEPENDENCIES
25
- rspec-console!
26
- rspec-core
36
+ rspec-expectations
37
+ rspec-interactive!
27
38
 
28
39
  BUNDLED WITH
29
40
  2.2.17
data/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # RSpec Interactive
2
+
3
+ **WARNING: New (or maybe old by now), experimental, untested and poorly documented. Use at your own risk.**
4
+
5
+ An Pry console capable of running specs.
6
+
7
+ ## Installation & Configuration
8
+
9
+ Install:
10
+
11
+ ```ruby
12
+ gem 'rspec-interactive'
13
+ ```
14
+
15
+ Add a config file named `.rspec_interactive_config`:
16
+
17
+ ```json
18
+ {
19
+ "configs": [
20
+ {
21
+ "name": "spec",
22
+ "watch_dirs": ["app"],
23
+ "init_script": "spec/spec_helper.rb"
24
+ },
25
+ {
26
+ "name": "spec_integration",
27
+ "watch_dirs": ["app"],
28
+ "init_script": "spec_integration/integration_helper.rb"
29
+ }
30
+ ]
31
+ }
32
+ ```
33
+
34
+ Update `.gitignore`
35
+
36
+ ```shell
37
+ echo '.rspec_interactive_history' >> .gitignore
38
+ ```
39
+
40
+ ## Usage
41
+
42
+ See more examples below.
43
+
44
+ ```shell
45
+ bundle exec rspec-interactive [spec name]
46
+ ```
47
+
48
+ ## Example Usage In This Repo
49
+
50
+ Start:
51
+
52
+ ```shell
53
+ bundle exec rspec-interactive
54
+ ```
55
+
56
+ Run a passing spec:
57
+
58
+ ```shell
59
+ [1] pry(main)> rspec examples/passing_spec.rb
60
+ ```
61
+
62
+ Inspect the result:
63
+
64
+ ```shell
65
+ [2] pry(main)> result
66
+ ```
67
+
68
+ Run a failing spec:
69
+
70
+ ```shell
71
+ [3] pry(main)> rspec examples/failing_spec.rb
72
+ ```
73
+
74
+ Inspect result history:
75
+
76
+ ```shell
77
+ [4] pry(main)> results
78
+ ```
79
+
80
+ Run an example group:
81
+
82
+ ```shell
83
+ [5] pry(main)> rspec examples/passing_spec.rb:4
84
+ ```
85
+
86
+ Run multiple specs:
87
+
88
+ ```shell
89
+ [6] pry(main)> rspec examples/passing_spec.rb examples/failing_spec.rb
90
+ ```
91
+
92
+ Debug a spec (use `exit` to resume while debugging):
93
+
94
+ ```shell
95
+ [7] pry(main)> rspec examples/debugged_spec.rb
96
+ ```
97
+
98
+ Run multiple specs using globbing (use `exit` to resume while debugging):
99
+
100
+ ```shell
101
+ [8] pry(main)> rspec examples/*_spec.rb
102
+ ```
103
+
104
+ Exit:
105
+
106
+ ```shell
107
+ [9] pry(main)> exit
108
+ ```
data/bin/console CHANGED
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "bundler/setup"
5
- require "repo"
5
+ require 'rspec-interactive'
6
6
 
7
7
  # You can add fixtures and/or initialization code here to make experimenting
8
8
  # with your gem easier. You can also use a different console, if you like.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'rspec-interactive.rb'
3
+ require 'rspec-interactive'
4
4
 
5
- RSpecInteractive::Console.new(ARGV).start()
5
+ RSpec::Interactive.start(ARGV)
@@ -0,0 +1,9 @@
1
+ require 'rspec/core'
2
+ require 'pry'
3
+
4
+ describe "example spec" do
5
+ it "gets debugged" do
6
+ binding.pry
7
+ expect(true).to eq(true)
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require 'rspec/core'
2
+
3
+ describe "example spec" do
4
+ it "fails" do
5
+ expect(true).to eq(false)
6
+ end
7
+
8
+ it "fails again" do
9
+ expect(true).to eq(false)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'rspec/core'
2
+
3
+ describe "example spec" do
4
+ it "succeeds" do
5
+ expect(true).to eq(true)
6
+ end
7
+
8
+ it "succeeds again" do
9
+ expect(true).to eq(true)
10
+ end
11
+ end
@@ -4,52 +4,73 @@ require 'json'
4
4
  require 'listen'
5
5
  require 'readline'
6
6
  require 'rspec/core'
7
- require 'shellwords'
7
+ require 'pry'
8
8
 
9
- require_relative 'rspec-interactive/runner.rb'
9
+ require 'rspec-interactive/runner'
10
+ require 'rspec-interactive/config_cache'
11
+ require 'rspec-interactive/input_completer'
12
+ require 'rspec-interactive/rspec_command'
10
13
 
11
- module RSpecInteractive
12
- class Console
14
+ module RSpec
15
+ module Interactive
13
16
 
14
17
  HISTORY_FILE = '.rspec_interactive_history'.freeze
15
18
  CONFIG_FILE = '.rspec_interactive_config'.freeze
16
- MAX_HISTORY_ITEMS = 100
17
- COMMANDS = ['help', 'rspec']
18
19
 
19
- def initialize(args)
20
+ class <<self
21
+ attr_accessor :config, :stty_save, :mutex, :config_cache, :runner, :results, :result, :updated_files
22
+ end
23
+
24
+ def self.start(args)
20
25
  if args.size > 1
21
26
  STDERR.puts "expected 0 or 1 argument, got: #{args.join(', ')}"
22
27
  exit!(1)
23
28
  end
24
29
 
30
+ @updated_files = []
31
+ @results = []
32
+ @config = get_config(args[0])
25
33
  @stty_save = %x`stty -g`.chomp
26
34
  @mutex = Mutex.new
27
- @runner = nil
28
- load_config(args[0])
29
- end
35
+ @config_cache = RSpec::Interactive::ConfigCache.new
30
36
 
31
- def start()
37
+ load_rspec_config
38
+ check_rails
32
39
  start_file_watcher
33
- load_history
34
- configure_auto_complete
35
40
  trap_interrupt
36
- start_console
41
+ configure_pry
42
+
43
+ Pry.start
37
44
  end
38
45
 
39
- private
46
+ def self.check_rails
47
+ if defined?(::Rails)
48
+ if ::Rails.application.config.cache_classes
49
+ STDERR.puts "warning: Rails.application.config.cache_classes enabled. Disable to ensure code is reloaded."
50
+ end
51
+ end
52
+ end
40
53
 
41
- def load_config(name = nil)
42
- @config = get_config(name)
43
- load @config["init_script"]
54
+ def self.load_rspec_config
55
+ @config_cache.record_configuration(&rspec_configuration)
44
56
  end
45
57
 
46
- def get_config(name = nil)
47
- if !File.exists? CONFIG_FILE
48
- STDERR.puts "file not found: #{CONFIG_FILE}"
49
- exit!(1)
58
+ def self.rspec_configuration
59
+ proc do
60
+ if @config["init_script"]
61
+ $LOAD_PATH << '.'
62
+ require @config["init_script"]
63
+ end
64
+ end
65
+ end
66
+
67
+ def self.get_config(name = nil)
68
+ unless File.exists? CONFIG_FILE
69
+ STDERR.puts "warning: #{CONFIG_FILE} not found, using default config"
70
+ return {}
50
71
  end
51
72
 
52
- configs = JSON.parse(File.read(CONFIG_FILE))["configs"]
73
+ configs = JSON.parse(File.read(CONFIG_FILE))["configs"] || []
53
74
  if configs.empty?
54
75
  STDERR.puts "no configs found in: #{CONFIG_FILE}"
55
76
  exit!(1)
@@ -83,123 +104,42 @@ module RSpecInteractive
83
104
  end
84
105
  end
85
106
 
86
- def trap_interrupt
107
+ def self.trap_interrupt
87
108
  trap('INT') do
88
- @mutex.synchronize do
89
- if @runner
90
- @runner.quit
91
- else
92
- puts
93
- system "stty", @stty_save
94
- exit!(0)
95
- end
96
- end
97
- end
98
- end
99
-
100
- def start_file_watcher
101
- # Only polling seems to work in Docker.
102
- listener = Listen.to(*@config["watch_dirs"], only: /\.rb$/, force_polling: true) do |modified, added, removed|
103
- (added + modified).each { |filename| load filename }
104
- end
105
- end
106
-
107
- def load_history
108
- if File.exists? HISTORY_FILE
109
- lines = File.readlines(HISTORY_FILE)
110
- lines.each do |line|
111
- Readline::HISTORY << line.strip
112
- end
113
- end
114
- end
115
-
116
- def configure_auto_complete
117
- Readline.completion_append_character = ""
118
- end
119
-
120
- def start_console
121
- loop do
122
- buffer = Readline.readline('> ', true)&.strip
123
-
124
- # Exit on ctrl-D.
125
- if !buffer
109
+ if @runner
110
+ # We are on a different thread. There is a race here. Ignore nil.
111
+ @runner&.quit
112
+ else
126
113
  puts
127
114
  system "stty", @stty_save
128
115
  exit!(0)
129
116
  end
130
-
131
- # Ignore blank lines.
132
- if buffer.empty?
133
- Readline::HISTORY.pop
134
- next
135
- end
136
-
137
- # Write history to file.
138
- if Readline::HISTORY.size > 0
139
- file = File.open(HISTORY_FILE, 'w')
140
- lines = Readline::HISTORY.to_a
141
- lines[-[MAX_HISTORY_ITEMS, lines.size].min..-1].each do |line|
142
- file.write(line.strip + "\n")
143
- end
144
- file.close
145
- end
146
-
147
- # Handle quoting, etc.
148
- args = Shellwords.shellsplit(buffer)
149
- next if args.empty?
150
-
151
- command = args[0].strip
152
- if COMMANDS.include?(command)
153
- send command.to_sym, args[1..-1]
154
- else
155
- STDERR.puts "command not found: #{args[0]}"
156
- end
157
117
  end
158
118
  end
159
119
 
160
- def help(args)
161
- if !args.empty?
162
- STDERR.puts "invalid argument(s): #{args}"
163
- return
164
- end
165
-
166
- print "commands:\n\n"
167
- print "help - print this message\n"
168
- print "rspec - execute the specified spec file(s), wildcards allowed\n"
169
- end
120
+ def self.start_file_watcher
121
+ return unless @config["watch_dirs"]
170
122
 
171
- def rspec(args)
172
- if args.empty?
173
- STDERR.puts "you must specify one or more spec files"
174
- return
123
+ # Only polling seems to work in Docker.
124
+ listener = Listen.to(*@config["watch_dirs"], only: /\.rb$/, force_polling: true) do |modified, added, removed|
125
+ @mutex.synchronize do
126
+ @updated_files.concat(added + modified)
127
+ end
175
128
  end
129
+ listener.start
130
+ end
176
131
 
177
- # Allow wildcards.
178
- filenames = args.flat_map { |filename| Dir.glob(filename) }
179
-
180
- # Store formatters, if any, set by the init script. They will be cleared by RSpec below.
181
- formatters = RSpec.configuration.formatters || []
182
-
183
- # Initialize the runner. Also accessed by the signal handler above.
184
- # RSpecInteractive::Runner sets RSpec.world.wants_to_quit to false. The signal
185
- # handler sets it to true.
186
- @mutex.synchronize { @runner = RSpecInteractive::Runner.new(filenames) }
187
-
188
- # Run the specs.
189
- @runner.run
132
+ def self.configure_pry
133
+ # Prevent Pry from trapping too. It will break ctrl-c handling.
134
+ Pry.config.should_trap_interrupts = false
190
135
 
191
- # Clear the runner.
192
- @mutex.synchronize { @runner = nil }
136
+ # Set Pry to use Readline. This is the default anyway.
137
+ Pry.config.input = Readline
193
138
 
194
- # Clear data from previous run.
195
- RSpec.clear_examples
139
+ # Use custom completer to get file completion.
140
+ Pry.config.completer = RSpec::Interactive::InputCompleter
196
141
 
197
- # Formatters get cleared by clear_examples. I don't understand why but the actual run
198
- # also modifies the list of formatters. Reset them to whatever the init script set.
199
- if !RSpec.configuration.formatters.empty?
200
- raise "internal error. expected formatters to be cleared."
201
- end
202
- formatters.each { |f| RSpec.configuration.add_formatter(f) }
142
+ Pry.config.history_file = HISTORY_FILE
203
143
  end
204
144
  end
205
145
  end
@@ -0,0 +1,96 @@
1
+ # Copied from https://github.com/nviennot/rspec-console/blob/master/lib/rspec-console/config_cache.rb
2
+ class RSpec::Interactive::ConfigCache
3
+ # We have to reset the RSpec.configuration, because it contains a lot of
4
+ # information related to the current test (what's running, what are the
5
+ # different test results, etc).
6
+ #
7
+ # RSpec.configuration gets also loaded with a bunch of stuff from the
8
+ # 'spec/spec_helper.rb' file. Often that instance is extended with other
9
+ # modules (FactoryGirl, Mocha,...) and we don't want to replace requires with
10
+ # load all around the place.
11
+ #
12
+ # Instead, we proxy and record whatever is done to RSpec.configuration during
13
+ # the first invocation of require('spec_helper'). This is done by interposing
14
+ # the RecordingProxy class on of RSpec.configuration.
15
+ attr_accessor :config_proxy, :root_shared_examples
16
+
17
+ class RecordingProxy < Struct.new(:target, :recorded_messages)
18
+ [:include, :extend].each do |method|
19
+ define_method(method) do |*args|
20
+ method_missing(method, *args)
21
+ end
22
+ end
23
+
24
+ def method_missing(method, *args, &block)
25
+ self.recorded_messages << [method, args, block]
26
+ self.target.send(method, *args, &block)
27
+ end
28
+ end
29
+
30
+ def record_configuration(&configuration_block)
31
+ ensure_configuration_setter!
32
+
33
+ original_config = ::RSpec.configuration
34
+ ::RSpec.configuration = RecordingProxy.new(original_config, [])
35
+
36
+ configuration_block.call # spec helper is called during this yield, see #reset
37
+
38
+ self.config_proxy = ::RSpec.configuration
39
+ ::RSpec.configuration = original_config
40
+
41
+ stash_shared_examples
42
+
43
+ forward_rspec_config_singleton_to(self.config_proxy)
44
+ end
45
+
46
+ def replay_configuration
47
+ ::RSpec.configure do |config|
48
+ self.config_proxy.recorded_messages.each do |method, args, block|
49
+ # reporter caches config.output_stream which is not good as it
50
+ # prevents the runner to use a custom stdout.
51
+ next if method == :reporter
52
+ config.send(method, *args, &block)
53
+ end
54
+ end
55
+
56
+ restore_shared_examples
57
+
58
+ forward_rspec_config_singleton_to(self.config_proxy)
59
+ end
60
+
61
+ def has_recorded_config?
62
+ !!self.config_proxy
63
+ end
64
+
65
+ def forward_rspec_config_singleton_to(config_proxy)
66
+ # an old version of rspec-rails/lib/rspec/rails/view_rendering.rb adds
67
+ # methods on the configuration singleton. This takes care of that.
68
+ ::RSpec.configuration.singleton_class
69
+ .send(:define_method, :method_missing, &config_proxy.method(:send))
70
+ end
71
+
72
+ def stash_shared_examples
73
+ self.root_shared_examples = ::RSpec.world.shared_example_group_registry.send(:shared_example_groups).dup
74
+ end
75
+
76
+ def restore_shared_examples
77
+ shared_example_groups = ::RSpec.world.shared_example_group_registry.send(:shared_example_groups)
78
+ shared_example_groups.clear
79
+
80
+ self.root_shared_examples.each do |context, hash|
81
+ hash.each do |name, shared_module|
82
+ shared_example_groups[context][name] = shared_module
83
+ end
84
+ end
85
+ end
86
+
87
+ def ensure_configuration_setter!
88
+ return if RSpec.respond_to?(:configuration=)
89
+
90
+ ::RSpec.instance_eval do
91
+ def self.configuration=(value)
92
+ @configuration = value
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,24 @@
1
+ module RSpec::Interactive
2
+ class InputCompleter < Pry::InputCompleter
3
+
4
+ def rspec_completions(string)
5
+ line = Readline.line_buffer
6
+ before_current = Readline.point == string.length ? '' : line[0..(Readline.point - string.length)]
7
+ before_cursor = line[0..(Readline.point - 1)]
8
+
9
+ if line.match(/^ *rspec +/)
10
+ Dir[string + '*'].map { |filename| File.directory?(filename) ? "#{filename}/" : filename }
11
+ elsif before_current.strip.empty? && "rspec".match(/^#{Regexp.escape(string)}/)
12
+ ["rspec "]
13
+ else
14
+ nil
15
+ end
16
+ end
17
+
18
+ def call(str, options = {})
19
+ rspec_completions = rspec_completions(str)
20
+ return rspec_completions if rspec_completions
21
+ super
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec::Interactive
4
+ class RSpecCommand < Pry::ClassCommand
5
+ match 'rspec'
6
+ description "Invoke RSpec."
7
+
8
+ banner <<-BANNER
9
+ Usage: rspec [arguments]
10
+
11
+ See https://relishapp.com/rspec/rspec-core/docs/command-line.
12
+ BANNER
13
+
14
+ command_options(
15
+ :keep_retval => true
16
+ )
17
+
18
+ def process
19
+ parsed_args = args.flat_map do |arg|
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
63
+ end
64
+
65
+ Pry::Commands.add_command(::RSpec::Interactive::RSpecCommand)
66
+ end
67
+ end
@@ -1,46 +1,77 @@
1
1
  require 'rspec/core'
2
2
 
3
- module RSpecInteractive
4
- class Runner
5
- def initialize(args)
6
- RSpec.world.wants_to_quit = false
7
- @options = RSpec::Core::ConfigurationOptions.new(args)
3
+ module RSpec
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
8
12
  end
9
13
 
10
- def run()
11
- begin
12
- @options.configure(RSpec.configuration)
13
- return if RSpec.world.wants_to_quit
14
+ class Result
15
+ attr_accessor :groups, :success, :exit_code
14
16
 
15
- RSpec.configuration.load_spec_files
16
- ensure
17
- RSpec.world.announce_filters
17
+ def initialize(groups, success, exit_code)
18
+ @groups = groups
19
+ @success = success
20
+ @exit_code = exit_code
18
21
  end
19
22
 
20
- return RSpec.configuration.reporter.exit_early(RSpec.configuration.failure_exit_code) if RSpec.world.wants_to_quit
23
+ def inspect(original = false)
24
+ original ? super() : "<RSpec::Interactive::Result @success=#{@success}, @groups=[...]>"
25
+ end
26
+ end
21
27
 
22
- example_groups = RSpec.world.ordered_example_groups
23
- examples_count = RSpec.world.example_count(example_groups)
28
+ class Runner
29
+ def initialize(args)
30
+ RSpec.world.wants_to_quit = false
31
+ @options = RSpec::Core::ConfigurationOptions.new(args)
32
+ end
24
33
 
25
- success = RSpec.configuration.reporter.report(examples_count) do |reporter|
26
- RSpec.configuration.with_suite_hooks do
27
- if examples_count == 0 && RSpec.configuration.fail_if_no_examples
28
- return RSpec.configuration.failure_exit_code
29
- end
34
+ def run()
35
+ begin
36
+ @options.configure(RSpec.configuration)
37
+ return if RSpec.world.wants_to_quit
30
38
 
31
- result = example_groups.map do |example_group|
32
- example_group.run(reporter)
33
- end
39
+ RSpec.configuration.load_spec_files
40
+ ensure
41
+ RSpec.world.announce_filters
42
+ end
34
43
 
35
- result.all?
44
+ return RSpec.configuration.reporter.exit_early(RSpec.configuration.failure_exit_code) if RSpec.world.wants_to_quit
45
+
46
+ example_groups = RSpec.world.ordered_example_groups
47
+ examples_count = RSpec.world.example_count(example_groups)
48
+
49
+ result = RSpec.configuration.reporter.report(examples_count) do |reporter|
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
53
+ end
54
+
55
+ results = example_groups.map do |example_group|
56
+ group_success = example_group.run(reporter)
57
+ ExampleGroupResult.new(example_group, group_success)
58
+ end
59
+
60
+ success = results.all?(&:success)
61
+ exit_code = success ? 0 : 1
62
+ if RSpec.world.non_example_failure
63
+ success = false
64
+ exit_code = RSpec.configuration.failure_exit_code
65
+ end
66
+ Result.new(results, success, exit_code)
67
+ end
36
68
  end
69
+ result
37
70
  end
38
71
 
39
- success && !RSpec.world.non_example_failure ? 0 : RSpec.configuration.failure_exit_code
40
- end
41
-
42
- def quit
43
- RSpec.world.wants_to_quit = true
72
+ def quit
73
+ RSpec.world.wants_to_quit = true
74
+ end
44
75
  end
45
76
  end
46
77
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RSpecInteractive
4
- VERSION = "0.1.0"
3
+ module RSpec
4
+ module Interactive
5
+ VERSION = "0.2.0"
6
+ end
5
7
  end
@@ -4,7 +4,7 @@ require_relative "lib/rspec-interactive/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "rspec-interactive"
7
- spec.version = RSpecInteractive::VERSION
7
+ spec.version = RSpec::Interactive::VERSION
8
8
  spec.authors = ["Nick Dower"]
9
9
  spec.email = ["nicholasdower@gmail.com"]
10
10
 
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = "https://github.com/nicholasdower/rspec-interactive"
19
- spec.metadata["changelog_uri"] = "https://github.com/nicholasdower/rspec-interactive"
19
+ spec.metadata["changelog_uri"] = "https://github.com/nicholasdower/rspec-interactive/releases"
20
20
 
21
21
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
22
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
@@ -25,5 +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 "listen"
28
+ spec.add_dependency 'rspec-core', '~> 3.9.2', '>= 3.9.2'
29
+ spec.add_dependency 'listen', '~> 3.5', '>= 3.5.1'
30
+ spec.add_dependency 'pry', '~> 0.14.1'
29
31
  end
metadata CHANGED
@@ -1,29 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-interactive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
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-05-09 00:00:00.000000000 Z
11
+ date: 2021-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.9.2
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.9.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 3.9.2
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.9.2
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: listen
15
35
  requirement: !ruby/object:Gem::Requirement
16
36
  requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.5'
17
40
  - - ">="
18
41
  - !ruby/object:Gem::Version
19
- version: '0'
42
+ version: 3.5.1
20
43
  type: :runtime
21
44
  prerelease: false
22
45
  version_requirements: !ruby/object:Gem::Requirement
23
46
  requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '3.5'
24
50
  - - ">="
25
51
  - !ruby/object:Gem::Version
26
- version: '0'
52
+ version: 3.5.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: pry
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: 0.14.1
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: 0.14.1
27
67
  description: An interactive console for running specs.
28
68
  email:
29
69
  - nicholasdower@gmail.com
@@ -36,15 +76,20 @@ files:
36
76
  - Gemfile
37
77
  - Gemfile.lock
38
78
  - LICENSE.txt
79
+ - README.md
39
80
  - Rakefile
40
81
  - bin/console
41
82
  - bin/rspec-interactive
42
83
  - bin/setup
43
- - lib/repo.rb
84
+ - examples/debugged_spec.rb
85
+ - examples/failing_spec.rb
86
+ - examples/passing_spec.rb
44
87
  - lib/rspec-interactive.rb
88
+ - lib/rspec-interactive/config_cache.rb
89
+ - lib/rspec-interactive/input_completer.rb
90
+ - lib/rspec-interactive/rspec_command.rb
45
91
  - lib/rspec-interactive/runner.rb
46
92
  - lib/rspec-interactive/version.rb
47
- - rspec-console-0.1.0.gem
48
93
  - rspec-interactive.gemspec
49
94
  homepage: https://github.com/nicholasdower/rspec-interactive
50
95
  licenses:
@@ -52,7 +97,7 @@ licenses:
52
97
  metadata:
53
98
  homepage_uri: https://github.com/nicholasdower/rspec-interactive
54
99
  source_code_uri: https://github.com/nicholasdower/rspec-interactive
55
- changelog_uri: https://github.com/nicholasdower/rspec-interactive
100
+ changelog_uri: https://github.com/nicholasdower/rspec-interactive/releases
56
101
  post_install_message:
57
102
  rdoc_options: []
58
103
  require_paths:
data/lib/repo.rb DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "repo/version"
4
-
5
- module Repo
6
- class Error < StandardError; end
7
- # Your code goes here...
8
- end
Binary file