test_bench-session 2.1.3.2 → 3.0.0.0.pre.2

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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/lib/test_bench/session/controls/backtrace/location.rb +46 -0
  3. data/lib/test_bench/session/controls/backtrace.rb +81 -0
  4. data/lib/test_bench/session/controls/comment_disposition.rb +15 -0
  5. data/lib/test_bench/session/controls/event.rb +27 -1
  6. data/lib/test_bench/session/controls/events/aborted.rb +49 -0
  7. data/lib/test_bench/session/controls/events/commented.rb +26 -76
  8. data/lib/test_bench/session/controls/events/context_finished.rb +68 -28
  9. data/lib/test_bench/session/controls/events/context_started.rb +17 -32
  10. data/lib/test_bench/session/controls/events/detailed.rb +26 -76
  11. data/lib/test_bench/session/controls/events/failed.rb +16 -24
  12. data/lib/test_bench/session/controls/events/file_executed.rb +99 -0
  13. data/lib/test_bench/session/controls/events/file_not_found.rb +39 -0
  14. data/lib/test_bench/session/controls/events/file_queued.rb +39 -0
  15. data/lib/test_bench/session/controls/events/skipped.rb +49 -0
  16. data/lib/test_bench/session/controls/events/test_finished.rb +48 -28
  17. data/lib/test_bench/session/controls/events/test_started.rb +17 -32
  18. data/lib/test_bench/session/controls/events.rb +19 -19
  19. data/lib/test_bench/session/controls/exception/message.rb +21 -0
  20. data/lib/test_bench/session/controls/exception/raise.rb +50 -0
  21. data/lib/test_bench/session/controls/exception.rb +55 -21
  22. data/lib/test_bench/session/controls/message.rb +41 -0
  23. data/lib/test_bench/session/controls/{time.rb → metadata.rb} +1 -1
  24. data/lib/test_bench/session/controls/path/apex_directory.rb +74 -0
  25. data/lib/test_bench/session/controls/path/file/create.rb +111 -0
  26. data/lib/test_bench/session/controls/path/file.rb +40 -0
  27. data/lib/test_bench/session/controls/path.rb +85 -0
  28. data/lib/test_bench/session/controls/random.rb +1 -1
  29. data/lib/test_bench/session/controls/result.rb +3 -11
  30. data/lib/test_bench/session/controls/{events/event_data.rb → sequence.rb} +4 -2
  31. data/lib/test_bench/session/controls/status.rb +90 -0
  32. data/lib/test_bench/session/controls/telemetry.rb +13 -0
  33. data/lib/test_bench/session/controls/telemetry_sink.rb +29 -1
  34. data/lib/test_bench/session/controls/text.rb +31 -0
  35. data/lib/test_bench/session/controls/title.rb +12 -12
  36. data/lib/test_bench/session/controls.rb +31 -26
  37. data/lib/test_bench/session/defaults.rb +15 -0
  38. data/lib/test_bench/session/events.rb +12 -15
  39. data/lib/test_bench/session/exception/format_backtrace/substitute.rb +32 -0
  40. data/lib/test_bench/session/exception/format_backtrace.rb +112 -0
  41. data/lib/test_bench/session/isolate/substitute.rb +43 -0
  42. data/lib/test_bench/session/isolate.rb +157 -0
  43. data/lib/test_bench/session/result.rb +42 -0
  44. data/lib/test_bench/session/session.rb +137 -164
  45. data/lib/test_bench/session/status.rb +58 -0
  46. data/lib/test_bench/session/substitute/sink.rb +30 -45
  47. data/lib/test_bench/session/substitute.rb +91 -52
  48. data/lib/test_bench/session/trace.rb +51 -0
  49. data/lib/test_bench/session.rb +15 -15
  50. metadata +53 -45
  51. data/lib/test_bench/session/controls/comment.rb +0 -105
  52. data/lib/test_bench/session/controls/detail.rb +0 -91
  53. data/lib/test_bench/session/controls/events/context_skipped.rb +0 -47
  54. data/lib/test_bench/session/controls/events/fixture_finished.rb +0 -53
  55. data/lib/test_bench/session/controls/events/fixture_started.rb +0 -47
  56. data/lib/test_bench/session/controls/events/test_skipped.rb +0 -47
  57. data/lib/test_bench/session/controls/failure.rb +0 -19
  58. data/lib/test_bench/session/controls/fixture.rb +0 -19
  59. data/lib/test_bench/session/controls/output/detail.rb +0 -29
  60. data/lib/test_bench/session/controls/output.rb +0 -55
  61. data/lib/test_bench/session/controls/process_id.rb +0 -7
  62. data/lib/test_bench/session/controls/substitute/path.rb +0 -33
  63. data/lib/test_bench/session/output/get.rb +0 -27
  64. data/lib/test_bench/session/output/writer/buffer/interactive/viewport.rb +0 -165
  65. data/lib/test_bench/session/output/writer/buffer/interactive.rb +0 -139
  66. data/lib/test_bench/session/output/writer/buffer.rb +0 -27
  67. data/lib/test_bench/session/output/writer/defaults.rb +0 -17
  68. data/lib/test_bench/session/output/writer/substitute.rb +0 -17
  69. data/lib/test_bench/session/output/writer.rb +0 -95
  70. data/lib/test_bench/session/output.rb +0 -384
  71. data/lib/test_bench/session/projection.rb +0 -28
  72. data/lib/test_bench/session/store.rb +0 -59
  73. data/lib/test_bench/session/substitute/path.rb +0 -63
@@ -1,260 +1,233 @@
1
1
  module TestBench
2
2
  class Session
3
3
  Failure = Class.new(RuntimeError)
4
- Abort = Class.new(Failure)
4
+
5
+ ExecutionBreak = Object.new
5
6
 
6
7
  def telemetry
7
- @telemetry ||= TestBench::Telemetry::Substitute.build
8
+ @telemetry ||= Telemetry::Substitute.build
8
9
  end
9
10
  attr_writer :telemetry
10
11
 
11
- def failure_sequence
12
- @failure_sequence ||= 0
12
+ def format_backtrace
13
+ @format_backtrace ||= Exception::FormatBacktrace::Substitute.build
14
+ end
15
+ attr_writer :format_backtrace
16
+
17
+ def isolate
18
+ @isolate ||= Isolate::Substitute.build
19
+ end
20
+ attr_writer :isolate
21
+
22
+ def status
23
+ @status ||= Status.initial
13
24
  end
14
- attr_writer :failure_sequence
25
+ attr_writer :status
26
+
27
+ def trace
28
+ @trace ||= Trace.new
29
+ end
30
+ attr_writer :trace
15
31
 
16
32
  def assertion_sequence
17
33
  @assertion_sequence ||= 0
18
34
  end
19
35
  attr_writer :assertion_sequence
20
36
 
21
- def skip_sequence
22
- @skip_sequence ||= 0
23
- end
24
- attr_writer :skip_sequence
25
-
26
- def self.build(&block)
37
+ def self.build
27
38
  instance = new
28
39
 
29
40
  Telemetry.configure(instance)
30
-
31
- if not block.nil?
32
- block.(instance.telemetry)
33
- end
41
+ Exception::FormatBacktrace.configure(instance)
42
+ Isolate.configure(instance)
34
43
 
35
44
  instance
36
45
  end
37
46
 
38
- def self.configure(receiver, session: nil, attr_name: nil, &block)
39
- session ||= Store.fetch
40
- attr_name ||= :session
41
-
42
- instance = session
43
- receiver.public_send(:"#{attr_name}=", instance)
47
+ def self.instance
48
+ @instance ||= build
44
49
  end
45
50
 
46
- def inspect
47
- text = self.to_s
48
-
49
- instance_variables = self.instance_variables - [:@telemetry]
51
+ def self.configure(receiver, session: nil, attr_name: nil)
52
+ session ||= instance
53
+ attr_name ||= :session
50
54
 
51
- instance_variables.each_with_index do |name, index|
52
- ivar_text = String.new
55
+ receiver.public_send(:"#{attr_name}=", session)
56
+ end
53
57
 
54
- if index > 0
55
- ivar_text << ','
56
- end
58
+ def self.establish(session)
59
+ @instance = session
60
+ end
57
61
 
58
- value = instance_variable_get(name)
59
- value = value.inspect
62
+ def self.register_telemetry_sink(telemetry_sink)
63
+ instance.register_telemetry_sink(telemetry_sink)
64
+ end
60
65
 
61
- ivar_text << " #{name}=#{value}"
66
+ def assert(value, failure_message)
67
+ self.assertion_sequence += 1
62
68
 
63
- text.insert(-2, ivar_text)
69
+ if not value
70
+ raise Failure, failure_message
64
71
  end
65
-
66
- text
67
72
  end
68
73
 
69
- def passed?
70
- if failed?
71
- false
72
- elsif require_passing_test?
73
- asserted? && !skipped?
74
- else
75
- true
76
- end
74
+ def comment(text, disposition=nil)
75
+ record_event(Events::Commented.build(text, disposition))
77
76
  end
78
77
 
79
- def require_passing_test?
80
- Defaults.require_passing_tests
78
+ def detail(text, disposition=nil)
79
+ record_event(Events::Detailed.build(text, disposition))
81
80
  end
82
81
 
83
- def fixture(name, &block)
84
- original_failure_sequence = failure_sequence
85
-
86
- record_event(Events::FixtureStarted.new(name))
82
+ def test(title=nil, &block)
83
+ record_event(Events::TestStarted.build(title))
87
84
 
88
- begin
89
- block.()
85
+ pending_test_finished_event = Events::TestFinished.build(title)
90
86
 
91
- rescue Failure
87
+ evaluate(pending_test_finished_event) do
88
+ previous_sequence = self.assertion_sequence
92
89
 
93
- ensure
94
- result = !failed?(original_failure_sequence)
90
+ block.()
95
91
 
96
- record_event(Events::FixtureFinished.new(name, result))
92
+ if self.assertion_sequence == previous_sequence
93
+ raise Failure, "Test didn't perform an assertion"
94
+ end
97
95
  end
98
-
99
- result
100
96
  end
101
97
 
102
- def detail(text, quote, heading=nil)
103
- record_event(Events::Detailed.new(text, quote, heading))
104
- end
98
+ def context(title=nil, &block)
99
+ record_event(Events::ContextStarted.build(title))
100
+
101
+ pending_context_finished_event = Events::ContextFinished.build(title)
105
102
 
106
- def comment(text, quote, heading=nil)
107
- record_event(Events::Commented.new(text, quote, heading))
103
+ evaluate(pending_context_finished_event, &block)
108
104
  end
109
105
 
110
- def context!(...)
111
- if context(...) == false
112
- message = Session.abort_message
113
- raise Abort, message
114
- end
106
+ def skip(message=nil)
107
+ record_event(Events::Skipped.build(message))
115
108
  end
116
109
 
117
- def context(title=nil, &block)
118
- if block.nil?
119
- record_skip
120
- record_event(Events::ContextSkipped.new(title))
110
+ def execute(file_path)
111
+ if file_not_found?(file_path)
112
+ record_event(Events::FileNotFound.build(file_path))
121
113
  return
122
114
  end
123
115
 
124
- original_failure_sequence = failure_sequence
116
+ record_event(Events::FileQueued.build(file_path))
125
117
 
126
- record_event(Events::ContextStarted.new(title))
118
+ pended_event = Events::FileExecuted.build(file_path, result)
127
119
 
128
- begin
129
- block.()
130
-
131
- rescue Failure
132
-
133
- ensure
134
- result = !failed?(original_failure_sequence)
135
-
136
- record_event(Events::ContextFinished.new(title, result))
120
+ evaluate(pended_event) do
121
+ isolate.(file_path) do |event_data|
122
+ record_event(event_data)
123
+ end
137
124
  end
125
+ end
138
126
 
139
- result
127
+ def file_not_found?(file_path)
128
+ !File.exist?(file_path)
140
129
  end
141
130
 
142
- def test!(...)
143
- if test(...) == false
144
- message = Session.abort_message
145
- raise Abort, message
146
- end
131
+ def register_telemetry_sink(telemetry_sink)
132
+ telemetry.register(telemetry_sink)
147
133
  end
148
134
 
149
- def test(title=nil, &block)
150
- if block.nil?
151
- record_skip
152
- record_event(Events::TestSkipped.new(title))
153
- return
135
+ def inspect(raw: nil)
136
+ if raw
137
+ return super()
154
138
  end
155
139
 
156
- original_failure_sequence = failure_sequence
157
- original_assertion_sequence = assertion_sequence
158
-
159
- record_event(Events::TestStarted.new(title))
160
-
161
- begin
162
- block.()
140
+ telemetry_placeholder = Struct.new(:inspect).new("(not inspected)")
163
141
 
164
- result = !failed?(original_failure_sequence)
142
+ original_telemetry = self.telemetry
165
143
 
166
- if result
167
- if not asserted?(original_assertion_sequence)
168
- failure_message = Session.no_assertion_message
169
- fail(failure_message)
170
- end
171
- end
144
+ self.telemetry = telemetry_placeholder
172
145
 
173
- rescue Failure
174
- result = false
146
+ begin
147
+ super()
175
148
 
176
149
  ensure
177
- record_event(Events::TestFinished.new(title, result))
150
+ self.telemetry = original_telemetry
178
151
  end
179
-
180
- result
181
152
  end
182
153
 
183
- def assert(result)
184
- failure_message = Session.assertion_failure_message
154
+ def update(event_or_event_data)
155
+ case event_or_event_data
156
+ in Telemetry::Event => event
185
157
 
186
- record_assertion
158
+ in Telemetry::EventData => event_data
159
+ event_type = event_data.type
160
+ event_class = Events.const_get(event_type, false)
187
161
 
188
- if result == false
189
- fail(failure_message)
162
+ event = Telemetry::Event::Import.(event_data, event_class)
190
163
  end
191
- end
192
164
 
193
- def fail(message=nil)
194
- message ||= self.class.default_failure_message
165
+ case event
166
+ when Events::ContextStarted, Events::TestStarted
167
+ title = event.title
195
168
 
196
- record_failure
169
+ if not title.nil?
170
+ trace.push(title)
171
+ end
197
172
 
198
- record_event(Events::Failed.new(message))
173
+ when Events::Commented, Events::Detailed
174
+ trace.push(event.text)
175
+ end
199
176
 
200
- raise Failure, message
201
- end
177
+ telemetry.record(event)
202
178
 
203
- def asserted?(compare_sequence=nil)
204
- compare_sequence ||= 0
179
+ status.update(event)
205
180
 
206
- compare_sequence != assertion_sequence
207
- end
181
+ case event
182
+ when Events::Commented, Events::Detailed
183
+ trace.pop
208
184
 
209
- def register_telemetry_sink(telemetry_sink)
210
- telemetry.register(telemetry_sink)
185
+ when Events::ContextFinished, Events::TestFinished
186
+ title = event.title
187
+
188
+ if not title.nil?
189
+ trace.pop
190
+ end
191
+ end
211
192
  end
193
+ alias :record_event :update
212
194
 
213
- def record_assertion
214
- self.assertion_sequence += 1
195
+ def result(previous_status=nil)
196
+ status.result(previous_status)
215
197
  end
216
198
 
217
- def failed?(compare_sequence=nil)
218
- compare_sequence ||= 0
199
+ def evaluate(pending_event, &block)
200
+ previous_status = status.dup
219
201
 
220
- compare_sequence != failure_sequence
221
- end
202
+ catch(ExecutionBreak) do
203
+ block.(self)
204
+ end
222
205
 
223
- def record_event(event)
224
- telemetry.record(event)
225
- end
206
+ rescue Failure => failure
207
+ message = failure.message
208
+ record_event(Events::Failed.build(message))
226
209
 
227
- def record_failure
228
- self.failure_sequence += 1
229
- end
210
+ rescue ::Exception => exception
211
+ aborted_recorded = status.error_sequence > previous_status.error_sequence
230
212
 
231
- def skipped?
232
- skip_sequence != 0
233
- end
213
+ if not aborted_recorded
214
+ location = format_backtrace.(exception)
234
215
 
235
- def record_skip
236
- self.skip_sequence += 1
237
- end
216
+ message = exception.detailed_message
238
217
 
239
- def self.default_failure_message
240
- 'Failed'
241
- end
218
+ record_event(Events::Aborted.build(message, location))
219
+ end
242
220
 
243
- def self.assertion_failure_message
244
- "Assertion failed"
245
- end
221
+ raise exception
246
222
 
247
- def self.abort_message
248
- "Abort"
249
- end
223
+ ensure
224
+ result = status.result(previous_status, pending_event)
250
225
 
251
- def self.no_assertion_message
252
- "Test didn't perform an assertion"
253
- end
226
+ pending_event.result = result
227
+ record_event(pending_event)
254
228
 
255
- module Defaults
256
- def self.require_passing_tests
257
- ENV.fetch('TEST_BENCH_REQUIRE_PASSING_TEST', 'on') == 'on'
229
+ if exception.nil?
230
+ return result
258
231
  end
259
232
  end
260
233
  end
@@ -0,0 +1,58 @@
1
+ module TestBench
2
+ class Session
3
+ Status = Struct.new(:test_sequence, :failure_sequence, :error_sequence, :skip_sequence)
4
+
5
+ class Status
6
+ def self.initial
7
+ new(0, 0, 0, 0)
8
+ end
9
+
10
+ def result(previous_status=nil, pending_event=nil)
11
+ previous_status ||= Status.initial
12
+
13
+ compare_status = compare(previous_status)
14
+
15
+ if not pending_event.nil?
16
+ compare_status.update(pending_event)
17
+ end
18
+
19
+ if compare_status.error_sequence > 0
20
+ Result.aborted
21
+ elsif compare_status.failure_sequence > 0
22
+ Result.failed
23
+ elsif compare_status.skip_sequence > 0
24
+ Result.incomplete
25
+ elsif not compare_status.test_sequence > 0
26
+ Result.none
27
+ else
28
+ Result.passed
29
+ end
30
+ end
31
+
32
+ def update(event)
33
+ case event
34
+ when Events::TestFinished
35
+ self.test_sequence += 1
36
+ when Events::Failed
37
+ self.failure_sequence += 1
38
+ when Events::Aborted, Events::FileNotFound
39
+ self.error_sequence += 1
40
+ when Events::Skipped
41
+ self.skip_sequence += 1
42
+ end
43
+ end
44
+
45
+ def compare(previous_status)
46
+ test_sequence_difference = test_sequence - previous_status.test_sequence
47
+
48
+ failure_sequence_difference = failure_sequence - previous_status.failure_sequence
49
+
50
+ error_sequence_difference = error_sequence - previous_status.error_sequence
51
+
52
+ skip_sequence_difference = skip_sequence - previous_status.skip_sequence
53
+
54
+ Status.new(test_sequence_difference, failure_sequence_difference, error_sequence_difference, skip_sequence_difference)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -3,50 +3,35 @@ module TestBench
3
3
  module Substitute
4
4
  class Sink
5
5
  include Telemetry::Sink
6
- include Events
6
+
7
+ def trace
8
+ @trace ||= Trace.new
9
+ end
10
+ attr_writer :trace
7
11
 
8
12
  def records
9
13
  @records ||= []
10
14
  end
11
15
  attr_writer :records
12
16
 
13
- def path
14
- @path ||= Path.new
15
- end
16
- attr_writer :path
17
-
18
- def receive(event_data)
19
- event_type = event_data.type
17
+ def self.build(trace=nil)
18
+ instance = new
20
19
 
21
- case event_data.type
22
- when :TestStarted, :ContextStarted
23
- title, * = event_data.data
24
- if not title.nil?
25
- path.push(title)
26
- end
27
-
28
- when :TestFinished, :ContextFinished
29
- title, * = event_data.data
30
- if not title.nil?
31
- path.pop(title)
32
- end
20
+ if not trace.nil?
21
+ instance.trace = trace
33
22
  end
34
23
 
35
- record = Record.new(event_data)
36
- path.copy(record)
24
+ instance
25
+ end
37
26
 
38
- case event_data.type
39
- when :TestFinished, :ContextFinished
40
- title, * = event_data.data
41
- if not title.nil?
42
- record.path.push(title)
43
- end
27
+ def receive(event_data)
28
+ trace_copy = Trace.new
44
29
 
45
- when :Commented, :Detailed
46
- comment_text, * = event_data.data
47
- record.path.push(comment_text)
30
+ trace.each do |entry|
31
+ trace_copy.push(entry)
48
32
  end
49
33
 
34
+ record = Record.new(event_data, trace_copy)
50
35
  records.push(record)
51
36
 
52
37
  record
@@ -62,32 +47,32 @@ module TestBench
62
47
  end
63
48
  end
64
49
 
65
- def one_event?(event_class, *path_segments, **attributes)
66
- event_sink = event_sink(*path_segments)
50
+ def one_event?(event_class, *titles, **attributes)
51
+ event_sink = event_sink(*titles)
67
52
  event_sink.one_event?(event_class, **attributes)
68
53
  end
69
54
 
70
- def one_event(event_class, *path_segments, **attributes)
71
- event_sink = event_sink(*path_segments)
55
+ def one_event(event_class, *titles, **attributes)
56
+ event_sink = event_sink(*titles)
72
57
  event_sink.one_event(event_class, **attributes)
73
58
  end
74
59
 
75
- def any_event?(event_class, *path_segments, **attributes)
76
- event_sink = event_sink(*path_segments)
60
+ def any_event?(event_class, *titles, **attributes)
61
+ event_sink = event_sink(*titles)
77
62
  event_sink.any_event?(event_class, **attributes)
78
63
  end
79
64
  alias :event? :any_event?
80
65
 
81
- def events(event_class, *path_segments, **attributes)
82
- event_sink = event_sink(*path_segments)
66
+ def events(event_class, *titles, **attributes)
67
+ event_sink = event_sink(*titles)
83
68
  event_sink.events(event_class, **attributes)
84
69
  end
85
70
 
86
- def event_sink(*path_segments)
71
+ def event_sink(*titles)
87
72
  event_sink = Telemetry::Substitute::Sink.new
88
73
 
89
74
  records.each do |record|
90
- if record.match?(path_segments)
75
+ if record.match?(titles)
91
76
  event_data = record.event_data
92
77
 
93
78
  event_sink.receive(event_data)
@@ -97,10 +82,10 @@ module TestBench
97
82
  event_sink
98
83
  end
99
84
 
100
- Record = Struct.new(:event_data, :path) do
101
- def match?(path_segments)
102
- if path_segments.any?
103
- path.match?(*path_segments)
85
+ Record = Struct.new(:event_data, :trace) do
86
+ def match?(titles)
87
+ if titles.any?
88
+ trace.match?(*titles)
104
89
  else
105
90
  true
106
91
  end