turbo_tests 1.2.2 → 1.3.0

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: 92f70e0d1c7d01b5f9d17960ddcf2418c8c4fa620e8c46d0bb81df21b9193452
4
- data.tar.gz: 0a21dd64949d53a8045e167754f19b698356f2a5c088f6ad56b83297d42932a6
3
+ metadata.gz: 83d546a7efd52f8d3c1e20d6973b3a956c7cbf2f2b51b5e78c7d2ad67819b7db
4
+ data.tar.gz: 6f9d1a0841e3121a814c9f98a6ab0ac7146a78506d7a8adec622b9cf6e8e4a53
5
5
  SHA512:
6
- metadata.gz: 0d0e28e448d9b3f6e8dc5f47ef6b6308d3a8a08ffdcdcacdddc20f979af2a1f6d7e0827afbe5cc1fd09293efa3abed703cf7c0082a5d5cc400dd32fb9c9672a0
7
- data.tar.gz: 6efbeb21524f9973d759914766cf0966f4b3da0d0c68dab75c4efe0c412808df6a979324793ce3de21ff77745ca7f5bffda605f3a6e73635839e14e84b1d4658
6
+ metadata.gz: ad2917d505e40659a07e665523eff5af84f7b3ed9e2dacd8e7e1dd08ecc3eea88e507572f49c31cb973bbc63e1922825ef8a2c690db954689cf3afa071dbcb40
7
+ data.tar.gz: 7da1494e59ecaff728dd8a0231e96d83a89f15cc67a0f9a5a67dbc4539fc3c0268cf43824ade7caed0aa2565e8b559e0996d0706e0b210061fd02d8990d71fc1
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
+ --tty
3
4
  --require spec_helper
data/Gemfile CHANGED
@@ -3,4 +3,4 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in turbo_tests.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake", "~> 12.0"
6
+ gem "rake", "~> 13.0"
data/Gemfile.lock CHANGED
@@ -1,10 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- turbo_tests (1.2.2)
4
+ turbo_tests (1.3.0)
5
5
  bundler
6
6
  parallel_tests (~> 3.3)
7
- rspec (~> 3.10.0)
7
+ rspec (~> 3.10)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
@@ -12,13 +12,13 @@ GEM
12
12
  coderay (1.1.3)
13
13
  diff-lcs (1.4.4)
14
14
  method_source (1.0.0)
15
- parallel (1.20.1)
16
- parallel_tests (3.5.0)
15
+ parallel (1.21.0)
16
+ parallel_tests (3.7.3)
17
17
  parallel
18
- pry (0.14.0)
18
+ pry (0.14.1)
19
19
  coderay (~> 1.1)
20
20
  method_source (~> 1.0)
21
- rake (12.3.3)
21
+ rake (13.0.6)
22
22
  rspec (3.10.0)
23
23
  rspec-core (~> 3.10.0)
24
24
  rspec-expectations (~> 3.10.0)
@@ -37,9 +37,9 @@ PLATFORMS
37
37
  ruby
38
38
 
39
39
  DEPENDENCIES
40
- pry (~> 0.13)
41
- rake (~> 12.0)
40
+ pry (~> 0.14)
41
+ rake (~> 13.0)
42
42
  turbo_tests!
43
43
 
44
44
  BUNDLED WITH
45
- 2.1.4
45
+ 2.2.27
data/README.md CHANGED
@@ -78,6 +78,7 @@ Options:
78
78
  -f, --format FORMATTER Choose a formatter. Available formatters: progress (p), documentation (d). Default: progress
79
79
  -t, --tag TAG Run examples with the specified tag.
80
80
  -o, --out FILE Write output to a file instead of $stdout
81
+ --runtime-log FILE Location of previously recorded test runtimes
81
82
  -v, --verbose More output
82
83
  --fail-fast=[N]
83
84
  ```
@@ -0,0 +1,5 @@
1
+ RSpec.describe "Fixture of spec file with errors outside of examples" do
2
+ it("passes") { expect(2 * 2).to eql(4) }
3
+
4
+ 1 / 0
5
+ end
@@ -0,0 +1,15 @@
1
+ RSpec.describe "Fixture of spec file with pending failed examples" do
2
+ it "is implemented but skipped with 'pending'" do
3
+ pending("TODO: skipped with 'pending'")
4
+
5
+ expect(2).to eq(3)
6
+ end
7
+
8
+ it "is implemented but skipped with 'skip'", skip: "TODO: skipped with 'skip'" do
9
+ expect(100).to eq(500)
10
+ end
11
+
12
+ xit "is implemented but skipped with 'xit'" do
13
+ expect(1).to eq(42)
14
+ end
15
+ end
@@ -13,6 +13,7 @@ module TurboTests
13
13
  formatters = []
14
14
  tags = []
15
15
  count = nil
16
+ runtime_log = nil
16
17
  verbose = false
17
18
  fail_fast = nil
18
19
 
@@ -57,6 +58,10 @@ module TurboTests
57
58
  formatters.last[:outputs] << filename
58
59
  end
59
60
 
61
+ opts.on("--runtime-log FILE", "Location of previously recorded test runtimes") do |filename|
62
+ runtime_log = filename
63
+ end
64
+
60
65
  opts.on("-v", "--verbose", "More output") do
61
66
  verbose = true
62
67
  end
@@ -90,6 +95,7 @@ module TurboTests
90
95
  formatters: formatters,
91
96
  tags: tags,
92
97
  files: @argv.empty? ? ["spec"] : @argv,
98
+ runtime_log: runtime_log,
93
99
  verbose: verbose,
94
100
  fail_fast: fail_fast,
95
101
  count: count,
@@ -29,7 +29,7 @@ module TurboTests
29
29
  :example_pending,
30
30
  :example_group_started,
31
31
  :example_group_finished,
32
- :example_pending,
32
+ :message,
33
33
  :seed
34
34
  )
35
35
 
@@ -39,59 +39,65 @@ module TurboTests
39
39
  @output = output
40
40
  end
41
41
 
42
-
43
42
  def start(notification)
44
43
  output_row(
45
- "type" => :load_summary,
46
- "summary" => load_summary_to_json(notification)
44
+ type: :load_summary,
45
+ summary: load_summary_to_json(notification)
47
46
  )
48
47
  end
49
48
 
50
49
  def example_group_started(notification)
51
50
  output_row(
52
- "type" => :group_started,
53
- "group" => group_to_json(notification)
51
+ type: :group_started,
52
+ group: group_to_json(notification)
54
53
  )
55
54
  end
56
55
 
57
56
  def example_group_finished(notification)
58
57
  output_row(
59
- "type" => :group_finished,
60
- "group" => group_to_json(notification)
58
+ type: :group_finished,
59
+ group: group_to_json(notification)
61
60
  )
62
61
  end
63
62
 
64
63
  def example_passed(notification)
65
64
  output_row(
66
- "type" => :example_passed,
67
- "example" => example_to_json(notification.example)
65
+ type: :example_passed,
66
+ example: example_to_json(notification.example)
68
67
  )
69
68
  end
70
69
 
71
70
  def example_pending(notification)
72
71
  output_row(
73
- "type" => :example_pending,
74
- "example" => example_to_json(notification.example)
72
+ type: :example_pending,
73
+ example: example_to_json(notification.example)
75
74
  )
76
75
  end
77
76
 
78
77
  def example_failed(notification)
79
78
  output_row(
80
- "type" => :example_failed,
81
- "example" => example_to_json(notification.example)
79
+ type: :example_failed,
80
+ example: example_to_json(notification.example)
82
81
  )
83
82
  end
84
83
 
85
84
  def seed(notification)
86
85
  output_row(
87
- "type" => :seed,
88
- "seed" => notification.seed
86
+ type: :seed,
87
+ seed: notification.seed
89
88
  )
90
89
  end
91
90
 
92
91
  def close(notification)
93
92
  output_row(
94
- "type" => :close
93
+ type: :close
94
+ )
95
+ end
96
+
97
+ def message(notification)
98
+ output_row(
99
+ type: :message,
100
+ message: notification.message
95
101
  )
96
102
  end
97
103
 
@@ -100,62 +106,65 @@ module TurboTests
100
106
  def exception_to_json(exception)
101
107
  if exception
102
108
  {
103
- "class_name" => exception.class.name.to_s,
104
- "backtrace" => exception.backtrace,
105
- "message" => exception.message,
106
- "cause" => exception_to_json(exception.cause)
109
+ class_name: exception.class.name.to_s,
110
+ backtrace: exception.backtrace,
111
+ message: exception.message,
112
+ cause: exception_to_json(exception.cause)
107
113
  }
108
114
  end
109
115
  end
110
116
 
111
117
  def execution_result_to_json(result)
112
118
  {
113
- "example_skipped?" => result.example_skipped?,
114
- "pending_message" => result.pending_message,
115
- "status" => result.status,
116
- "pending_fixed?" => result.pending_fixed?,
117
- "exception" => exception_to_json(result.exception)
119
+ example_skipped?: result.example_skipped?,
120
+ pending_message: result.pending_message,
121
+ status: result.status,
122
+ pending_fixed?: result.pending_fixed?,
123
+ exception: exception_to_json(result.exception || result.pending_exception)
118
124
  }
119
125
  end
120
126
 
121
127
  def stack_frame_to_json(frame)
122
128
  {
123
- "shared_group_name" => frame.shared_group_name,
124
- "inclusion_location" => frame.inclusion_location
129
+ shared_group_name: frame.shared_group_name,
130
+ inclusion_location: frame.inclusion_location
125
131
  }
126
132
  end
127
133
 
128
134
  def example_to_json(example)
129
135
  {
130
- "execution_result" => execution_result_to_json(example.execution_result),
131
- "location" => example.location,
132
- "description" => example.description,
133
- "full_description" => example.full_description,
134
- "metadata" => {
135
- "shared_group_inclusion_backtrace" =>
136
- example.metadata[:shared_group_inclusion_backtrace].map { |frame| stack_frame_to_json(frame) }
136
+ execution_result: execution_result_to_json(example.execution_result),
137
+ location: example.location,
138
+ description: example.description,
139
+ full_description: example.full_description,
140
+ metadata: {
141
+ shared_group_inclusion_backtrace:
142
+ example
143
+ .metadata[:shared_group_inclusion_backtrace]
144
+ .map { |frame| stack_frame_to_json(frame) }
137
145
  },
138
- "location_rerun_argument" => example.location_rerun_argument
146
+ location_rerun_argument: example.location_rerun_argument
139
147
  }
140
148
  end
141
149
 
142
150
  def load_summary_to_json(notification)
143
151
  {
144
152
  count: notification.count,
145
- load_time: notification.load_time
153
+ load_time: notification.load_time,
146
154
  }
147
155
  end
148
156
 
149
157
  def group_to_json(notification)
150
158
  {
151
- "group": {
152
- "description": notification.group.description
159
+ group: {
160
+ description: notification.group.description
153
161
  }
154
162
  }
155
163
  end
156
164
 
157
165
  def output_row(obj)
158
- output.puts ENV["RSPEC_FORMATTER_OUTPUT_ID"] + obj.to_json
166
+ output.puts(obj.to_json)
167
+ output.flush
159
168
  end
160
169
  end
161
170
  end
@@ -11,7 +11,7 @@ module TurboTests
11
11
  name, outputs = config.values_at(:name, :outputs)
12
12
 
13
13
  outputs.map! do |filename|
14
- filename == "-" ? STDOUT : File.open(filename, "w")
14
+ filename == "-" ? $stdout : File.open(filename, "w")
15
15
  end
16
16
 
17
17
  reporter.add(name, outputs)
@@ -28,8 +28,10 @@ module TurboTests
28
28
  @pending_examples = []
29
29
  @failed_examples = []
30
30
  @all_examples = []
31
+ @messages = []
31
32
  @start_time = start_time
32
33
  @load_time = 0
34
+ @errors_outside_of_examples_count = 0
33
35
  end
34
36
 
35
37
  def add(name, outputs)
@@ -76,6 +78,15 @@ module TurboTests
76
78
  @failed_examples << example
77
79
  end
78
80
 
81
+ def message(message)
82
+ delegate_to_formatters(:message, RSpec::Core::Notifications::MessageNotification.new(message))
83
+ @messages << message
84
+ end
85
+
86
+ def error_outside_of_examples
87
+ @errors_outside_of_examples_count += 1
88
+ end
89
+
79
90
  def finish
80
91
  # SEE: https://bit.ly/2NP87Cz
81
92
  end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
@@ -97,7 +108,7 @@ module TurboTests
97
108
  @failed_examples,
98
109
  @pending_examples,
99
110
  @load_time,
100
- 0
111
+ @errors_outside_of_examples_count
101
112
  ))
102
113
  delegate_to_formatters(:close,
103
114
  RSpec::Core::Notifications::NullNotification)
@@ -16,16 +16,22 @@ module TurboTests
16
16
 
17
17
  # SEE: https://bit.ly/2NP87Cz
18
18
  start_time = opts.fetch(:start_time) { Process.clock_gettime(Process::CLOCK_MONOTONIC) }
19
+ runtime_log = opts.fetch(:runtime_log, nil)
19
20
  verbose = opts.fetch(:verbose, false)
20
21
  fail_fast = opts.fetch(:fail_fast, nil)
21
22
  count = opts.fetch(:count, nil)
22
23
 
24
+ if verbose
25
+ STDERR.puts "VERBOSE"
26
+ end
27
+
23
28
  reporter = Reporter.from_config(formatters, start_time)
24
29
 
25
30
  new(
26
31
  reporter: reporter,
27
32
  files: files,
28
33
  tags: tags,
34
+ runtime_log: runtime_log,
29
35
  verbose: verbose,
30
36
  fail_fast: fail_fast,
31
37
  count: count
@@ -36,17 +42,17 @@ module TurboTests
36
42
  @reporter = opts[:reporter]
37
43
  @files = opts[:files]
38
44
  @tags = opts[:tags]
45
+ @runtime_log = opts[:runtime_log] || "tmp/turbo_rspec_runtime.log"
39
46
  @verbose = opts[:verbose]
40
47
  @fail_fast = opts[:fail_fast]
41
48
  @count = opts[:count]
42
49
  @load_time = 0
43
50
  @load_count = 0
44
-
45
51
  @failure_count = 0
46
- @runtime_log = "tmp/parallel_runtime_rspec.log"
47
52
 
48
53
  @messages = Queue.new
49
54
  @threads = []
55
+ @error = false
50
56
  end
51
57
 
52
58
  def run
@@ -55,17 +61,33 @@ module TurboTests
55
61
  ParallelTests::RSpec::Runner.tests_with_size(@files, {}).size
56
62
  ].min
57
63
 
64
+ use_runtime_info = @files == ["spec"]
65
+
66
+ group_opts = {}
67
+
68
+ if use_runtime_info
69
+ group_opts[:runtime_log] = @runtime_log
70
+ else
71
+ group_opts[:group_by] = :filesize
72
+ end
73
+
58
74
  tests_in_groups =
59
75
  ParallelTests::RSpec::Runner.tests_in_groups(
60
76
  @files,
61
77
  @num_processes,
62
- runtime_log: @runtime_log
78
+ **group_opts
63
79
  )
64
80
 
81
+ setup_tmp_dir
82
+
83
+ subprocess_opts = {
84
+ record_runtime: use_runtime_info
85
+ }
86
+
65
87
  report_number_of_tests(tests_in_groups)
66
88
 
67
- tests_in_groups.each_with_index do |tests, process_id|
68
- start_regular_subprocess(tests, process_id + 1)
89
+ wait_threads = tests_in_groups.map.with_index do |tests, process_id|
90
+ start_regular_subprocess(tests, process_id + 1, **subprocess_opts)
69
91
  end
70
92
 
71
93
  handle_messages
@@ -74,38 +96,64 @@ module TurboTests
74
96
 
75
97
  @threads.each(&:join)
76
98
 
77
- @reporter.failed_examples.empty?
99
+ @reporter.failed_examples.empty? && wait_threads.map(&:value).all?(&:success?)
78
100
  end
79
101
 
80
- protected
102
+ private
103
+
104
+ def setup_tmp_dir
105
+ begin
106
+ FileUtils.rm_r("tmp/test-pipes")
107
+ rescue Errno::ENOENT
108
+ end
109
+
110
+ FileUtils.mkdir_p("tmp/test-pipes/")
111
+ end
81
112
 
82
- def start_regular_subprocess(tests, process_id)
113
+ def start_regular_subprocess(tests, process_id, **opts)
83
114
  start_subprocess(
84
115
  {"TEST_ENV_NUMBER" => process_id.to_s},
85
116
  @tags.map { |tag| "--tag=#{tag}" },
86
117
  tests,
87
- process_id
118
+ process_id,
119
+ **opts
88
120
  )
89
121
  end
90
122
 
91
- def start_subprocess(env, extra_args, tests, process_id)
123
+ def start_subprocess(env, extra_args, tests, process_id, record_runtime:)
92
124
  if tests.empty?
93
125
  @messages << {
94
- "type" => "exit",
95
- "process_id" => process_id
126
+ type: "exit",
127
+ process_id: process_id
96
128
  }
97
129
  else
98
- require "securerandom"
99
- env["RSPEC_FORMATTER_OUTPUT_ID"] = SecureRandom.uuid
100
- env["RUBYOPT"] = "-I#{File.expand_path("..", __dir__)}"
130
+ tmp_filename = "tmp/test-pipes/subprocess-#{process_id}"
131
+
132
+ begin
133
+ File.mkfifo(tmp_filename)
134
+ rescue Errno::EEXIST
135
+ end
136
+
137
+ env["RUBYOPT"] = ["-I#{File.expand_path("..", __dir__)}", ENV["RUBYOPT"]].compact.join(" ")
138
+ env["RSPEC_SILENCE_FILTER_ANNOUNCEMENTS"] = "1"
139
+
140
+ record_runtime_options =
141
+ if record_runtime
142
+ [
143
+ "--format", "ParallelTests::RSpec::RuntimeLogger",
144
+ "--out", @runtime_log,
145
+ ]
146
+ else
147
+ []
148
+ end
101
149
 
102
150
  command = [
103
151
  ENV["BUNDLE_BIN_PATH"], "exec", "rspec",
104
152
  *extra_args,
105
- "--seed", rand(2**16).to_s,
106
- "--format", "ParallelTests::RSpec::RuntimeLogger",
107
- "--out", @runtime_log,
153
+ "--seed", rand(0xFFFF).to_s,
108
154
  "--format", "TurboTests::JsonRowsFormatter",
155
+ "--out", tmp_filename,
156
+ *record_runtime_options,
109
157
  *tests
110
158
  ]
111
159
 
@@ -118,29 +166,33 @@ module TurboTests
118
166
  STDERR.puts "Process #{process_id}: #{command_str}"
119
167
  end
120
168
 
121
- _stdin, stdout, stderr, _wait_thr = Open3.popen3(env, *command)
169
+ stdin, stdout, stderr, wait_thr = Open3.popen3(env, *command)
170
+ stdin.close
122
171
 
123
172
  @threads <<
124
- Thread.new {
125
- require "json"
126
- stdout.each_line do |line|
127
- result = line.split(env["RSPEC_FORMATTER_OUTPUT_ID"])
128
-
129
- output = result.shift
130
- STDOUT.print(output) unless output.empty?
131
-
132
- message = result.shift
133
- next unless message
134
-
135
- message = JSON.parse(message)
136
- message["process_id"] = process_id
137
- @messages << message
173
+ Thread.new do
174
+ File.open(tmp_filename) do |fd|
175
+ fd.each_line do |line|
176
+ message = JSON.parse(line, symbolize_names: true)
177
+
178
+ message[:process_id] = process_id
179
+ @messages << message
180
+ end
138
181
  end
139
182
 
140
- @messages << {"type" => "exit", "process_id" => process_id}
141
- }
183
+ @messages << {type: "exit", process_id: process_id}
184
+ end
142
185
 
186
+ @threads << start_copy_thread(stdout, STDOUT)
143
187
  @threads << start_copy_thread(stderr, STDERR)
188
+
189
+ @threads << Thread.new {
190
+ unless wait_thr.value.success?
191
+ @messages << {type: "error"}
192
+ end
193
+ }
194
+
195
+ wait_thr
144
196
  end
145
197
  end
146
198
 
@@ -149,6 +201,7 @@ module TurboTests
149
201
  loop do
150
202
  msg = src.readpartial(4096)
151
203
  rescue EOFError
204
+ src.close
152
205
  break
153
206
  else
154
207
  dst.write(msg)
@@ -161,40 +214,47 @@ module TurboTests
161
214
 
162
215
  loop do
163
216
  message = @messages.pop
164
- case message["type"]
217
+ case message[:type]
165
218
  when "example_passed"
166
- example = FakeExample.from_obj(message["example"])
219
+ example = FakeExample.from_obj(message[:example])
167
220
  @reporter.example_passed(example)
168
221
  when "group_started"
169
- @reporter.group_started(message["group"].to_struct)
222
+ @reporter.group_started(message[:group].to_struct)
170
223
  when "group_finished"
171
224
  @reporter.group_finished
172
225
  when "example_pending"
173
- example = FakeExample.from_obj(message["example"])
226
+ example = FakeExample.from_obj(message[:example])
174
227
  @reporter.example_pending(example)
175
228
  when "load_summary"
176
- message = message["summary"]
229
+ message = message[:summary]
177
230
  # NOTE: notifications order and content is not guaranteed hence the fetch
178
231
  # and count increment tracking to get the latest accumulated load time
179
- @reporter.load_time = message["load_time"] if message.fetch("count", 0) > @load_count
232
+ @reporter.load_time = message[:load_time] if message.fetch(:count, 0) > @load_count
180
233
  when "example_failed"
181
- example = FakeExample.from_obj(message["example"])
234
+ example = FakeExample.from_obj(message[:example])
182
235
  @reporter.example_failed(example)
183
236
  @failure_count += 1
184
237
  if fail_fast_met
185
238
  @threads.each(&:kill)
186
239
  break
187
240
  end
241
+ when "message"
242
+ @reporter.message(message[:message])
188
243
  when "seed"
189
244
  when "close"
245
+ when "error"
246
+ @reporter.error_outside_of_examples
247
+ @error = true
190
248
  when "exit"
191
249
  exited += 1
192
250
  if exited == @num_processes
193
251
  break
194
252
  end
195
253
  else
196
- warn("Unhandled message in main process: #{message}")
254
+ STDERR.puts("Unhandled message in main process: #{message}")
197
255
  end
256
+
257
+ STDOUT.flush
198
258
  end
199
259
  rescue Interrupt
200
260
  end
@@ -203,8 +263,6 @@ module TurboTests
203
263
  !@fail_fast.nil? && @fail_fast >= @failure_count
204
264
  end
205
265
 
206
- private
207
-
208
266
  def report_number_of_tests(groups)
209
267
  name = ParallelTests::RSpec::Runner.test_file_name
210
268
 
@@ -1,3 +1,3 @@
1
1
  module TurboTests
2
- VERSION = "1.2.2"
2
+ VERSION = "1.3.0"
3
3
  end
data/lib/turbo_tests.rb CHANGED
@@ -23,28 +23,29 @@ module TurboTests
23
23
  klass =
24
24
  Class.new(FakeException) {
25
25
  define_singleton_method(:name) do
26
- obj["class_name"]
26
+ obj[:class_name]
27
27
  end
28
28
  }
29
29
 
30
30
  klass.new(
31
- obj["backtrace"],
32
- obj["message"],
33
- FakeException.from_obj(obj["cause"])
31
+ obj[:backtrace],
32
+ obj[:message],
33
+ FakeException.from_obj(obj[:cause])
34
34
  )
35
35
  end
36
36
  end
37
37
  end
38
38
 
39
- FakeExecutionResult = Struct.new(:example_skipped?, :pending_message, :status, :pending_fixed?, :exception)
39
+ FakeExecutionResult = Struct.new(:example_skipped?, :pending_message, :status, :pending_fixed?, :exception, :pending_exception)
40
40
  class FakeExecutionResult
41
41
  def self.from_obj(obj)
42
42
  new(
43
- obj["example_skipped?"],
44
- obj["pending_message"],
45
- obj["status"].to_sym,
46
- obj["pending_fixed?"],
47
- FakeException.from_obj(obj["exception"])
43
+ obj[:example_skipped?],
44
+ obj[:pending_message],
45
+ obj[:status].to_sym,
46
+ obj[:pending_fixed?],
47
+ FakeException.from_obj(obj[:exception]),
48
+ FakeException.from_obj(obj[:exception])
48
49
  )
49
50
  end
50
51
  end
@@ -52,24 +53,24 @@ module TurboTests
52
53
  FakeExample = Struct.new(:execution_result, :location, :description, :full_description, :metadata, :location_rerun_argument)
53
54
  class FakeExample
54
55
  def self.from_obj(obj)
55
- metadata = obj["metadata"]
56
+ metadata = obj[:metadata]
56
57
 
57
- metadata["shared_group_inclusion_backtrace"].map! do |frame|
58
+ metadata[:shared_group_inclusion_backtrace].map! do |frame|
58
59
  RSpec::Core::SharedExampleGroupInclusionStackFrame.new(
59
- frame["shared_group_name"],
60
- frame["inclusion_location"]
60
+ frame[:shared_group_name],
61
+ frame[:inclusion_location]
61
62
  )
62
63
  end
63
64
 
64
- metadata[:shared_group_inclusion_backtrace] = metadata.delete("shared_group_inclusion_backtrace")
65
+ metadata[:shared_group_inclusion_backtrace] = metadata.delete(:shared_group_inclusion_backtrace)
65
66
 
66
67
  new(
67
- FakeExecutionResult.from_obj(obj["execution_result"]),
68
- obj["location"],
69
- obj["description"],
70
- obj["full_description"],
68
+ FakeExecutionResult.from_obj(obj[:execution_result]),
69
+ obj[:location],
70
+ obj[:description],
71
+ obj[:full_description],
71
72
  metadata,
72
- obj["location_rerun_argument"]
73
+ obj[:location_rerun_argument]
73
74
  )
74
75
  end
75
76
 
data/turbo_tests.gemspec CHANGED
@@ -14,12 +14,12 @@ Gem::Specification.new do |spec|
14
14
  spec.metadata["source_code_uri"] = "https://github.com/serpapi/turbo_tests"
15
15
  spec.metadata["changelog_uri"] = "https://github.com/serpapi/turbo_tests/releases"
16
16
 
17
- spec.required_ruby_version = ">= 2.4.0"
17
+ spec.required_ruby_version = ">= 2.4"
18
18
 
19
- spec.add_dependency "rspec", "~> 3.10.0"
19
+ spec.add_dependency "rspec", "~> 3.10"
20
20
  spec.add_dependency "parallel_tests", "~> 3.3"
21
21
 
22
- spec.add_development_dependency "pry", "~> 0.13"
22
+ spec.add_development_dependency "pry", "~> 0.14"
23
23
 
24
24
  spec.add_runtime_dependency "bundler"
25
25
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbo_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Zub
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-02 00:00:00.000000000 Z
11
+ date: 2021-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 3.10.0
19
+ version: '3.10'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 3.10.0
26
+ version: '3.10'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: parallel_tests
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.13'
47
+ version: '0.14'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.13'
54
+ version: '0.14'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,6 +86,8 @@ files:
86
86
  - README.md
87
87
  - Rakefile
88
88
  - bin/turbo_tests
89
+ - fixtures/rspec/errors_outside_of_examples_spec.rb
90
+ - fixtures/rspec/pending_exceptions_spec.rb
89
91
  - lib/turbo_tests.rb
90
92
  - lib/turbo_tests/cli.rb
91
93
  - lib/turbo_tests/json_rows_formatter.rb
@@ -109,14 +111,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
109
111
  requirements:
110
112
  - - ">="
111
113
  - !ruby/object:Gem::Version
112
- version: 2.4.0
114
+ version: '2.4'
113
115
  required_rubygems_version: !ruby/object:Gem::Requirement
114
116
  requirements:
115
117
  - - ">="
116
118
  - !ruby/object:Gem::Version
117
119
  version: '0'
118
120
  requirements: []
119
- rubygems_version: 3.1.4
121
+ rubygems_version: 3.2.27
120
122
  signing_key:
121
123
  specification_version: 4
122
124
  summary: Runner for grosser/parallel_tests with incremental summarized output. Based