rspec-interactive 0.9.8 → 0.9.11

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: 895c315e10777f7d94c8efdf005129bb532463b31d764af1ddd079692b3e0e62
4
- data.tar.gz: 264d523cfc32ffab312ef3d9323611c05f00d851d755d5cf53735680eac0ce4a
3
+ metadata.gz: 8cced0f02ca892c718d8df21ce4098fb6ef1f8b2f2845e9795811147ee9b4bc0
4
+ data.tar.gz: 23434b560c9f01d9c4c9342ba180ffb53e35134342e2a87522f913d51eb1d5dd
5
5
  SHA512:
6
- metadata.gz: 47ca24fe9e49e7ea070c62b3786d72232cb52eabc2faac4777b913099c515a4cb9a0eaeb2515ab204637c344824461fcfdc6e3a460082ca1384bf57d2e04e773
7
- data.tar.gz: f7d35eb450b116bb275eac5eaf729d37af936464e18ce9015d3bea953b6204517212299c923eb9e114182b120df3ad3868112be716bd9bd20d6de2c2c8c6326d
6
+ metadata.gz: a3057fd377b3862bd39962ad7864b7cfed2605ca2a87bb0aae9d5fef24c286cf5804fa86e6edb494152025a79a68e092994f6a176b245612c61de93dc7d085dd
7
+ data.tar.gz: 79c345903c78993722af61c4294423f733a4f92136f6219e173c494956268ab8bf94f9b8fdbe05e967ffe13ddb62c642047942e46d30c182b3b60771d0505a31
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-interactive (0.9.7)
5
- listen
4
+ rspec-interactive (0.9.10)
6
5
  pry
7
6
  rspec-core
8
7
  rspec-teamcity (= 1.0.0)
@@ -14,9 +13,6 @@ GEM
14
13
  diff-lcs (1.4.4)
15
14
  ffi (1.15.5)
16
15
  ffi (1.15.5-java)
17
- listen (3.7.1)
18
- rb-fsevent (~> 0.10, >= 0.10.3)
19
- rb-inotify (~> 0.9, >= 0.9.10)
20
16
  method_source (1.0.0)
21
17
  pry (0.14.1)
22
18
  coderay (~> 1.1)
@@ -25,9 +21,6 @@ GEM
25
21
  coderay (~> 1.1)
26
22
  method_source (~> 1.0)
27
23
  spoon (~> 0.0)
28
- rb-fsevent (0.11.1)
29
- rb-inotify (0.10.1)
30
- ffi (~> 1.0)
31
24
  rspec (3.9.0)
32
25
  rspec-core (~> 3.9.0)
33
26
  rspec-expectations (~> 3.9.0)
@@ -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.8"
5
+ VERSION = "0.9.11"
6
6
  end
7
7
  end
@@ -1,8 +1,9 @@
1
+ require 'find'
1
2
  require 'json'
2
- require 'listen'
3
3
  require 'pry'
4
4
  require 'readline'
5
5
  require 'rspec/core'
6
+ require 'set'
6
7
  require 'shellwords'
7
8
  require 'socket'
8
9
  require 'teamcity/spec/runner/formatter/teamcity/formatter'
@@ -19,6 +20,7 @@ require 'rspec-interactive/rubo_cop_command'
19
20
  require 'rspec-interactive/runner'
20
21
  require 'rspec-interactive/stdio'
21
22
  require 'rspec-interactive/string_output'
23
+ require 'rspec-interactive/threaded_output'
22
24
 
23
25
  module RSpec
24
26
  module Interactive
@@ -46,8 +48,7 @@ module RSpec
46
48
  @history_file = history_file
47
49
  @updated_files = []
48
50
  @stty_save = %x`stty -g`.chomp
49
- @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
@@ -59,27 +60,43 @@ module RSpec
59
60
  check_rails
60
61
  maybe_trap_interrupt
61
62
  configure_pry
63
+ configure_watched_files
62
64
 
63
65
  @startup_thread = Thread.start do
66
+ Thread.current.report_on_exception = false
64
67
  if server
65
68
  @server_thread = Thread.start do
66
69
  server = TCPServer.new port
67
70
 
68
- while client = server.accept
69
- request = client.gets
70
- args = Shellwords.split(request)
71
- rspec_for_server(client, args)
72
- client.close
71
+ while true
72
+ break unless client = server.accept
73
+ begin
74
+ request = client.gets
75
+ args = Shellwords.split(request)
76
+ rspec_for_server(client, args)
77
+ rescue StandardError => e
78
+ # It would be nice to log to the client here but it might be
79
+ # disconnected or disconnect before we successfully write. Any
80
+ # error here is unexpected so just log to the console.
81
+ @output_stream.puts
82
+ @output_stream.puts 'error handling client request'
83
+ log_exception(@output_stream, e)
84
+ ensure
85
+ client.close
86
+ end
73
87
  end
74
88
  end
75
89
  end
76
90
 
77
- @config_cache.record_configuration { @configuration.configure_rspec.call }
78
- start_file_watcher
91
+ @startup_output = StringOutput.new
92
+ output = ThreadedOutput.new(thread_map: { Thread.current => @startup_output }, default: @output_stream)
93
+
94
+ Stdio.capture(stdout: output, stderr: output) do
95
+ @config_cache.record_configuration { @configuration.configure_rspec.call }
96
+ end
79
97
  end
80
98
 
81
99
  Pry.start
82
- @listener.stop if @listener
83
100
  @server_thread.exit if @server_thread
84
101
  @startup_thread.exit if @startup_thread
85
102
  0
@@ -114,18 +131,6 @@ module RSpec
114
131
  end
115
132
  end
116
133
 
117
- def self.start_file_watcher
118
- return if @configuration.watch_dirs.empty?
119
-
120
- # Only polling seems to work in Docker.
121
- @listener = Listen.to(*@configuration.watch_dirs, only: /\.rb$/, force_polling: true) do |modified, added|
122
- @file_change_mutex.synchronize do
123
- @updated_files.concat(added + modified)
124
- end
125
- end
126
- @listener.start
127
- end
128
-
129
134
  def self.configure_pry
130
135
  # Set up IO.
131
136
  Pry.config.input = Readline
@@ -139,19 +144,16 @@ module RSpec
139
144
  Pry.config.history_file = @history_file
140
145
  end
141
146
 
142
- def self.refresh
143
- @file_change_mutex.synchronize do
144
- @updated_files.uniq.each do |filename|
145
- @output_stream.puts "changed: #{filename}"
146
- trace = TracePoint.new(:class) do |tp|
147
- @configuration.on_class_load.call(tp.self)
148
- end
149
- trace.enable
150
- load filename
151
- trace.disable
152
- @output_stream.puts
147
+ def self.refresh(output: @output_stream)
148
+ get_updated_files.each do |filename|
149
+ output.puts "changed: #{filename}"
150
+ trace = TracePoint.new(:class) do |tp|
151
+ @configuration.on_class_load.call(tp.self)
153
152
  end
154
- @updated_files.clear
153
+ trace.enable
154
+ load filename
155
+ trace.disable
156
+ output.puts
155
157
  end
156
158
  @configuration.refresh.call
157
159
  end
@@ -178,7 +180,7 @@ module RSpec
178
180
  end
179
181
 
180
182
  def self.rspec(args)
181
- @command_mutex.synchronize do
183
+ @rspec_mutex.synchronize do
182
184
  begin
183
185
  @runner = RSpec::Interactive::Runner.new(parse_args(args))
184
186
 
@@ -211,25 +213,22 @@ module RSpec
211
213
  end
212
214
 
213
215
  def self.rspec_for_server(client, args)
214
- @command_mutex.synchronize do
216
+ @rspec_mutex.synchronize do
215
217
  disable_pry = ENV['DISABLE_PRY']
216
218
  output = ClientOutput.new(client)
217
219
 
218
220
  ENV['TEAMCITY_RAKE_RUNNER_DEBUG_OUTPUT_CAPTURER_ENABLED'] = 'false'
219
221
  Rake::TeamCity::RunnerCommon.class_variable_set(:@@original_stdout, output)
220
222
 
221
- Stdio.capture(
222
- stdout: output,
223
- stderr: output) do
224
-
225
- await_startup(output: output)
223
+ return unless await_startup(output: output)
226
224
 
225
+ Stdio.capture(stdout: output, stderr: output) do
227
226
  # Prevent the debugger from being used. The server isn't interactive.
228
227
  ENV['DISABLE_PRY'] = 'true'
229
228
 
230
- @runner = RSpec::Interactive::Runner.new(parse_args(args))
229
+ runner = RSpec::Interactive::Runner.new(parse_args(args))
231
230
 
232
- refresh
231
+ refresh(output: output)
233
232
 
234
233
  # RSpec::Interactive-specific RSpec configuration
235
234
  RSpec.configure do |config|
@@ -250,18 +249,17 @@ module RSpec
250
249
  RSpec.configuration.formatter = Spec::Runner::Formatter::TeamcityFormatter
251
250
 
252
251
  # Run.
253
- @runner.run
254
- rescue Errno::EPIPE => e
252
+ runner.run
253
+ rescue Errno::EPIPE, IOError
255
254
  # Don't care.
256
255
  ensure
257
256
  ENV['DISABLE_PRY'] = disable_pry
258
- @runner = nil
257
+ runner = nil
259
258
 
260
259
  # Reset
261
260
  RSpec.clear_examples
262
261
  RSpec.reset
263
262
 
264
- await_startup(output: output)
265
263
  @config_cache.replay_configuration
266
264
  end
267
265
  end
@@ -279,24 +277,69 @@ module RSpec
279
277
  return yield if line.nil? # EOF
280
278
  return yield if line.empty? # blank line
281
279
 
282
- begin
283
- await_startup
284
- rescue Interrupt
280
+ if await_startup
281
+ yield
282
+ else
285
283
  @output_stream.puts
286
- return true
284
+ true
287
285
  end
288
-
289
- yield
290
286
  end
291
287
 
292
288
  def self.await_startup(output: @output_stream)
293
- if @startup_thread
294
- if @startup_thread.alive?
295
- output.puts 'waiting for configure_rspec...'
296
- end
289
+ return true unless @startup_thread
290
+
291
+ if @startup_thread.alive?
292
+ output.puts 'waiting for configure_rspec...'
293
+ end
294
+
295
+ begin
297
296
  @startup_thread.join
298
297
  @startup_thread = nil
298
+ print_startup_output(output: output)
299
+ true
300
+ rescue Interrupt
301
+ false
302
+ rescue StandardError => e
303
+ print_startup_output(output: output)
304
+ output.puts 'configure_rspec failed'
305
+ log_exception(output, e)
306
+ false
307
+ end
308
+ end
309
+
310
+ def self.log_exception(output, e)
311
+ output.puts "#{e.backtrace[0]}: #{e.message} (#{e.class})"
312
+ e.backtrace[1..-1].each { |b| output.puts "\t#{b}" }
313
+ end
314
+
315
+ def self.print_startup_output(output: @output_stream)
316
+ return if @startup_output.nil? || @startup_output.string.empty?
317
+
318
+ output.puts(@startup_output.string)
319
+ @startup_output = nil
320
+ end
321
+
322
+ def self.configure_watched_files
323
+ @watched_files = get_watched_files
324
+ end
325
+
326
+ def self.get_watched_files
327
+ return Set.new if @configuration.watch_dirs.empty?
328
+ entries = Find.find(*@configuration.watch_dirs).flat_map do |file|
329
+ if FileTest.file?(file)
330
+ [[file, File.mtime(file).to_i]]
331
+ else
332
+ []
333
+ end
299
334
  end
335
+ entries.to_set
336
+ end
337
+
338
+ def self.get_updated_files
339
+ new_watched_files = get_watched_files
340
+ difference = new_watched_files - @watched_files
341
+ @watched_files = new_watched_files
342
+ difference.map(&:first)
300
343
  end
301
344
  end
302
345
  end
@@ -27,6 +27,5 @@ Gem::Specification.new do |spec|
27
27
 
28
28
  spec.add_dependency 'rspec-core'
29
29
  spec.add_dependency 'rspec-teamcity', '1.0.0'
30
- spec.add_dependency 'listen'
31
30
  spec.add_dependency 'pry'
32
31
  end
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.8
4
+ version: 0.9.11
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-27 00:00:00.000000000 Z
11
+ date: 2022-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-core
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.0.0
41
- - !ruby/object:Gem::Dependency
42
- name: listen
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: pry
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -103,6 +89,7 @@ files:
103
89
  - lib/rspec-interactive/runner.rb
104
90
  - lib/rspec-interactive/stdio.rb
105
91
  - lib/rspec-interactive/string_output.rb
92
+ - lib/rspec-interactive/threaded_output.rb
106
93
  - lib/rspec-interactive/version.rb
107
94
  - lib/teamcity/spec/runner/formatter/teamcity/formatter.rb
108
95
  - rspec-interactive.gemspec