turbo_tests 1.2.2 → 1.3.0

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