app_identity 1.0.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 +7 -0
- data/.rdoc_options +28 -0
- data/Changelog.md +5 -0
- data/Contributing.md +70 -0
- data/Licence.md +25 -0
- data/Manifest.txt +30 -0
- data/README.md +70 -0
- data/Rakefile +50 -0
- data/bin/app-identity-suite-ruby +12 -0
- data/lib/app_identity/app.rb +214 -0
- data/lib/app_identity/error.rb +42 -0
- data/lib/app_identity/faraday_middleware.rb +94 -0
- data/lib/app_identity/internal.rb +130 -0
- data/lib/app_identity/rack_middleware.rb +242 -0
- data/lib/app_identity/validation.rb +83 -0
- data/lib/app_identity/versions.rb +194 -0
- data/lib/app_identity.rb +233 -0
- data/licences/APACHE-2.0.txt +168 -0
- data/licences/DCO.txt +34 -0
- data/spec.md +409 -0
- data/support/app_identity/suite/generator.rb +242 -0
- data/support/app_identity/suite/optional.json +491 -0
- data/support/app_identity/suite/program.rb +204 -0
- data/support/app_identity/suite/required.json +514 -0
- data/support/app_identity/suite/runner.rb +132 -0
- data/support/app_identity/suite.rb +10 -0
- data/support/app_identity/support.rb +119 -0
- data/test/minitest_helper.rb +24 -0
- data/test/test_app_identity.rb +124 -0
- data/test/test_app_identity_app.rb +64 -0
- data/test/test_app_identity_rack_middleware.rb +90 -0
- metadata +306 -0
@@ -0,0 +1,514 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"app": {
|
4
|
+
"version": 1
|
5
|
+
},
|
6
|
+
"description": "App V1, Proof V1",
|
7
|
+
"expect": "pass",
|
8
|
+
"proof": {
|
9
|
+
"version": 1
|
10
|
+
},
|
11
|
+
"spec_version": 4
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"app": {
|
15
|
+
"version": 1
|
16
|
+
},
|
17
|
+
"description": "App V1, Proof V2",
|
18
|
+
"expect": "pass",
|
19
|
+
"proof": {
|
20
|
+
"version": 2
|
21
|
+
},
|
22
|
+
"spec_version": 4
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"app": {
|
26
|
+
"version": 1
|
27
|
+
},
|
28
|
+
"description": "App V1, Proof V3",
|
29
|
+
"expect": "pass",
|
30
|
+
"proof": {
|
31
|
+
"version": 3
|
32
|
+
},
|
33
|
+
"spec_version": 4
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"app": {
|
37
|
+
"version": 1
|
38
|
+
},
|
39
|
+
"description": "App V1, Proof V4",
|
40
|
+
"expect": "pass",
|
41
|
+
"proof": {
|
42
|
+
"version": 4
|
43
|
+
},
|
44
|
+
"spec_version": 4
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"app": {
|
48
|
+
"version": 2
|
49
|
+
},
|
50
|
+
"description": "App V2, Proof V2",
|
51
|
+
"expect": "pass",
|
52
|
+
"proof": {
|
53
|
+
"version": 2
|
54
|
+
},
|
55
|
+
"spec_version": 4
|
56
|
+
},
|
57
|
+
{
|
58
|
+
"app": {
|
59
|
+
"version": 2
|
60
|
+
},
|
61
|
+
"description": "App V2, Proof V3",
|
62
|
+
"expect": "pass",
|
63
|
+
"proof": {
|
64
|
+
"version": 3
|
65
|
+
},
|
66
|
+
"spec_version": 4
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"app": {
|
70
|
+
"version": 2
|
71
|
+
},
|
72
|
+
"description": "App V2, Proof V4",
|
73
|
+
"expect": "pass",
|
74
|
+
"proof": {
|
75
|
+
"version": 4
|
76
|
+
},
|
77
|
+
"spec_version": 4
|
78
|
+
},
|
79
|
+
{
|
80
|
+
"app": {
|
81
|
+
"version": 3
|
82
|
+
},
|
83
|
+
"description": "App V3, Proof V3",
|
84
|
+
"expect": "pass",
|
85
|
+
"proof": {
|
86
|
+
"version": 3
|
87
|
+
},
|
88
|
+
"spec_version": 4
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"app": {
|
92
|
+
"version": 3
|
93
|
+
},
|
94
|
+
"description": "App V3, Proof V4",
|
95
|
+
"expect": "pass",
|
96
|
+
"proof": {
|
97
|
+
"version": 4
|
98
|
+
},
|
99
|
+
"spec_version": 4
|
100
|
+
},
|
101
|
+
{
|
102
|
+
"app": {
|
103
|
+
"version": 4
|
104
|
+
},
|
105
|
+
"description": "App V4, Proof V4",
|
106
|
+
"expect": "pass",
|
107
|
+
"proof": {
|
108
|
+
"version": 4
|
109
|
+
},
|
110
|
+
"spec_version": 4
|
111
|
+
},
|
112
|
+
{
|
113
|
+
"app": {
|
114
|
+
"config": {
|
115
|
+
"fuzz": 300
|
116
|
+
},
|
117
|
+
"version": 1
|
118
|
+
},
|
119
|
+
"description": "App V1, Proof V2 (custom fuzz)",
|
120
|
+
"expect": "pass",
|
121
|
+
"proof": {
|
122
|
+
"version": 2
|
123
|
+
},
|
124
|
+
"spec_version": 4
|
125
|
+
},
|
126
|
+
{
|
127
|
+
"app": {
|
128
|
+
"config": {
|
129
|
+
"fuzz": 300
|
130
|
+
},
|
131
|
+
"version": 1
|
132
|
+
},
|
133
|
+
"description": "App V1, Proof V3 (custom fuzz)",
|
134
|
+
"expect": "pass",
|
135
|
+
"proof": {
|
136
|
+
"version": 3
|
137
|
+
},
|
138
|
+
"spec_version": 4
|
139
|
+
},
|
140
|
+
{
|
141
|
+
"app": {
|
142
|
+
"config": {
|
143
|
+
"fuzz": 300
|
144
|
+
},
|
145
|
+
"version": 1
|
146
|
+
},
|
147
|
+
"description": "App V1, Proof V4 (custom fuzz)",
|
148
|
+
"expect": "pass",
|
149
|
+
"proof": {
|
150
|
+
"version": 4
|
151
|
+
},
|
152
|
+
"spec_version": 4
|
153
|
+
},
|
154
|
+
{
|
155
|
+
"app": {
|
156
|
+
"config": {
|
157
|
+
"fuzz": 300
|
158
|
+
},
|
159
|
+
"version": 2
|
160
|
+
},
|
161
|
+
"description": "App V2, Proof V2 (custom fuzz)",
|
162
|
+
"expect": "pass",
|
163
|
+
"proof": {
|
164
|
+
"version": 2
|
165
|
+
},
|
166
|
+
"spec_version": 4
|
167
|
+
},
|
168
|
+
{
|
169
|
+
"app": {
|
170
|
+
"config": {
|
171
|
+
"fuzz": 300
|
172
|
+
},
|
173
|
+
"version": 2
|
174
|
+
},
|
175
|
+
"description": "App V2, Proof V3 (custom fuzz)",
|
176
|
+
"expect": "pass",
|
177
|
+
"proof": {
|
178
|
+
"version": 3
|
179
|
+
},
|
180
|
+
"spec_version": 4
|
181
|
+
},
|
182
|
+
{
|
183
|
+
"app": {
|
184
|
+
"config": {
|
185
|
+
"fuzz": 300
|
186
|
+
},
|
187
|
+
"version": 2
|
188
|
+
},
|
189
|
+
"description": "App V2, Proof V4 (custom fuzz)",
|
190
|
+
"expect": "pass",
|
191
|
+
"proof": {
|
192
|
+
"version": 4
|
193
|
+
},
|
194
|
+
"spec_version": 4
|
195
|
+
},
|
196
|
+
{
|
197
|
+
"app": {
|
198
|
+
"config": {
|
199
|
+
"fuzz": 300
|
200
|
+
},
|
201
|
+
"version": 3
|
202
|
+
},
|
203
|
+
"description": "App V3, Proof V3 (custom fuzz)",
|
204
|
+
"expect": "pass",
|
205
|
+
"proof": {
|
206
|
+
"version": 3
|
207
|
+
},
|
208
|
+
"spec_version": 4
|
209
|
+
},
|
210
|
+
{
|
211
|
+
"app": {
|
212
|
+
"config": {
|
213
|
+
"fuzz": 300
|
214
|
+
},
|
215
|
+
"version": 3
|
216
|
+
},
|
217
|
+
"description": "App V3, Proof V4 (custom fuzz)",
|
218
|
+
"expect": "pass",
|
219
|
+
"proof": {
|
220
|
+
"version": 4
|
221
|
+
},
|
222
|
+
"spec_version": 4
|
223
|
+
},
|
224
|
+
{
|
225
|
+
"app": {
|
226
|
+
"config": {
|
227
|
+
"fuzz": 300
|
228
|
+
},
|
229
|
+
"version": 4
|
230
|
+
},
|
231
|
+
"description": "App V4, Proof V4 (custom fuzz)",
|
232
|
+
"expect": "pass",
|
233
|
+
"proof": {
|
234
|
+
"version": 4
|
235
|
+
},
|
236
|
+
"spec_version": 4
|
237
|
+
},
|
238
|
+
{
|
239
|
+
"app": {
|
240
|
+
"config": {
|
241
|
+
"fuzz": 300
|
242
|
+
},
|
243
|
+
"version": 1
|
244
|
+
},
|
245
|
+
"description": "App V1, Proof V2 old timestamp",
|
246
|
+
"expect": "fail",
|
247
|
+
"nonce": {
|
248
|
+
"value": "20060102T150405.333Z"
|
249
|
+
},
|
250
|
+
"proof": {
|
251
|
+
"version": 2
|
252
|
+
},
|
253
|
+
"spec_version": 4
|
254
|
+
},
|
255
|
+
{
|
256
|
+
"app": {
|
257
|
+
"version": 1
|
258
|
+
},
|
259
|
+
"description": "App V1, Proof V3 old timestamp",
|
260
|
+
"expect": "fail",
|
261
|
+
"nonce": {
|
262
|
+
"value": "20060102T150405.333Z"
|
263
|
+
},
|
264
|
+
"proof": {
|
265
|
+
"version": 3
|
266
|
+
},
|
267
|
+
"spec_version": 4
|
268
|
+
},
|
269
|
+
{
|
270
|
+
"app": {
|
271
|
+
"version": 1
|
272
|
+
},
|
273
|
+
"description": "App V1, Proof V4 old timestamp",
|
274
|
+
"expect": "fail",
|
275
|
+
"nonce": {
|
276
|
+
"value": "20060102T150405.333Z"
|
277
|
+
},
|
278
|
+
"proof": {
|
279
|
+
"version": 4
|
280
|
+
},
|
281
|
+
"spec_version": 4
|
282
|
+
},
|
283
|
+
{
|
284
|
+
"app": {
|
285
|
+
"version": 2
|
286
|
+
},
|
287
|
+
"description": "App V2, Proof V2 old timestamp",
|
288
|
+
"expect": "fail",
|
289
|
+
"nonce": {
|
290
|
+
"value": "20060102T150405.333Z"
|
291
|
+
},
|
292
|
+
"proof": {
|
293
|
+
"version": 2
|
294
|
+
},
|
295
|
+
"spec_version": 4
|
296
|
+
},
|
297
|
+
{
|
298
|
+
"app": {
|
299
|
+
"version": 2
|
300
|
+
},
|
301
|
+
"description": "App V2, Proof V3 old timestamp",
|
302
|
+
"expect": "fail",
|
303
|
+
"nonce": {
|
304
|
+
"value": "20060102T150405.333Z"
|
305
|
+
},
|
306
|
+
"proof": {
|
307
|
+
"version": 3
|
308
|
+
},
|
309
|
+
"spec_version": 4
|
310
|
+
},
|
311
|
+
{
|
312
|
+
"app": {
|
313
|
+
"version": 2
|
314
|
+
},
|
315
|
+
"description": "App V2, Proof V4 old timestamp",
|
316
|
+
"expect": "fail",
|
317
|
+
"nonce": {
|
318
|
+
"value": "20060102T150405.333Z"
|
319
|
+
},
|
320
|
+
"proof": {
|
321
|
+
"version": 4
|
322
|
+
},
|
323
|
+
"spec_version": 4
|
324
|
+
},
|
325
|
+
{
|
326
|
+
"app": {
|
327
|
+
"version": 3
|
328
|
+
},
|
329
|
+
"description": "App V3, Proof V3 old timestamp",
|
330
|
+
"expect": "fail",
|
331
|
+
"nonce": {
|
332
|
+
"value": "20060102T150405.333Z"
|
333
|
+
},
|
334
|
+
"proof": {
|
335
|
+
"version": 3
|
336
|
+
},
|
337
|
+
"spec_version": 4
|
338
|
+
},
|
339
|
+
{
|
340
|
+
"app": {
|
341
|
+
"version": 3
|
342
|
+
},
|
343
|
+
"description": "App V3, Proof V4 old timestamp",
|
344
|
+
"expect": "fail",
|
345
|
+
"nonce": {
|
346
|
+
"value": "20060102T150405.333Z"
|
347
|
+
},
|
348
|
+
"proof": {
|
349
|
+
"version": 4
|
350
|
+
},
|
351
|
+
"spec_version": 4
|
352
|
+
},
|
353
|
+
{
|
354
|
+
"app": {
|
355
|
+
"version": 4
|
356
|
+
},
|
357
|
+
"description": "App V4, Proof V4 old timestamp",
|
358
|
+
"expect": "fail",
|
359
|
+
"nonce": {
|
360
|
+
"value": "20060102T150405.333Z"
|
361
|
+
},
|
362
|
+
"proof": {
|
363
|
+
"version": 4
|
364
|
+
},
|
365
|
+
"spec_version": 4
|
366
|
+
},
|
367
|
+
{
|
368
|
+
"app": {
|
369
|
+
"version": 1
|
370
|
+
},
|
371
|
+
"description": "App V1, Proof V2 old timestamp (custom fuzz)",
|
372
|
+
"expect": "fail",
|
373
|
+
"nonce": {
|
374
|
+
"value": "20060102T150405.333Z"
|
375
|
+
},
|
376
|
+
"proof": {
|
377
|
+
"version": 2
|
378
|
+
},
|
379
|
+
"spec_version": 4
|
380
|
+
},
|
381
|
+
{
|
382
|
+
"app": {
|
383
|
+
"config": {
|
384
|
+
"fuzz": 300
|
385
|
+
},
|
386
|
+
"version": 1
|
387
|
+
},
|
388
|
+
"description": "App V1, Proof V3 old timestamp (custom fuzz)",
|
389
|
+
"expect": "fail",
|
390
|
+
"nonce": {
|
391
|
+
"value": "20060102T150405.333Z"
|
392
|
+
},
|
393
|
+
"proof": {
|
394
|
+
"version": 3
|
395
|
+
},
|
396
|
+
"spec_version": 4
|
397
|
+
},
|
398
|
+
{
|
399
|
+
"app": {
|
400
|
+
"config": {
|
401
|
+
"fuzz": 300
|
402
|
+
},
|
403
|
+
"version": 1
|
404
|
+
},
|
405
|
+
"description": "App V1, Proof V4 old timestamp (custom fuzz)",
|
406
|
+
"expect": "fail",
|
407
|
+
"nonce": {
|
408
|
+
"value": "20060102T150405.333Z"
|
409
|
+
},
|
410
|
+
"proof": {
|
411
|
+
"version": 4
|
412
|
+
},
|
413
|
+
"spec_version": 4
|
414
|
+
},
|
415
|
+
{
|
416
|
+
"app": {
|
417
|
+
"config": {
|
418
|
+
"fuzz": 300
|
419
|
+
},
|
420
|
+
"version": 2
|
421
|
+
},
|
422
|
+
"description": "App V2, Proof V2 old timestamp (custom fuzz)",
|
423
|
+
"expect": "fail",
|
424
|
+
"nonce": {
|
425
|
+
"value": "20060102T150405.333Z"
|
426
|
+
},
|
427
|
+
"proof": {
|
428
|
+
"version": 2
|
429
|
+
},
|
430
|
+
"spec_version": 4
|
431
|
+
},
|
432
|
+
{
|
433
|
+
"app": {
|
434
|
+
"config": {
|
435
|
+
"fuzz": 300
|
436
|
+
},
|
437
|
+
"version": 2
|
438
|
+
},
|
439
|
+
"description": "App V2, Proof V3 old timestamp (custom fuzz)",
|
440
|
+
"expect": "fail",
|
441
|
+
"nonce": {
|
442
|
+
"value": "20060102T150405.333Z"
|
443
|
+
},
|
444
|
+
"proof": {
|
445
|
+
"version": 3
|
446
|
+
},
|
447
|
+
"spec_version": 4
|
448
|
+
},
|
449
|
+
{
|
450
|
+
"app": {
|
451
|
+
"version": 2
|
452
|
+
},
|
453
|
+
"description": "App V2, Proof V4 old timestamp (custom fuzz)",
|
454
|
+
"expect": "fail",
|
455
|
+
"nonce": {
|
456
|
+
"value": "20060102T150405.333Z"
|
457
|
+
},
|
458
|
+
"proof": {
|
459
|
+
"version": 4
|
460
|
+
},
|
461
|
+
"spec_version": 4
|
462
|
+
},
|
463
|
+
{
|
464
|
+
"app": {
|
465
|
+
"config": {
|
466
|
+
"fuzz": 300
|
467
|
+
},
|
468
|
+
"version": 3
|
469
|
+
},
|
470
|
+
"description": "App V3, Proof V3 old timestamp (custom fuzz)",
|
471
|
+
"expect": "fail",
|
472
|
+
"nonce": {
|
473
|
+
"value": "20060102T150405.333Z"
|
474
|
+
},
|
475
|
+
"proof": {
|
476
|
+
"version": 3
|
477
|
+
},
|
478
|
+
"spec_version": 4
|
479
|
+
},
|
480
|
+
{
|
481
|
+
"app": {
|
482
|
+
"config": {
|
483
|
+
"fuzz": 300
|
484
|
+
},
|
485
|
+
"version": 3
|
486
|
+
},
|
487
|
+
"description": "App V3, Proof V4 old timestamp (custom fuzz)",
|
488
|
+
"expect": "fail",
|
489
|
+
"nonce": {
|
490
|
+
"value": "20060102T150405.333Z"
|
491
|
+
},
|
492
|
+
"proof": {
|
493
|
+
"version": 4
|
494
|
+
},
|
495
|
+
"spec_version": 4
|
496
|
+
},
|
497
|
+
{
|
498
|
+
"app": {
|
499
|
+
"config": {
|
500
|
+
"fuzz": 300
|
501
|
+
},
|
502
|
+
"version": 4
|
503
|
+
},
|
504
|
+
"description": "App V4, Proof V4 old timestamp (custom fuzz)",
|
505
|
+
"expect": "fail",
|
506
|
+
"nonce": {
|
507
|
+
"value": "20060102T150405.333Z"
|
508
|
+
},
|
509
|
+
"proof": {
|
510
|
+
"version": 4
|
511
|
+
},
|
512
|
+
"spec_version": 4
|
513
|
+
}
|
514
|
+
]
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
class AppIdentity::Suite::Runner # :nodoc:
|
6
|
+
class << self
|
7
|
+
private :new
|
8
|
+
|
9
|
+
def run(paths, options)
|
10
|
+
new(paths, options).run
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(paths, options)
|
15
|
+
@paths = paths
|
16
|
+
@options = options
|
17
|
+
@suites = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
@suites = [*piped_suite, *load_suites(paths)]
|
22
|
+
summarize_and_annotate
|
23
|
+
suites.reduce(true) { |result, suite| run_suite(suite) && result }
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def load_suites(names)
|
29
|
+
names.flat_map { |name| load_suite(name) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_suite(name)
|
33
|
+
if File.file?(name)
|
34
|
+
[parse_suite(File.read(name))]
|
35
|
+
elsif File.directory?(name)
|
36
|
+
load_suites(Dir[File.join(name, "*.json")])
|
37
|
+
else
|
38
|
+
raise "Path #{name} is not a file or a directory."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def piped_suite
|
43
|
+
data = options[:stdin] ? $stdin.read.strip : nil
|
44
|
+
data ? [parse_suite(data)] : []
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_suite(data)
|
48
|
+
JSON.parse(data)
|
49
|
+
end
|
50
|
+
|
51
|
+
def summarize_and_annotate
|
52
|
+
index = 0
|
53
|
+
total = 0
|
54
|
+
|
55
|
+
suites.each do |suite|
|
56
|
+
tests = suite["tests"]
|
57
|
+
total += tests.length
|
58
|
+
|
59
|
+
tests.each do |test|
|
60
|
+
index += 1
|
61
|
+
test["index"] = index
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
puts <<~TAP
|
66
|
+
TAP Version 14
|
67
|
+
1..#{total}
|
68
|
+
TAP
|
69
|
+
|
70
|
+
puts "# No suites provided." if total.zero?
|
71
|
+
end
|
72
|
+
|
73
|
+
def run_suite(suite)
|
74
|
+
puts "# #{AppIdentity::NAME} #{AppIdentity::VERSION} " \
|
75
|
+
"(spec #{AppIdentity::SPEC_VERSION}) testing " \
|
76
|
+
"#{suite["name"]} #{suite["version"]} (spec #{suite["spec_version"]})"
|
77
|
+
suite["tests"].reduce(true) { |result, test| run_test(test) && result }
|
78
|
+
end
|
79
|
+
|
80
|
+
def run_test(test)
|
81
|
+
if AppIdentity::INFO[:spec_version] < test["spec_version"]
|
82
|
+
compare = [AppIdentity::INFO[:spec_version], "<", test["spec_version"]].join(" ")
|
83
|
+
puts "ok #{test["index"]} - #{test["description"]} # SKIP unsupported spec version #{compare}"
|
84
|
+
return true
|
85
|
+
end
|
86
|
+
|
87
|
+
result, message = check_result(AppIdentity::Internal.verify_proof!(test["proof"], test["app"]), test)
|
88
|
+
|
89
|
+
puts message
|
90
|
+
result
|
91
|
+
rescue => ex
|
92
|
+
result, message = check_result(ex, test)
|
93
|
+
puts message
|
94
|
+
result
|
95
|
+
end
|
96
|
+
|
97
|
+
def check_result(result, test)
|
98
|
+
if test["expect"] == "pass"
|
99
|
+
if result.is_a?(AppIdentity::App)
|
100
|
+
ok(test)
|
101
|
+
else
|
102
|
+
not_ok(test, result || "proof verification failed")
|
103
|
+
end
|
104
|
+
elsif result.is_a?(AppIdentity::App)
|
105
|
+
not_ok(test, "proof should have failed #{app.inspect}")
|
106
|
+
else
|
107
|
+
ok(test)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def ok(test)
|
112
|
+
[true, "ok #{test["index"]} - #{test["description"]}"]
|
113
|
+
end
|
114
|
+
|
115
|
+
def not_ok(test, error)
|
116
|
+
message = "not ok #{test["index"]} - #{test["description"]}"
|
117
|
+
|
118
|
+
if !test["required"] && !options[:strict]
|
119
|
+
message << " # TODO optional failing test"
|
120
|
+
end
|
121
|
+
|
122
|
+
if options[:diagnostic] && error
|
123
|
+
error_message = error.is_a?(Exception) ? error.message : error
|
124
|
+
|
125
|
+
message += "\n ---\n message: #{error_message}\n ..."
|
126
|
+
end
|
127
|
+
|
128
|
+
[false, message]
|
129
|
+
end
|
130
|
+
|
131
|
+
attr_reader :paths, :options, :suites
|
132
|
+
end
|