rspec-interactive 0.9.6 → 0.9.9

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: 448fb430c0970d2d6f3dc12a3a1b6577dde234516d0d7f3fdccc735be784919b
4
- data.tar.gz: 650d41f575295fb43d1c97930ae49e4a7fe34aac1d4cb1ca2a7d3fe6a1cb25c6
3
+ metadata.gz: c87a284feb4bf76bac68cda8cbe5703a66f04a856c8e2aed9e27d30b89e2654e
4
+ data.tar.gz: 9336d2bff3ba1973921f8d7ba6a36d88bc11d4acd1c2b2ee86d7c47cb58d0356
5
5
  SHA512:
6
- metadata.gz: d5a4b51199209d0d248e1fc26a2d7e3cb4abf993eb2a61775162eda5107a2a97529bdd58867cb1e870a9c10f9da7c3ef60ce0ccd4ad484f6f900f9c2b0708a6f
7
- data.tar.gz: f57523af399e9ca55303101479fbc0940c60095a0ffe93a2092255954fe5be3003bfc82c41c7a416df72a12d72fd4aae0d578b5d7f6da85c1385a9f620950227
6
+ metadata.gz: 36afe559f97bc7cdee9e6833655f23e6092004b800e53beed28099afb8db6ce5511bc8177c9cc648ffc0a558bd221ca2ff13c5ff44e76132c20af99b30281fda
7
+ data.tar.gz: '097084b7f1fec026f08433a8d12d56997b83a8deb8852026fc04dc1f3e7ec5410433e0758b374724cb2b5450f7b5be4e4db2d9953241a7bbd703f610f032e6ef'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-interactive (0.9.5)
4
+ rspec-interactive (0.9.8)
5
5
  listen
6
6
  pry
7
7
  rspec-core
@@ -17,6 +17,13 @@ module RSpec
17
17
  @client.print(str.to_s + "\n")
18
18
  end
19
19
 
20
+ def flush
21
+ end
22
+
23
+ def closed?
24
+ @client.closed?
25
+ end
26
+
20
27
  def string
21
28
  @output
22
29
  end
@@ -4,7 +4,7 @@ class Pry
4
4
  alias_method :old_eval, :eval
5
5
 
6
6
  def eval(line, options = {})
7
- RSpec::Interactive.eval do
7
+ RSpec::Interactive.eval(line, options) do
8
8
  old_eval(line, options)
9
9
  end
10
10
  end
@@ -1,52 +1,13 @@
1
1
  module RSpec
2
2
  module Interactive
3
3
  class Stdio
4
- def self.capture2(stdout:, stderr:)
4
+ def self.capture(stdout:, stderr:)
5
5
  old_stdout, old_stderr = $stdout, $stderr
6
6
  $stdout, $stderr = stdout, stderr
7
7
  yield
8
8
  ensure
9
9
  $stdout, $stderr = old_stdout, old_stderr
10
10
  end
11
-
12
- def self.capture(stdout:, stderr:)
13
- raise ArgumentError, 'missing block' unless block_given?
14
-
15
- old_stdout, old_stderr = STDOUT.dup, STDERR.dup
16
-
17
- IO.pipe do |stdout_read, stdout_write|
18
- IO.pipe do |stderr_read, stderr_write|
19
- STDOUT.reopen(stdout_write)
20
- STDERR.reopen(stderr_write)
21
-
22
- stdout_write.close
23
- stderr_write.close
24
-
25
- stdout_thread = Thread.new do
26
- while line = stdout_read.gets do
27
- stdout.print(line)
28
- end
29
- end
30
-
31
- stderr_thread = Thread.new do
32
- while line = stderr_read.gets do
33
- stderr.print(line)
34
- end
35
- end
36
-
37
- begin
38
- yield
39
- ensure
40
- # TODO: should the threads be killed here?
41
- STDOUT.reopen old_stdout
42
- STDERR.reopen old_stderr
43
- end
44
-
45
- stdout_thread.join
46
- stderr_thread.join
47
- end
48
- end
49
- end
50
11
  end
51
12
  end
52
13
  end
@@ -18,6 +18,13 @@ module RSpec
18
18
  def print(str = "")
19
19
  @string += str.to_s
20
20
  end
21
+
22
+ def flush
23
+ end
24
+
25
+ def closed?
26
+ @client.closed?
27
+ end
21
28
  end
22
29
  end
23
30
  end
@@ -0,0 +1,33 @@
1
+ module RSpec
2
+ module Interactive
3
+ class ThreadedOutput
4
+ attr_reader :string
5
+
6
+ def initialize(thread_map:, default:)
7
+ @thread_map = thread_map
8
+ @default = default
9
+ @string = ''
10
+ end
11
+
12
+ def write(name, str = "")
13
+ (@thread_map[Thread.current] || @default).write(name, str)
14
+ end
15
+
16
+ def puts(str = "")
17
+ (@thread_map[Thread.current] || @default).puts(str)
18
+ end
19
+
20
+ def print(str = "")
21
+ (@thread_map[Thread.current] || @default).puts(str)
22
+ end
23
+
24
+ def flush
25
+ (@thread_map[Thread.current] || @default).flush
26
+ end
27
+
28
+ def closed?
29
+ (@thread_map[Thread.current] || @default).closed?
30
+ end
31
+ end
32
+ end
33
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module Interactive
5
- VERSION = "0.9.6"
5
+ VERSION = "0.9.9"
6
6
  end
7
7
  end
@@ -19,6 +19,7 @@ require 'rspec-interactive/rubo_cop_command'
19
19
  require 'rspec-interactive/runner'
20
20
  require 'rspec-interactive/stdio'
21
21
  require 'rspec-interactive/string_output'
22
+ require 'rspec-interactive/threaded_output'
22
23
 
23
24
  module RSpec
24
25
  module Interactive
@@ -47,7 +48,7 @@ module RSpec
47
48
  @updated_files = []
48
49
  @stty_save = %x`stty -g`.chomp
49
50
  @file_change_mutex = Mutex.new
50
- @command_mutex = Mutex.new
51
+ @rspec_mutex = Mutex.new
51
52
  @output_stream = output_stream
52
53
  @input_stream = input_stream
53
54
  @error_stream = error_stream
@@ -61,29 +62,44 @@ module RSpec
61
62
  configure_pry
62
63
 
63
64
  @startup_thread = Thread.start do
64
- @startup_output = StringOutput.new
65
- Stdio.capture2(stdout: @startup_output, stderr: @startup_output) do
66
- @config_cache.record_configuration { @configuration.configure_rspec.call }
67
- start_file_watcher
68
- end
69
-
65
+ Thread.current.report_on_exception = false
70
66
  if server
71
67
  @server_thread = Thread.start do
72
68
  server = TCPServer.new port
73
69
 
74
- while client = server.accept
75
- request = client.gets
76
- args = Shellwords.split(request)
77
- rspec_for_server(client, args)
78
- client.close
70
+ while true
71
+ break unless client = server.accept
72
+ begin
73
+ request = client.gets
74
+ args = Shellwords.split(request)
75
+ rspec_for_server(client, args)
76
+ rescue StandardError => e
77
+ # It would be nice to log to the client here but it might be
78
+ # disconnected or disconnect before we successfully write. Any
79
+ # error here is unexpected so just log to the console.
80
+ @output_stream.puts
81
+ @output_stream.puts 'error handling client request'
82
+ log_exception(@output_stream, e)
83
+ ensure
84
+ client.close
85
+ end
79
86
  end
80
87
  end
81
88
  end
89
+
90
+ @startup_output = StringOutput.new
91
+ output = ThreadedOutput.new(thread_map: { Thread.current => @startup_output }, default: @output_stream)
92
+
93
+ Stdio.capture(stdout: output, stderr: output) do
94
+ @config_cache.record_configuration { @configuration.configure_rspec.call }
95
+ start_file_watcher
96
+ end
82
97
  end
83
98
 
84
99
  Pry.start
85
100
  @listener.stop if @listener
86
101
  @server_thread.exit if @server_thread
102
+ @startup_thread.exit if @startup_thread
87
103
  0
88
104
  end
89
105
 
@@ -141,17 +157,17 @@ module RSpec
141
157
  Pry.config.history_file = @history_file
142
158
  end
143
159
 
144
- def self.refresh
160
+ def self.refresh(output: @output_stream)
145
161
  @file_change_mutex.synchronize do
146
162
  @updated_files.uniq.each do |filename|
147
- @output_stream.puts "changed: #{filename}"
163
+ output.puts "changed: #{filename}"
148
164
  trace = TracePoint.new(:class) do |tp|
149
165
  @configuration.on_class_load.call(tp.self)
150
166
  end
151
167
  trace.enable
152
168
  load filename
153
169
  trace.disable
154
- @output_stream.puts
170
+ output.puts
155
171
  end
156
172
  @updated_files.clear
157
173
  end
@@ -180,50 +196,60 @@ module RSpec
180
196
  end
181
197
 
182
198
  def self.rspec(args)
183
- @runner = RSpec::Interactive::Runner.new(parse_args(args))
199
+ @rspec_mutex.synchronize do
200
+ begin
201
+ @runner = RSpec::Interactive::Runner.new(parse_args(args))
184
202
 
185
- refresh
203
+ refresh
186
204
 
187
- # Stop saving history in case a new Pry session is started for debugging.
188
- Pry.config.history_save = false
205
+ # Stop saving history in case a new Pry session is started for debugging.
206
+ Pry.config.history_save = false
189
207
 
190
- # RSpec::Interactive-specific RSpec configuration
191
- RSpec.configure do |config|
192
- config.error_stream = @error_stream
193
- config.output_stream = @output_stream
194
- config.start_time = RSpec::Core::Time.now
195
- end
208
+ # RSpec::Interactive-specific RSpec configuration
209
+ RSpec.configure do |config|
210
+ config.error_stream = @error_stream
211
+ config.output_stream = @output_stream
212
+ config.start_time = RSpec::Core::Time.now
213
+ end
196
214
 
197
- # Run.
198
- exit_code = @runner.run
199
- ensure
200
- @runner = nil
215
+ # Run.
216
+ @runner.run
217
+ ensure
218
+ @runner = nil
201
219
 
202
- # Reenable history
203
- Pry.config.history_save = true
220
+ # Reenable history
221
+ Pry.config.history_save = true
204
222
 
205
- # Reset
206
- RSpec.clear_examples
207
- RSpec.reset
208
- @config_cache.replay_configuration
223
+ # Reset
224
+ RSpec.clear_examples
225
+ RSpec.reset
226
+ @config_cache.replay_configuration
227
+ end
228
+ end
209
229
  end
210
230
 
211
231
  def self.rspec_for_server(client, args)
212
- @command_mutex.synchronize do
213
- # Prevent the debugger from being used. The server isn't interactive.
232
+ @rspec_mutex.synchronize do
214
233
  disable_pry = ENV['DISABLE_PRY']
215
- ENV['DISABLE_PRY'] = 'true'
216
-
217
234
  output = ClientOutput.new(client)
235
+
236
+ ENV['TEAMCITY_RAKE_RUNNER_DEBUG_OUTPUT_CAPTURER_ENABLED'] = 'false'
237
+ Rake::TeamCity::RunnerCommon.class_variable_set(:@@original_stdout, output)
238
+
239
+ return unless await_startup(output: output)
240
+
218
241
  Stdio.capture(stdout: output, stderr: output) do
219
- @runner = RSpec::Interactive::Runner.new(parse_args(args))
242
+ # Prevent the debugger from being used. The server isn't interactive.
243
+ ENV['DISABLE_PRY'] = 'true'
220
244
 
221
- refresh
245
+ runner = RSpec::Interactive::Runner.new(parse_args(args))
246
+
247
+ refresh(output: output)
222
248
 
223
249
  # RSpec::Interactive-specific RSpec configuration
224
250
  RSpec.configure do |config|
225
- config.error_stream = @error_stream
226
- config.output_stream = @output_stream
251
+ config.error_stream = output
252
+ config.output_stream = output
227
253
  config.start_time = RSpec::Core::Time.now
228
254
  end
229
255
 
@@ -239,15 +265,19 @@ module RSpec
239
265
  RSpec.configuration.formatter = Spec::Runner::Formatter::TeamcityFormatter
240
266
 
241
267
  # Run.
242
- exit_code = @runner.run
268
+ runner.run
269
+ rescue Errno::EPIPE, IOError
270
+ # Don't care.
271
+ ensure
272
+ ENV['DISABLE_PRY'] = disable_pry
273
+ runner = nil
243
274
 
244
275
  # Reset
245
276
  RSpec.clear_examples
246
277
  RSpec.reset
278
+
247
279
  @config_cache.replay_configuration
248
280
  end
249
- ensure
250
- ENV['DISABLE_PRY'] = disable_pry
251
281
  end
252
282
  end
253
283
 
@@ -259,28 +289,50 @@ module RSpec
259
289
  end
260
290
  end
261
291
 
262
- def self.eval(&block)
263
- if Thread.current.thread_variable_get('holding_lock')
292
+ def self.eval(line, options, &block)
293
+ return yield if line.nil? # EOF
294
+ return yield if line.empty? # blank line
295
+
296
+ if await_startup
264
297
  yield
265
298
  else
266
- @command_mutex.synchronize do
267
- Thread.current.thread_variable_set('holding_lock', true)
268
- if @startup_thread
269
- if @startup_thread.alive?
270
- @output_stream.puts 'waiting for configure_rspec...'
271
- end
272
- @startup_thread.join
273
- @startup_thread = nil
274
- unless @startup_output.string.empty?
275
- @output_stream.puts(@startup_output.string)
276
- end
277
- @startup_output = nil
278
- end
279
- yield
280
- ensure
281
- Thread.current.thread_variable_set('holding_lock', false)
282
- end
299
+ @output_stream.puts
300
+ true
301
+ end
302
+ end
303
+
304
+ def self.await_startup(output: @output_stream)
305
+ return true unless @startup_thread
306
+
307
+ if @startup_thread.alive?
308
+ output.puts 'waiting for configure_rspec...'
283
309
  end
310
+
311
+ begin
312
+ @startup_thread.join
313
+ @startup_thread = nil
314
+ print_startup_output(output: output)
315
+ true
316
+ rescue Interrupt
317
+ false
318
+ rescue StandardError => e
319
+ print_startup_output(output: output)
320
+ output.puts 'configure_rspec failed'
321
+ log_exception(output, e)
322
+ false
323
+ end
324
+ end
325
+
326
+ def self.log_exception(output, e)
327
+ output.puts "#{e.backtrace[0]}: #{e.message} (#{e.class})"
328
+ e.backtrace[1..-1].each { |b| output.puts "\t#{b}" }
329
+ end
330
+
331
+ def self.print_startup_output(output: @output_stream)
332
+ return if @startup_output.nil? || @startup_output.string.empty?
333
+
334
+ output.puts(@startup_output.string)
335
+ @startup_output = nil
284
336
  end
285
337
  end
286
338
  end
@@ -24,8 +24,12 @@ parser = OptionParser.new do |opts|
24
24
  end.parse
25
25
 
26
26
  server = TCPSocket.open(@options[:host], @options[:port])
27
- server.puts ARGV.map{ |arg| Shellwords.escape arg }.join(' ')
28
- while response = server.gets do
29
- puts response
27
+ begin
28
+ server.puts ARGV.map{ |arg| Shellwords.escape arg }.join(' ')
29
+ server.close_write
30
+ while response = server.gets do
31
+ puts response
32
+ end
33
+ ensure
34
+ server.close
30
35
  end
31
- server.close
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.9.6
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Dower
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-26 00:00:00.000000000 Z
11
+ date: 2022-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-core
@@ -103,6 +103,7 @@ files:
103
103
  - lib/rspec-interactive/runner.rb
104
104
  - lib/rspec-interactive/stdio.rb
105
105
  - lib/rspec-interactive/string_output.rb
106
+ - lib/rspec-interactive/threaded_output.rb
106
107
  - lib/rspec-interactive/version.rb
107
108
  - lib/teamcity/spec/runner/formatter/teamcity/formatter.rb
108
109
  - rspec-interactive.gemspec