rspec-interactive 0.9.8 → 0.9.11

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