rspec-interactive 0.1.0 → 0.2.0

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: 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