json-spec 0.1.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.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +960 -0
  7. data/Rakefile +10 -0
  8. data/api_documentation.md +611 -0
  9. data/cachivache/.gitignore +1 -0
  10. data/cachivache/Gemfile +4 -0
  11. data/cachivache/README.md +247 -0
  12. data/cachivache/Rakefile +19 -0
  13. data/cachivache/Vagrantfile +70 -0
  14. data/cachivache/cachivache.rb +59 -0
  15. data/cachivache/lib/let-behaviour.rb +27 -0
  16. data/cachivache/lib/rake-helper.rb +131 -0
  17. data/cachivache/lib/sh-file-context.rb +39 -0
  18. data/cachivache/lib/sh-if-context.rb +31 -0
  19. data/cachivache/stuff/.gitkeep +0 -0
  20. data/cachivache/stuff/ruby-json-spec.rb +22 -0
  21. data/examples/example-1-simple.rb +66 -0
  22. data/examples/example-2-default-expectations.rb +63 -0
  23. data/examples/example-3-each-field.rb +104 -0
  24. data/examples/example-4-to-be-as-defined-in.rb +117 -0
  25. data/examples/example-5-custom-expectations.rb +153 -0
  26. data/examples/example-6-custom-messages.rb +36 -0
  27. data/examples/example-7-full-example.rb +231 -0
  28. data/examples/fixtures.rb +77 -0
  29. data/examples/validation-printer.rb +47 -0
  30. data/json-spec.gemspec +29 -0
  31. data/lib/cabeza-de-termo/json-spec/errors/error.rb +6 -0
  32. data/lib/cabeza-de-termo/json-spec/errors/expectation-not-found-error.rb +8 -0
  33. data/lib/cabeza-de-termo/json-spec/errors/modifier-not-found-error.rb +8 -0
  34. data/lib/cabeza-de-termo/json-spec/errors/unkown-json-type-error.rb +8 -0
  35. data/lib/cabeza-de-termo/json-spec/errors/validation-error.rb +8 -0
  36. data/lib/cabeza-de-termo/json-spec/expectations-library/default-expectations/default-expectation-builder.rb +29 -0
  37. data/lib/cabeza-de-termo/json-spec/expectations-library/default-expectations/default-expectations-mapping.rb +54 -0
  38. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/block-expectation-definition.rb +16 -0
  39. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/class-expectation-definition.rb +15 -0
  40. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expectation-definition.rb +19 -0
  41. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expectations-definition-builder.rb +136 -0
  42. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expecting-all-of-expectation-definition.rb +23 -0
  43. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expecting-any-of-expectation-definition.rb +23 -0
  44. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expecting-expectation-definition.rb +17 -0
  45. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/negating-expectation-definition.rb +16 -0
  46. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-library-definition-builder.rb +35 -0
  47. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/class-modifier-definition.rb +15 -0
  48. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/composing-modifiers-definition.rb +28 -0
  49. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/modifier-definition.rb +13 -0
  50. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/modifiers-definition-builder.rb +73 -0
  51. data/lib/cabeza-de-termo/json-spec/expectations-library/expectations-library.rb +150 -0
  52. data/lib/cabeza-de-termo/json-spec/expectations-library/initializers/default-library-initializer.rb +265 -0
  53. data/lib/cabeza-de-termo/json-spec/expectations-library/initializers/library-initializer.rb +9 -0
  54. data/lib/cabeza-de-termo/json-spec/expectations-library/messages/expectation-messages-mapping.rb +27 -0
  55. data/lib/cabeza-de-termo/json-spec/expectations/abstract-expectation.rb +39 -0
  56. data/lib/cabeza-de-termo/json-spec/expectations/all-expectations-composite.rb +33 -0
  57. data/lib/cabeza-de-termo/json-spec/expectations/any-expectation-composite.rb +33 -0
  58. data/lib/cabeza-de-termo/json-spec/expectations/block-expectation.rb +28 -0
  59. data/lib/cabeza-de-termo/json-spec/expectations/expectation.rb +51 -0
  60. data/lib/cabeza-de-termo/json-spec/expectations/is-email-expectation.rb +16 -0
  61. data/lib/cabeza-de-termo/json-spec/expectations/is-scalar-expectation.rb +17 -0
  62. data/lib/cabeza-de-termo/json-spec/expectations/is-url-expectation.rb +21 -0
  63. data/lib/cabeza-de-termo/json-spec/expectations/negated-expectation.rb +31 -0
  64. data/lib/cabeza-de-termo/json-spec/expectations/runner/abstract-expectations-runner.rb +27 -0
  65. data/lib/cabeza-de-termo/json-spec/expectations/runner/can-be-absent-expectations-runner.rb +50 -0
  66. data/lib/cabeza-de-termo/json-spec/expectations/runner/can-be-null-expectations-runner.rb +48 -0
  67. data/lib/cabeza-de-termo/json-spec/expectations/runner/expectations-runner.rb +43 -0
  68. data/lib/cabeza-de-termo/json-spec/expressions/json-any-of.rb +62 -0
  69. data/lib/cabeza-de-termo/json-spec/expressions/json-anything.rb +16 -0
  70. data/lib/cabeza-de-termo/json-spec/expressions/json-each-field.rb +58 -0
  71. data/lib/cabeza-de-termo/json-spec/expressions/json-each.rb +58 -0
  72. data/lib/cabeza-de-termo/json-spec/expressions/json-expression.rb +314 -0
  73. data/lib/cabeza-de-termo/json-spec/expressions/json-field-name.rb +16 -0
  74. data/lib/cabeza-de-termo/json-spec/expressions/json-field.rb +76 -0
  75. data/lib/cabeza-de-termo/json-spec/expressions/json-list.rb +40 -0
  76. data/lib/cabeza-de-termo/json-spec/expressions/json-object.rb +82 -0
  77. data/lib/cabeza-de-termo/json-spec/expressions/json-scalar.rb +20 -0
  78. data/lib/cabeza-de-termo/json-spec/expressions/json-spec.rb +174 -0
  79. data/lib/cabeza-de-termo/json-spec/instantiators/abstract-instantiator.rb +9 -0
  80. data/lib/cabeza-de-termo/json-spec/instantiators/all-expectations-composite-instantiator.rb +12 -0
  81. data/lib/cabeza-de-termo/json-spec/instantiators/any-expectation-composite-instantiator.rb +12 -0
  82. data/lib/cabeza-de-termo/json-spec/instantiators/block-expectation-instantiator.rb +16 -0
  83. data/lib/cabeza-de-termo/json-spec/instantiators/composite-instantiator.rb +45 -0
  84. data/lib/cabeza-de-termo/json-spec/instantiators/modifier-composite-instantiator.rb +12 -0
  85. data/lib/cabeza-de-termo/json-spec/instantiators/negated-expectation-instantiator.rb +20 -0
  86. data/lib/cabeza-de-termo/json-spec/instantiators/patial-application-instantiator.rb +26 -0
  87. data/lib/cabeza-de-termo/json-spec/json-spec.rb +2 -0
  88. data/lib/cabeza-de-termo/json-spec/message-formatters/block-message-formatter.rb +15 -0
  89. data/lib/cabeza-de-termo/json-spec/message-formatters/erb-message-formatter.rb +60 -0
  90. data/lib/cabeza-de-termo/json-spec/message-formatters/message-formatter.rb +9 -0
  91. data/lib/cabeza-de-termo/json-spec/metaprogramming/message-send.rb +37 -0
  92. data/lib/cabeza-de-termo/json-spec/metaprogramming/message.rb +37 -0
  93. data/lib/cabeza-de-termo/json-spec/metaprogramming/object-method.rb +14 -0
  94. data/lib/cabeza-de-termo/json-spec/modifiers/can-be-absent-modifier.rb +13 -0
  95. data/lib/cabeza-de-termo/json-spec/modifiers/can-be-null-modifier.rb +13 -0
  96. data/lib/cabeza-de-termo/json-spec/modifiers/expression-modifier.rb +9 -0
  97. data/lib/cabeza-de-termo/json-spec/modifiers/modifier-composite.rb +27 -0
  98. data/lib/cabeza-de-termo/json-spec/signals/signal.rb +6 -0
  99. data/lib/cabeza-de-termo/json-spec/signals/skip-branch-signal.rb +8 -0
  100. data/lib/cabeza-de-termo/json-spec/utilities/bind.rb +20 -0
  101. data/lib/cabeza-de-termo/json-spec/utilities/range.rb +70 -0
  102. data/lib/cabeza-de-termo/json-spec/value-holders/accessors-chain.rb +27 -0
  103. data/lib/cabeza-de-termo/json-spec/value-holders/missing-value.rb +21 -0
  104. data/lib/cabeza-de-termo/json-spec/value-holders/value-holder.rb +135 -0
  105. data/lib/cabeza-de-termo/json-spec/version.rb +5 -0
  106. data/lib/cabeza-de-termo/json-spec/walkers/expression-walker.rb +66 -0
  107. data/lib/cabeza-de-termo/json-spec/walkers/json-expectations-runner.rb +214 -0
  108. data/lib/cabeza-de-termo/json-spec/walkers/json-expression-explainer.rb +183 -0
  109. data/lib/cabeza-de-termo/json-spec/walkers/reporter/expectation-report.rb +63 -0
  110. data/lib/cabeza-de-termo/json-spec/walkers/reporter/json-expectations-reporter.rb +111 -0
  111. data/lib/cabeza-de-termo/json-spec/walkers/validator/json-validator-error.rb +29 -0
  112. data/lib/cabeza-de-termo/json-spec/walkers/validator/json-validator.rb +133 -0
  113. data/lib/cabeza-de-termo/json-spec/walkers/value-holders-stack-behaviour.rb +57 -0
  114. metadata +242 -0
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "spec"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['spec/**/*-spec.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,611 @@
1
+ # API
2
+
3
+ ## Expressions on the root json expression
4
+
5
+ ### expect_an(:object)
6
+
7
+ Expects a root object.
8
+
9
+ ```ruby
10
+ expect_an(:object) do
11
+ ...
12
+ end
13
+ ```
14
+
15
+ Example of expected json:
16
+
17
+ ```json
18
+ {}
19
+ ```
20
+
21
+ ### expect_a(:list)
22
+
23
+ Expects a root list.
24
+
25
+ ```ruby
26
+ expect_a(:list) do
27
+ ...
28
+ end
29
+ ```
30
+
31
+ Example of expected json:
32
+
33
+ ```json
34
+ []
35
+ ```
36
+
37
+ ### expect(:any_of)
38
+
39
+ Expects one among many possible different root expressions.
40
+
41
+ ```ruby
42
+ expect(:any_of)
43
+ ...
44
+ or_also()
45
+ ...
46
+ or_also()
47
+ ...
48
+ end
49
+ ```
50
+
51
+ Example of expected json:
52
+
53
+ ```json
54
+ {}
55
+ or
56
+ []
57
+ ```
58
+
59
+ ## Expressions on an json object
60
+
61
+ ### expect(field_name) .to_be_a(:scalar)
62
+
63
+ Expects a scalar on a field named field_name
64
+
65
+ ```ruby
66
+ expect('id') .to_be_a(:scalar)
67
+ ```
68
+
69
+ Example of expected json:
70
+
71
+ ```json
72
+ {
73
+ "id": 123
74
+ }
75
+ ```
76
+
77
+ ### expect(field_name) .to_be_an(:object)
78
+
79
+ Expects an object on a field named field_name
80
+
81
+ ```ruby
82
+ expect('user') .to_be_an(:object) do
83
+ end
84
+ ```
85
+
86
+ Example of expected json:
87
+
88
+ ```json
89
+ {
90
+ "user": {
91
+ ...
92
+ }
93
+ }
94
+ ```
95
+
96
+ ### expect(field_name) .to_be_a(:list)
97
+
98
+ Expects a list on a field named field_name
99
+
100
+ ```ruby
101
+ expect(field_name) .to_be_a(:list) do
102
+ each do
103
+ ...
104
+ end
105
+ end
106
+ ```
107
+
108
+ Example of expected json:
109
+
110
+ ```json
111
+ {
112
+ "users": [
113
+ ...
114
+ ]
115
+ }
116
+ ```
117
+
118
+ ### expect(field_name) .to_be(:any_of)
119
+
120
+ Expects one among many possible different expressions on a field named field_name
121
+
122
+ ```ruby
123
+ expect('object_or_list') .to_be(:any_of) do
124
+ expect_an(:object) do
125
+ ...
126
+ end
127
+ or_also
128
+ expect_a(:list) do
129
+ ...
130
+ end
131
+ end
132
+ ```
133
+
134
+ Example of expected json:
135
+
136
+ ```json
137
+ {
138
+ "object_or_list": {
139
+ ...
140
+ }
141
+ or
142
+ "object_or_list": [
143
+ ...
144
+ ]
145
+ }
146
+ ```
147
+
148
+ ### each_field
149
+
150
+ Expects a name and an expression on every field of the object
151
+
152
+ ```ruby
153
+ each_field
154
+ expect_name
155
+
156
+ # one of the following expressions
157
+
158
+ expect(:anything)
159
+ # or
160
+ expect_a(:scalar)
161
+ # or
162
+ expect_an(:object) do
163
+ ...
164
+ end
165
+ # or
166
+ expect_a(:list) do
167
+ ...
168
+ end
169
+ # or
170
+ expect(:any_of) do
171
+ ...
172
+ or_also
173
+ ...
174
+ end
175
+ end
176
+ ```
177
+
178
+ Example of expected json:
179
+
180
+ ```json
181
+ {
182
+ "id": 123
183
+ or
184
+ "id": []
185
+ or
186
+ "name": 123
187
+ or
188
+ "name": []
189
+ etc
190
+ }
191
+ ```
192
+
193
+ ### expect(field_name) .to_be(:anything)
194
+
195
+ Expects anything scalar on a field named field_name
196
+
197
+ ```ruby
198
+ expect('name') .to_be(:anything)
199
+ ```
200
+
201
+ Example of expected json:
202
+
203
+ ```json
204
+ {
205
+ "name": "cabeza de termo"
206
+ }
207
+ ```
208
+
209
+ ## Expressions on an json list
210
+
211
+ ### expect_a(:scalar)
212
+
213
+ Expects a scalar on each item of a list
214
+
215
+ ```ruby
216
+ json_list do
217
+ each do
218
+ expect_a(:scalar)
219
+ end
220
+ end
221
+ ```
222
+
223
+ Example of expected json:
224
+
225
+ ```json
226
+ [
227
+ 123
228
+ ]
229
+ ```
230
+
231
+ ### expect_an(:object)
232
+
233
+ Expects an object on each item of a list
234
+
235
+ ```ruby
236
+ json_list do
237
+ each do
238
+ expect_an(:object) do
239
+ ...
240
+ end
241
+ end
242
+ end
243
+ ```
244
+
245
+ Example of expected json:
246
+
247
+ ```json
248
+ [
249
+ {
250
+ ...
251
+ }
252
+ ]
253
+ ```
254
+
255
+ ### expect_a(:list)
256
+
257
+ Expects a list on each item of a list
258
+
259
+ ```ruby
260
+ json_list do
261
+ each do
262
+ expect_a(:list) do
263
+ ...
264
+ end
265
+ end
266
+ end
267
+ ```
268
+
269
+ Example of expected json:
270
+
271
+ ```json
272
+ [
273
+ [
274
+ ...
275
+ ]
276
+ ]
277
+ ```
278
+
279
+ ### expect(:any_of)
280
+
281
+ Expects one among many possible different expressions on each item of a list
282
+
283
+ ```ruby
284
+ json_list do
285
+ each do
286
+ expect(:any_of)
287
+ expect_an(:object) do
288
+ ...
289
+ end
290
+ or_also
291
+ expect_a(:list)
292
+ ...
293
+ end
294
+ end
295
+ end
296
+ end
297
+ ```
298
+
299
+ Example of expected json:
300
+
301
+ ```json
302
+ [
303
+ {
304
+ ...
305
+ }
306
+ or
307
+ [
308
+ ...
309
+ ]
310
+ ]
311
+ ```
312
+
313
+ ## Library expectations
314
+
315
+ ### .to_exist
316
+
317
+ Expects an expression to be present.
318
+
319
+ ```ruby
320
+ expect(...) .to_exist
321
+ ```
322
+
323
+ ### .to_be_absent
324
+
325
+ Expects an expression not to be present.
326
+
327
+ ```ruby
328
+ expect(...) .to_be_absent
329
+ ```
330
+
331
+ ### .to_be_boolean
332
+
333
+ Expects a value to be a boolean.
334
+
335
+ ```ruby
336
+ expect(...) .to_be_boolean
337
+ ```
338
+
339
+ ### .to_be_float
340
+
341
+ Expects a value to be a float.
342
+
343
+ ```ruby
344
+ expect(...) .to_be_float
345
+ ```
346
+
347
+ ### .to_be_integer
348
+
349
+ Expects a value to be an integer.
350
+
351
+ ```ruby
352
+ expect(...) .to_be_integer
353
+ ```
354
+
355
+ ### .to_be_list
356
+
357
+ Expects a value to be a list.
358
+
359
+ ```ruby
360
+ expect(...) .to_be_list
361
+ ```
362
+
363
+ ### .to_be_number
364
+
365
+ Expects a value to be an integer or a double.
366
+
367
+ ```ruby
368
+ expect(...) .to_be_number
369
+ ```
370
+
371
+ ### .to_be_scalar
372
+
373
+ Expects a value to be a number, string, boolean or null.
374
+
375
+ ```ruby
376
+ expect(...) .to_be_scalar
377
+ ```
378
+
379
+ ### .to_be_object
380
+
381
+ Expects a value to be an object.
382
+
383
+ ```ruby
384
+ expect(...) .to_be_object
385
+ ```
386
+
387
+ ### .to_be_string
388
+
389
+ Expects a value to be a string.
390
+
391
+ ```ruby
392
+ expect(...) .to_be_string
393
+ ```
394
+
395
+ ### .to_be_null
396
+
397
+ Expects a value to be null.
398
+
399
+ ```ruby
400
+ expect(...) .to_be_null
401
+ ```
402
+
403
+ ### .not_null
404
+
405
+ Expects a value not to be null.
406
+
407
+ ```ruby
408
+ expect(...) .not_null
409
+ ```
410
+
411
+ ### .to_be_defined
412
+
413
+ Expects a field to be present and be not null.
414
+
415
+ ```ruby
416
+ expect(...) .to_be_defined
417
+ ```
418
+
419
+ ### .not_defined
420
+
421
+ Expects a value to be null or to be absent.
422
+
423
+ ```ruby
424
+ expect(...) .not_defined
425
+ ```
426
+
427
+ ### .to_be_empty
428
+
429
+ - If the value is an object, expects the object to have no fields
430
+ - If the value is a list, expects the list to have no items
431
+ - If the value is a string, expects the string to be == ''
432
+ - For any other type, raises an error
433
+
434
+ ```ruby
435
+ expect(...) .to_be_empty
436
+ ```
437
+
438
+ ### .not_empty
439
+
440
+ - If the value is an object, expects the object to have at least one field
441
+ - If the value is a list, expects the list to have at least one item
442
+ - If the value is a string, expects the string to have at least one character
443
+ - For any other type, raises an error
444
+
445
+ ```ruby
446
+ expect(...) .not_empty
447
+ ```
448
+
449
+ ### .to_be_blank
450
+
451
+ Expects a value to be blank. Blank means having no printable characters, event if its not empty.
452
+
453
+ ```ruby
454
+ expect(...) .to_be_blank
455
+ ```
456
+
457
+ ### .not_blank
458
+
459
+ Expects a value not to be blank. Not blank means having at least one printable character.
460
+
461
+ ```ruby
462
+ expect(...) .not_blank
463
+ ```
464
+
465
+ ### .to_be_equal_to(expected_value)
466
+
467
+ Expects a value to be equal to the expected_value.
468
+
469
+ ```ruby
470
+ expect(...) ..to_be_equal_to(42)
471
+ ```
472
+
473
+ ### .not_equal_to(expected_value)
474
+
475
+ Expects a value not to be equal to the expected_value.
476
+
477
+ ```ruby
478
+ expect(...) .not_equal_to(42)
479
+ ```
480
+
481
+ ### .to_match(pattern)
482
+
483
+ Expects a value to match the regular expression pattern.
484
+
485
+ ```ruby
486
+ expect(...) .to_match(/[\d]+^/)
487
+ ```
488
+
489
+ ### .not_to_match(pattern)
490
+
491
+ Expects a value not to match the regular expression pattern.
492
+
493
+ ```ruby
494
+ expect(...) .not_to_match(/[\d]+^/)
495
+ ```
496
+
497
+ ### .to_be_string_as_integer
498
+
499
+ Expects a value to be an integer string.
500
+
501
+ ```ruby
502
+ expect(...) .to_be_string_as_integer
503
+ ```
504
+
505
+ ### .to_be_string_as_double
506
+
507
+ Expects a value to be a double string.
508
+
509
+ ```ruby
510
+ expect(...) .to_be_string_as_double
511
+ ```
512
+
513
+ ### .to_be_in
514
+
515
+ Expects a value to be equal to any value of an array of values.
516
+
517
+ ```ruby
518
+ expect(...) .to_be_in([1, 2, 3])
519
+ ```
520
+
521
+ ### .not_in
522
+
523
+ Expects a value to be different to all the values of an array of values.
524
+
525
+ ```ruby
526
+ expect(...) .not_in([1, 2, 3])
527
+ ```
528
+
529
+ ### .to_be_email
530
+
531
+ Expects a value to be a valid email string.
532
+
533
+ ```ruby
534
+ expect(...) .to_be_email
535
+ ```
536
+
537
+ ### .to_be_url
538
+
539
+ Expects a value to be a valid url string.
540
+
541
+ ```ruby
542
+ expect(...) .to_be_url
543
+ ```
544
+
545
+ ### .to_be_in_range
546
+
547
+ Expects a value to be in a range.
548
+
549
+ ```ruby
550
+ expect(...) .to_be_in_range( CabezaDeTermo::JsonSpec::Range.newFrom('(', 0, 10, ']') )
551
+ ```
552
+
553
+ ### .not_in_range
554
+
555
+ Expects a value not to be in a range.
556
+
557
+ ```ruby
558
+ expect(...) .not_in_range( CabezaDeTermo::JsonSpec::Range.newFrom('(', 0, 10, ']') )
559
+ ```
560
+
561
+ ### .to_be_between
562
+
563
+ Expects a value to be between 2 values, including them.
564
+
565
+ ```ruby
566
+ expect(...) .to_be_between(0, 10)
567
+ ```
568
+
569
+ ### .not_between
570
+
571
+ Expects a value not to be between 2 values, including them.
572
+
573
+ ```ruby
574
+ expect(...) .not_between(0, 10)
575
+ ```
576
+
577
+ ### .can_be_absent
578
+
579
+ Allow a field to be absent without failing the expectation.
580
+
581
+ If the field is absent, stop running other expectations for that field.
582
+
583
+ If present, run the rest of the expectations on that value.
584
+
585
+ ```ruby
586
+ expect(...) .can_be_absent .to_be_equal_to(42)
587
+ ```
588
+
589
+ ### .can_be_null
590
+
591
+ Allow a value to be null without failing the expectation.
592
+
593
+ If the value is null, stop running other expectations for that value.
594
+
595
+ If present, run the rest of the expectations on that value.
596
+
597
+ ```ruby
598
+ expect(...) .can_be_null .to_be_equal_to(42)
599
+ ```
600
+
601
+ ### .can_be_undefined
602
+
603
+ Allow a field to be absent or its value to be null without failing the expectation.
604
+
605
+ If the field is absent or its value is null, stop running other expectations for that value.
606
+
607
+ If the field is present and its value is not null, run the rest of the expectations on that value.
608
+
609
+ ```ruby
610
+ expect(...) .can_be_undefined .to_be_equal_to(42)
611
+ ```