rspec-interactive 0.9.1 → 0.9.4
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.lock +1 -1
- data/bin/rspec-interactive +6 -6
- data/examples/config.rb +7 -0
- data/lib/rspec-interactive/client_output.rb +17 -0
- data/lib/rspec-interactive/pry.rb +12 -0
- data/lib/rspec-interactive/rspec_core_example.rb +15 -0
- data/lib/rspec-interactive/stdio.rb +44 -0
- data/lib/rspec-interactive/version.rb +1 -1
- data/lib/rspec-interactive.rb +102 -52
- data/lib/teamcity/spec/runner/formatter/teamcity/formatter.rb +0 -8
- data/rspec-interactive.gemspec +0 -1
- data/runner/Gemfile +5 -0
- data/runner/Gemfile.lock +14 -0
- data/runner/README.md +3 -0
- data/{bin → runner}/rspec-interactive-run +2 -3
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58b63742b50c16f44d1cf19e2957e29ed07ef4a19c3ee91debed0624f519684a
|
4
|
+
data.tar.gz: 0217f523599d1ee0a104718bd3c2bd79aeaf9366d18a22f5abfdadb2ce1fc229
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d5dbf2e0ec74668264fee718f5e2edaa60f0bff510433f376ac8264a64afb61b2a3538e8604f3c8cc4e0c1e48b409bb4bccfaedb25e0b587145d7b9f4abbb11
|
7
|
+
data.tar.gz: 86bba6bf0ad9728ba06d9374a3efb7b74cb4736fb24f5a81799e7ed4d54c499c012153ca2e90096caf0ab3965098c38cccc28b2b9c0d031723e7cc698b0a4fcc
|
data/Gemfile.lock
CHANGED
data/bin/rspec-interactive
CHANGED
@@ -4,20 +4,20 @@ require 'optparse'
|
|
4
4
|
require 'rspec-interactive'
|
5
5
|
|
6
6
|
@options = {
|
7
|
-
server:
|
8
|
-
|
7
|
+
server: true,
|
8
|
+
server_port: RSpec::Interactive::DEFAULT_PORT
|
9
9
|
}
|
10
10
|
|
11
11
|
parser = OptionParser.new do |opts|
|
12
12
|
opts.banner = "Starts an interactive RSpec shell.\n\n"\
|
13
|
-
"Usage: bundle exec rspec-interactive [--config config-file] [--server [--port <port>]
|
13
|
+
"Usage: bundle exec rspec-interactive [--config config-file] [--no-server] [--port <port>]"
|
14
14
|
|
15
15
|
opts.on("-c", "--config <config-file>", String, "Optional. Path to the RSpec Interactive config file.") do |config_file|
|
16
16
|
@options[:config_file] = config_file
|
17
17
|
end
|
18
18
|
|
19
|
-
opts.on("-
|
20
|
-
@options[:server] =
|
19
|
+
opts.on("--no-server", "Optional. Disable server.") do
|
20
|
+
@options[:server] = false
|
21
21
|
end
|
22
22
|
|
23
23
|
opts.on("-p", "--port <port>", Integer, "Optional. Server port. Defaults to #{RSpec::Interactive::DEFAULT_PORT}.") do |port|
|
@@ -26,4 +26,4 @@ parser = OptionParser.new do |opts|
|
|
26
26
|
|
27
27
|
end.parse!
|
28
28
|
|
29
|
-
RSpec::Interactive.start(config_file: @options[:config_file], server: @options[:server], port: @options[:
|
29
|
+
RSpec::Interactive.start(config_file: @options[:config_file], server: @options[:server], port: @options[:server_port])
|
data/examples/config.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rspec/core'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Core
|
5
|
+
class Example
|
6
|
+
alias_method :old_run, :run
|
7
|
+
|
8
|
+
def run(example_group_instance, reporter)
|
9
|
+
execution_result.started_at = RSpec::Core::Time.now
|
10
|
+
old_run(example_group_instance, reporter)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Interactive
|
3
|
+
class Stdio
|
4
|
+
def self.capture(output)
|
5
|
+
raise ArgumentError, 'missing block' unless block_given?
|
6
|
+
|
7
|
+
stdout, stderr = STDOUT.dup, STDERR.dup
|
8
|
+
|
9
|
+
IO.pipe do |stdout_read, stdout_write|
|
10
|
+
IO.pipe do |stderr_read, stderr_write|
|
11
|
+
STDOUT.reopen(stdout_write)
|
12
|
+
STDERR.reopen(stderr_write)
|
13
|
+
|
14
|
+
stdout_write.close
|
15
|
+
stderr_write.close
|
16
|
+
|
17
|
+
stdout_thread = Thread.new do
|
18
|
+
while line = stdout_read.gets do
|
19
|
+
output.print(line)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
stderr_thread = Thread.new do
|
24
|
+
while line = stderr_read.gets do
|
25
|
+
output.print(line)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
yield
|
31
|
+
ensure
|
32
|
+
# TODO: should the threads be killed here?
|
33
|
+
STDOUT.reopen stdout
|
34
|
+
STDERR.reopen stderr
|
35
|
+
end
|
36
|
+
|
37
|
+
stdout_thread.join
|
38
|
+
stderr_thread.join
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/rspec-interactive.rb
CHANGED
@@ -7,13 +7,17 @@ require 'shellwords'
|
|
7
7
|
require 'socket'
|
8
8
|
require 'teamcity/spec/runner/formatter/teamcity/formatter'
|
9
9
|
|
10
|
+
require 'rspec-interactive/client_output'
|
10
11
|
require 'rspec-interactive/config'
|
11
12
|
require 'rspec-interactive/input_completer'
|
13
|
+
require 'rspec-interactive/pry'
|
12
14
|
require 'rspec-interactive/refresh_command'
|
13
15
|
require 'rspec-interactive/rspec_command'
|
14
16
|
require 'rspec-interactive/rspec_config_cache'
|
17
|
+
require 'rspec-interactive/rspec_core_example'
|
15
18
|
require 'rspec-interactive/rubo_cop_command'
|
16
19
|
require 'rspec-interactive/runner'
|
20
|
+
require 'rspec-interactive/stdio'
|
17
21
|
|
18
22
|
module RSpec
|
19
23
|
module Interactive
|
@@ -42,7 +46,7 @@ module RSpec
|
|
42
46
|
@updated_files = []
|
43
47
|
@stty_save = %x`stty -g`.chomp
|
44
48
|
@file_change_mutex = Mutex.new
|
45
|
-
@
|
49
|
+
@command_mutex = Mutex.new
|
46
50
|
@output_stream = output_stream
|
47
51
|
@input_stream = input_stream
|
48
52
|
@error_stream = error_stream
|
@@ -52,14 +56,16 @@ module RSpec
|
|
52
56
|
load config_file if config_file
|
53
57
|
|
54
58
|
check_rails
|
59
|
+
trap_interrupt
|
55
60
|
configure_pry
|
61
|
+
load_rspec_configuration
|
56
62
|
|
57
|
-
@config_cache.record_configuration { @configuration.configure_rspec.call }
|
58
63
|
start_file_watcher
|
59
64
|
|
60
65
|
if server
|
66
|
+
@output_stream.puts "listening on port #{port}"
|
61
67
|
server_thread = Thread.start do
|
62
|
-
server = TCPServer.new
|
68
|
+
server = TCPServer.new port
|
63
69
|
|
64
70
|
while client = server.accept
|
65
71
|
request = client.gets
|
@@ -84,11 +90,14 @@ module RSpec
|
|
84
90
|
end
|
85
91
|
end
|
86
92
|
|
87
|
-
def self.
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
93
|
+
def self.trap_interrupt
|
94
|
+
trap('INT') do
|
95
|
+
if @runner
|
96
|
+
# We are on a different thread. There is a race here. Ignore nil.
|
97
|
+
@runner&.quit
|
98
|
+
else
|
99
|
+
raise Interrupt
|
100
|
+
end
|
92
101
|
end
|
93
102
|
end
|
94
103
|
|
@@ -104,7 +113,24 @@ module RSpec
|
|
104
113
|
@listener.start
|
105
114
|
end
|
106
115
|
|
116
|
+
def self.load_rspec_configuration
|
117
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
118
|
+
config_thread = Thread.start do
|
119
|
+
@config_cache.record_configuration { @configuration.configure_rspec.call }
|
120
|
+
end
|
121
|
+
unless config_thread.join(3)
|
122
|
+
@output_stream.puts "executing configure_rspec hook..."
|
123
|
+
end
|
124
|
+
config_thread.join
|
125
|
+
|
126
|
+
end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
127
|
+
@output_stream.puts "configure_rspec hook took #{(end_time - start_time).round} seconds" if end_time - start_time > 5
|
128
|
+
end
|
129
|
+
|
107
130
|
def self.configure_pry
|
131
|
+
# Prevent Pry from trapping too. It will break ctrl-c handling.
|
132
|
+
Pry.config.should_trap_interrupts = false
|
133
|
+
|
108
134
|
# Set up IO.
|
109
135
|
Pry.config.input = Readline
|
110
136
|
Pry.config.output = @output_stream
|
@@ -146,63 +172,75 @@ module RSpec
|
|
146
172
|
end
|
147
173
|
|
148
174
|
def self.rspec(args)
|
149
|
-
@
|
175
|
+
@runner = RSpec::Interactive::Runner.new(parse_args(args))
|
150
176
|
|
151
|
-
|
177
|
+
refresh
|
152
178
|
|
153
|
-
|
179
|
+
# Stop saving history in case a new Pry session is started for debugging.
|
180
|
+
Pry.config.history_save = false
|
154
181
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
182
|
+
# RSpec::Interactive-specific RSpec configuration
|
183
|
+
RSpec.configure do |config|
|
184
|
+
config.error_stream = @error_stream
|
185
|
+
config.output_stream = @output_stream
|
186
|
+
config.start_time = RSpec::Core::Time.now
|
187
|
+
end
|
160
188
|
|
161
|
-
|
162
|
-
|
163
|
-
|
189
|
+
# Run.
|
190
|
+
exit_code = @runner.run
|
191
|
+
@runner = nil
|
164
192
|
|
165
|
-
|
166
|
-
|
193
|
+
# Reenable history
|
194
|
+
Pry.config.history_save = true
|
167
195
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
ensure
|
175
|
-
@runner = nil
|
176
|
-
end
|
196
|
+
# Reset
|
197
|
+
RSpec.clear_examples
|
198
|
+
RSpec.reset
|
199
|
+
@config_cache.replay_configuration
|
200
|
+
ensure
|
201
|
+
@runner = nil
|
177
202
|
end
|
178
203
|
|
179
204
|
def self.rspec_for_server(client, args)
|
180
|
-
@
|
181
|
-
#
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
205
|
+
@command_mutex.synchronize do
|
206
|
+
# Prevent the debugger from being used. The server isn't interactive.
|
207
|
+
disable_pry = ENV['DISABLE_PRY']
|
208
|
+
ENV['DISABLE_PRY'] = 'true'
|
209
|
+
|
210
|
+
output = ClientOutput.new(client)
|
211
|
+
Stdio.capture(ClientOutput.new(client)) do
|
212
|
+
@runner = RSpec::Interactive::Runner.new(parse_args(args))
|
213
|
+
|
214
|
+
refresh
|
215
|
+
|
216
|
+
# RSpec::Interactive-specific RSpec configuration
|
217
|
+
RSpec.configure do |config|
|
218
|
+
config.error_stream = @error_stream
|
219
|
+
config.output_stream = @output_stream
|
220
|
+
config.start_time = RSpec::Core::Time.now
|
221
|
+
end
|
187
222
|
|
188
|
-
|
189
|
-
|
223
|
+
# RubyMine specifies --format. That causes a formatter to be added. It does not override
|
224
|
+
# the existing formatter (if one is set by default). Clear any formatters but resetting
|
225
|
+
# the loader.
|
226
|
+
RSpec.configuration.instance_variable_set(
|
227
|
+
:@formatter_loader,
|
228
|
+
RSpec::Core::Formatters::Loader.new(RSpec::Core::Reporter.new(RSpec.configuration)))
|
190
229
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
:@formatter_loader,
|
195
|
-
RSpec::Core::Formatters::Loader.new(RSpec::Core::Reporter.new(RSpec.configuration)))
|
196
|
-
RSpec.configuration.formatter = Spec::Runner::Formatter::TeamcityFormatter
|
230
|
+
# Always use the teamcity formatter, even though RubyMine always specifies it.
|
231
|
+
# This make manual testing of rspec-interactive easier.
|
232
|
+
RSpec.configuration.formatter = Spec::Runner::Formatter::TeamcityFormatter
|
197
233
|
|
198
|
-
|
199
|
-
|
234
|
+
# Run.
|
235
|
+
exit_code = @runner.run
|
200
236
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
237
|
+
# Reset
|
238
|
+
RSpec.clear_examples
|
239
|
+
RSpec.reset
|
240
|
+
@config_cache.replay_configuration
|
241
|
+
end
|
242
|
+
ensure
|
243
|
+
ENV['DISABLE_PRY'] = disable_pry
|
206
244
|
end
|
207
245
|
end
|
208
246
|
|
@@ -214,5 +252,17 @@ module RSpec
|
|
214
252
|
end
|
215
253
|
end
|
216
254
|
|
255
|
+
def self.eval(&block)
|
256
|
+
if Thread.current.thread_variable_get('holding_lock')
|
257
|
+
yield
|
258
|
+
else
|
259
|
+
@command_mutex.synchronize do
|
260
|
+
Thread.current.thread_variable_set('holding_lock', true)
|
261
|
+
yield
|
262
|
+
ensure
|
263
|
+
Thread.current.thread_variable_set('holding_lock', false)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
217
267
|
end
|
218
268
|
end
|
data/rspec-interactive.gemspec
CHANGED
data/runner/Gemfile
ADDED
data/runner/Gemfile.lock
ADDED
data/runner/README.md
ADDED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'optparse'
|
4
|
-
require 'rspec-interactive'
|
5
4
|
require 'shellwords'
|
6
5
|
require 'socket'
|
7
6
|
|
@@ -25,8 +24,8 @@ parser = OptionParser.new do |opts|
|
|
25
24
|
end.parse
|
26
25
|
|
27
26
|
server = TCPSocket.open(@options[:host], @options[:port])
|
28
|
-
server.puts ARGV.map{|arg| Shellwords.escape arg}.join(' ')
|
27
|
+
server.puts ARGV.map{ |arg| Shellwords.escape arg }.join(' ')
|
29
28
|
while response = server.gets do
|
30
|
-
puts
|
29
|
+
puts response
|
31
30
|
end
|
32
31
|
server.close
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-interactive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Dower
|
@@ -71,7 +71,6 @@ email:
|
|
71
71
|
- nicholasdower@gmail.com
|
72
72
|
executables:
|
73
73
|
- rspec-interactive
|
74
|
-
- rspec-interactive-run
|
75
74
|
extensions: []
|
76
75
|
extra_rdoc_files: []
|
77
76
|
files:
|
@@ -83,25 +82,33 @@ files:
|
|
83
82
|
- Rakefile
|
84
83
|
- bin/console
|
85
84
|
- bin/rspec-interactive
|
86
|
-
- bin/rspec-interactive-run
|
87
85
|
- bin/setup
|
88
86
|
- bin/test
|
87
|
+
- examples/config.rb
|
89
88
|
- examples/debugged_spec.rb
|
90
89
|
- examples/failing_spec.rb
|
91
90
|
- examples/other_passing_spec.rb
|
92
91
|
- examples/passing_spec.rb
|
93
92
|
- examples/spec_with_syntax_error.rb
|
94
93
|
- lib/rspec-interactive.rb
|
94
|
+
- lib/rspec-interactive/client_output.rb
|
95
95
|
- lib/rspec-interactive/config.rb
|
96
96
|
- lib/rspec-interactive/input_completer.rb
|
97
|
+
- lib/rspec-interactive/pry.rb
|
97
98
|
- lib/rspec-interactive/refresh_command.rb
|
98
99
|
- lib/rspec-interactive/rspec_command.rb
|
99
100
|
- lib/rspec-interactive/rspec_config_cache.rb
|
101
|
+
- lib/rspec-interactive/rspec_core_example.rb
|
100
102
|
- lib/rspec-interactive/rubo_cop_command.rb
|
101
103
|
- lib/rspec-interactive/runner.rb
|
104
|
+
- lib/rspec-interactive/stdio.rb
|
102
105
|
- lib/rspec-interactive/version.rb
|
103
106
|
- lib/teamcity/spec/runner/formatter/teamcity/formatter.rb
|
104
107
|
- rspec-interactive.gemspec
|
108
|
+
- runner/Gemfile
|
109
|
+
- runner/Gemfile.lock
|
110
|
+
- runner/README.md
|
111
|
+
- runner/rspec-interactive-run
|
105
112
|
- scripts/release.sh
|
106
113
|
- scripts/run-with-local-dep.sh
|
107
114
|
- tests/debugged_spec_test.rb
|