xeme 1.2 → 2.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 (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +306 -225
  3. data/lib/xeme.rb +694 -627
  4. metadata +25 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cdf9cdb30bbab1fe3155496c778a01c83fb35c011bb9d00c63525fffa1c5cec8
4
- data.tar.gz: aa5b17da3d91e1ab8940aa84ff38dd4fcbe5d274acebcb7483c4bf9221ed6dca
3
+ metadata.gz: ae47399bb72561b8d7d6efedeb37e43840269d5fb6ab686bdfc31499ee3595e8
4
+ data.tar.gz: 83c15744b30011cfd1cac0ee53771ee790f34a15b5983af1763b65000109bc64
5
5
  SHA512:
6
- metadata.gz: 98eab45cddd377c4a3c81d1de8c800e169b360fbe0451402256e57c18e412c971f6eef059795ad54134297228757728561e730a33271e932574d198028976f99
7
- data.tar.gz: 1200e1c8b64b5233c102e83414499fdc39db85df7d5cf071caee830a5e218a29c94f590b6d44b8ed2266d8c6fb5b34ee9112d2d7eeb97201a9d49fc57225bd0b
6
+ metadata.gz: 3486a1a926faea61cb880dba644cf8619c8615bdf22af79e37ab5a3777907eb0c20f81532f215d42be8cfb7dbaf0773f80cbf6b5f9f42c50a6d4bc781a1f26c8
7
+ data.tar.gz: 21e10be699393ea20c8e6bcd488f66d9f05647aa6f8c6c51a0b8ea6072ecea4f51a4920061fbd9b2f53d98766fd103048937dcb1386952486b8e505d3a21fec2
data/README.md CHANGED
@@ -19,8 +19,8 @@ A xeme can be as simple as an empty hash:
19
19
  ```
20
20
 
21
21
  That structure indicates no errors, and, in fact, no details at all. However, it
22
- also does not explicitly indicate success, so that xeme would be considered to
23
- have failed.
22
+ also does not explicitly indicate success. In the absence of a defined value of
23
+ true or false, the result should be considered either undetermined or failed.
24
24
 
25
25
  To indicate a successful operation, a xeme must have an explicit `success`
26
26
  element:
@@ -35,69 +35,235 @@ A xeme can be marked as explicitly failed:
35
35
  {"success":false}
36
36
  ```
37
37
 
38
- If a xeme does not have an explicit `success` element, or it is set to `nil`, it
39
- should be considered to have failed. However, depending on how you process the
40
- xeme, `nil` could be considered as having not finished the test. In that case,
41
- consider using [promises](#promises).
38
+ Any truthy value for `success` is considered to indicate success. So, for
39
+ example, the following xeme should be considered to indicate success.
42
40
 
43
- ### Messages
41
+ ```json
42
+ {"success":{}}
43
+ ```
44
44
 
45
- A message is an error, a warning, a note, or a promise. Each type of message has
46
- an array. For example, this xeme has two errors:
45
+ A xeme may contain other arbitrary information. This is useful if you need more
46
+ information than just a success or failure.
47
47
 
48
48
  ```json
49
- { "errors":[{"id":"http-fault"}, {"id":"transaction-error"}] }
49
+ {"success":true, "tags":["a", "b"]}
50
50
  ```
51
51
 
52
- A message does not have to have any particular structure, but best practice is
53
- to give each message an identifier (`id`).
52
+ ### Metainformation
54
53
 
55
- If there are any errors then that indicates a failure, regardless of the value
56
- of `success`. Any implementation of Xeme should have a method for resolving
57
- conflicts between `success` and `errors`, always giving priority to the presence
58
- of errors over the value of `success`.
54
+ A xeme may contain a `meta` element. The `meta` element can contain a timestamp,
55
+ UUID, description, or other meta information.
59
56
 
60
- If a xeme has any promises then that indicates not success, though not
61
- necessarily explicit failure. If a xeme is marked as successful, but there are
62
- promises, then `success` should be considered nil.
57
+ ```json
58
+ {
59
+ "success":true,
60
+ "meta": {
61
+ "timestamp": "2023-06-21T08:57:56+00:00",
62
+ "uuid": "e11b668c-0823-4b70-aa28-5ac83757a37c",
63
+ "description": "directory tests"
64
+ }
65
+ }
66
+ ```
63
67
 
64
- Warnings indicate problems that don't outright cause a failure. Notes are
65
- messages that don't indicate a problem of any kind.
68
+ `meta` can contain any arbitrary information you want, but several elements, if
69
+ present, should follow some standards.
66
70
 
67
- ### Metainformation
71
+ | key | description |
72
+ |-------------|----------------------------------------------|
73
+ | id | A string, typically without spaces. |
74
+ | description | A short description of the xeme as a string. |
75
+ | timestamp | Timestamp in a standard ISO 8601 format. |
76
+ | UUID | A UUID. |
77
+
78
+ ### Nested xemes
79
+
80
+ A xeme represents the results of a single process. However, a xeme can also
81
+ contain nested xemes which provide information about sub-processes. In this
82
+ sense, a xeme can be considered as the final results of the xemes nested within
83
+ it.
68
84
 
69
- Sometimes it's useful to store metainformation the xeme. For example, log files
70
- are more discoverable if each xeme has a unique id and timestamp. Generally a
71
- xeme will have at least to elements, `uuid` and `timestamp`:
85
+ Child xemes are contained in the `nested` array.
72
86
 
73
87
  ```json
74
88
  {
75
- "meta":{
76
- "uuid":"dae1cf26-e8fa-43fa-bedc-88fea10255f4",
77
- "timestamp":"2023-05-25 03:46:19 -0400"
78
- }
89
+ "success":true,
90
+ "meta": {"id":"directory"},
91
+ "nested":[
92
+ {"success":true, "meta": {"id":"database-connection"}},
93
+ {"success":true, "meta": {"id":"update"}}
94
+ ]
79
95
  }
80
96
  ```
81
97
 
82
- ### Nested xemes
98
+ Nested xemes can themselves have nested xemes, forming a tree of process
99
+ results.
100
+
101
+ ```json
102
+ {
103
+ "success":true,
104
+ "meta": {"id":"database"},
105
+ "nested": [
106
+ {
107
+ "success":true,
108
+ "meta": {"id":"database-connection"},
109
+ "nested": [
110
+ {"success":true, "meta":{"id":"initialization"}},
111
+ {"success":true, "meta":{"id":"disconnection"}}
112
+ ]
113
+ }
114
+ ]
115
+ }
116
+ ```
117
+
118
+ ### Resolution
119
+
120
+ Xeme operates on the concept of "least successful outcome". A xeme cannot
121
+ represent more success than its descendent xemes. So, for example, the following
122
+ structure contains conflicts:
123
+
124
+ ```json
125
+ {
126
+ "success":true,
127
+ "nested":[
128
+ {"success":false}
129
+ ]
130
+ }
131
+ ```
132
+
133
+ It is necessary to resolve these conflicts before the xeme can be considered
134
+ valid. A conforming processor should implement the following rules:
135
+
136
+ * If a xeme is marked as failure, all of its ancestor xemes should be marked
137
+ as failed. So the example above would be resolved as follows:
138
+
139
+ ```json
140
+ {
141
+ "success":false,
142
+ "nested":[
143
+ {"success":false}
144
+ ]
145
+ }
146
+ ```
147
+
148
+ A process can be marked as failed regardless of its nested xemes. So there is no
149
+ conflict in the following structure.
150
+
151
+ ```json
152
+ {
153
+ "success":false,
154
+ "nested":[
155
+ {"success":true}
156
+ ]
157
+ }
158
+ ```
159
+
160
+ * If a xeme's `success` is null, then all its ancestors' `success` values must
161
+ be set to null if they are not already set to false. The following structure is
162
+ invalid.
163
+
164
+ ```json
165
+ {
166
+ "success":true,
167
+ "nested":[
168
+ {"success":null}
169
+ ]
170
+ }
171
+ ```
172
+
173
+ It should be resolved as follows:
174
+
175
+ ```json
176
+ {
177
+ "success":null,
178
+ "nested":[
179
+ {"success":null}
180
+ ]
181
+ }
182
+ ```
183
+
184
+ ### Advisory and promise xemes
185
+
186
+ Three types of Xemes operate on a different ruleset than standard xemes. Those
187
+ types are warnings, notes, and promises. They are indicated by the `type`
188
+ property:
189
+
190
+ ```json
191
+ {"type": "warning"}
192
+ ```
193
+
194
+ #### Warnings and notes
195
+
196
+ Warnings and notes provide advisory information about a process. They have no
197
+ affect on the success/failure determination. Warnings provide information about
198
+ non-fatal problems in a prosess. Notes do not indicate problems of any kind and
199
+ simply provide whatever arbitrary information might be useful. Advisory xemes
200
+ should not have `success` properties. So, for example, the following structure
201
+ is valid, even though the nested advisory xemes do not have `success`
202
+ properties.
203
+
204
+ ```json
205
+ {
206
+ "success":true,
207
+ "nested":[
208
+ {"type":"warning", "id":"invalid-setting"},
209
+ {"type":"note", "id":"database-connected"}
210
+ ]
211
+ }
212
+ ```
213
+
214
+ Advisory xemes can have nested xemes. However, all descendents of an advisory
215
+ xeme should themselves be advisory.
216
+
217
+ #### Promises
218
+
219
+ A promise xeme indicates that the success/failure of a process has yet to be
220
+ determined. A promise should have a `success` value of null, unless it has also
221
+ has a truthy value in `supplanted`. For example, the following xemes are valid:
222
+
223
+ ```json
224
+ { "type":"promise" }
225
+ ```
226
+
227
+ ```json
228
+ { "type":"promise", "supplanted":true, "success": true }
229
+ ```
230
+
231
+ ```json
232
+ { "type":"promise", "supplanted":"2023-06-22T06:28:43+0000", "success": true }
233
+ ```
83
234
 
84
- A xeme can have nested xemes within it. Those nested xemes go in the `nested`
85
- array:
235
+ Typically, a promise should have an indication of how the promise can be
236
+ resolved. For example, the following xeme is a promise, with further information
237
+ to indicate a URI where the final result can be determined, and how soon to
238
+ query that URI.
86
239
 
87
240
  ```json
88
241
  {
89
- "nested": [
90
- { "success": true },
91
- { "errors": [{"id":"server-fault"}] },
92
- ]
242
+ "type":"promise",
243
+ "uri": "https://example.com/20435t",
244
+ "delay": 6000
93
245
  }
94
246
  ```
95
247
 
96
- For a xeme to be considered successful, all of its nested xemes must be marked
97
- as success. If any nested xemes have errors, then the outermost xeme is
98
- considered to be considered as failed. If any nested xemes has `success` as nil,
99
- then the outermost xeme cannot `success` as true, though it can be explicitly
100
- false.
248
+ No standards are defined on how promises should provide such information. A
249
+ substandard may be defined down the road.
250
+
251
+ Best practice is that when a promise xeme is supplanted, it should have a nested
252
+ xeme that provides the final success/failure of the process.
253
+
254
+ ```json
255
+ {
256
+ "success": true,
257
+ "supplanted": true,
258
+ "type":"promise",
259
+ "uri": "https://example.com/20435t",
260
+ "delay": 6000,
261
+
262
+ "nested": [
263
+ {"success":true}
264
+ ]
265
+ }
266
+ ```
101
267
 
102
268
  ## Xeme gem
103
269
 
@@ -105,8 +271,8 @@ false.
105
271
 
106
272
  The usual:
107
273
 
108
- ```sh
109
- gem install xeme
274
+ ```bash
275
+ sudo gem install xeme
110
276
  ```
111
277
 
112
278
  ### Basic Xeme concepts
@@ -122,14 +288,6 @@ xeme = Xeme.new
122
288
  puts xeme # => #<Xeme:0x000055586f1340a8>
123
289
  ```
124
290
 
125
- Sometimes it's handy to give a xeme an identifier. You can do that by passing in
126
- a string in `Xeme.new`.
127
-
128
- ```ruby
129
- xeme = Xeme.new('my-xeme')
130
- puts xeme.id # => my-xeme
131
- ```
132
-
133
291
  If you want to access the hash stored in the xeme object, you can use the object
134
292
  as if it were a hash.
135
293
 
@@ -141,36 +299,30 @@ xeme['errors'].push({'id'=>'my-error'})
141
299
  ### Success and failure
142
300
 
143
301
  Because a xeme isn't considered successful until it has been explicitly declared
144
- so, a new xeme is considered to indicate failure. However, because there are no
145
- errors and `success` has not been explicitly set, `success?` returns `nil`
146
- instead of `false`.
302
+ so, a new xeme is considered to indicate failure or lack of determination of
303
+ success/failure.
147
304
 
148
305
  ```ruby
149
306
  xeme = Xeme.new
150
307
  puts xeme.success?.class # => NilClas
151
308
  ```
152
309
 
153
- There are two ways to mark a xeme as successful, one of which usually the better
154
- choice. The not-so-good way to mark success is with the `succeed` method.
310
+ To set a xeme to indicate failure, use the `fail` method.
155
311
 
156
312
  ```ruby
157
313
  xeme = Xeme.new
158
- xeme.succeed
159
- puts xeme.success? # => true
314
+ xeme.fail
315
+ puts xeme.success? # => false
160
316
  ```
161
317
 
162
- The problem with `succeed` is that if there are errors, `succeed` will raise an
163
- exception.
318
+ Perhaps counter-intuitively, there is no `succeed` method. That's because a xeme
319
+ cannot be reliably marked as succeeding without checking nested xemes (see
320
+ [resolution](#resolution)).
164
321
 
165
- ```ruby
166
- xeme = Xeme.new
167
- xeme.error 'my-error'
168
- xeme.succeed # => raises exception: `succeed': cannot-set-to-success: errors
169
- ```
170
-
171
- A better option is `try_succeed`. If your script gets to a point, usually at the
172
- end of the function or script, that you want to set the xeme to success, but
173
- only if there are no errors, use `try_succeed`.
322
+ Instead there is a `try_succeed` method. As its name implies, that method
323
+ resolves the xeme and its descendents, only marking the xeme as successful if
324
+ resolution allows. We'll get more into handling nested xemes later. The
325
+ following example shows setting a single xeme to success using `try_succeed`.
174
326
 
175
327
  ```ruby
176
328
  xeme = Xeme.new
@@ -178,217 +330,144 @@ xeme.try_succeed
178
330
  puts xeme.success? # => true
179
331
  ```
180
332
 
181
- If there are errors, `try_succeed` won't raise an exception, but will not set
182
- the xeme to failure.
333
+ `try_succeed` will only set a xeme to success if the current success is null or
334
+ true. It will not override an explicit setting of false.
183
335
 
184
336
  ```ruby
185
337
  xeme = Xeme.new
186
- xeme.error 'my-error'
338
+ xeme.fail
187
339
  xeme.try_succeed
188
340
  puts xeme.success? # => false
189
341
  ```
190
342
 
191
- ### Creating and using messages
343
+ ### Nesting xemes
192
344
 
193
- Messages in a xeme provide a way to indicate errors (i.e. fatal errors),
194
- warnings (non-fatal errors), notes (not an error at all), and promises (guides
195
- to getting the final success or failure of the process). A message is a hash
196
- with whatever arbitrary information you want to add. Each type of message has
197
- its own method for creating it, an array for storing them, and methods for
198
- checking if any exist. The following script creates an error, a warning, a
199
- note, and a promise.
345
+ Use `nest` to create nested xemes. If a block is sent, `nest` yields the new
346
+ xeme.
200
347
 
201
348
  ```ruby
202
- xeme = Xeme.new
203
- xeme.error 'my-error'
204
- xeme.warning 'my-warning'
205
- xeme.note 'my-note'
206
- xeme.promise 'my-promise'
349
+ xeme.nest() do |child|
350
+ # do stuff with nested xeme
351
+ end
207
352
  ```
208
353
 
209
- `#error`, `#warning`, `#note`, and `#promise` each create a message for their
210
- own type. Although it is not required, it's usually a good idea to give a string
211
- as the first parameter. That string will be set to the `id` element in the
212
- resulting hash, as seen in the example above.
354
+ `nest` also returns the new xeme.
355
+
356
+ ```ruby
357
+ child = xeme.nest()
358
+ ```
213
359
 
214
- `#errors`, `#warnings`, `#notes`, and `#promises` return arrays for each type.
360
+ Several methods exist to provide shortcuts for creating nested xemes of various
361
+ types: `success`, `error`, `warning`, `note`, and `promise`.
215
362
 
216
363
  ```ruby
217
- xeme.errors.each do |e|
218
- puts e['id'] # => my-error
364
+ xeme.success() do |child|
365
+ puts child.success? # => true
219
366
  end
220
367
 
221
- xeme.warnings.each do |w|
222
- puts w['id'] # => my-warning
368
+ xeme.error() do |child|
369
+ puts child.success? # => false
223
370
  end
224
371
 
225
- xeme.notes.each do |n|
226
- puts n['id'] # => my-note
372
+ # Xeme#failure does same thing as Xeme#error
373
+ xeme.failure() do |child|
374
+ puts child.success? # => false
227
375
  end
228
376
 
229
- xeme.promises.each do |p|
230
- puts p['id'] # => my-promise
377
+ xeme.warning() do |child|
378
+ puts child.class # => Xeme::Warning
231
379
  end
232
- ```
233
-
234
- **Gotcha:** These methods return frozen arrays, *not* the arrays in the xeme.
235
- This is because these methods return not only the xeme's own message arrays, but
236
- also any nested messages. See [Nesting xemes](#nesting-xemes) below.
237
-
238
- There are several ways to create and populate a message. Choose whichever is
239
- preferable to you. One way is demonstrated in the example above. You simply call
240
- the appropriate method, passing in an identifier. If all you want to do is
241
- create a message with an `id` then that's probably the easiest choice.
242
-
243
- Another way to use a `do` block to add custom information to the message.
244
380
 
245
- ```ruby
246
- xeme.error('my-error') do |error|
247
- error['database-error'] = 'some database error'
248
- error['commands'] = ['a', 'b', 'c']
381
+ xeme.note() do |child|
382
+ puts child.class # => Xeme::Note
249
383
  end
250
- ```
251
-
252
- Remember a message is just a hash, so you can add any kind of structure to the
253
- hash you want such a strings, booleans, hashes, and arrays.
254
-
255
- Finally, the message command returns the new message. So, if you want, you can
256
- assign that return value to a variable and work with the message that way.
257
-
258
- ```ruby
259
- err = xeme.error('my-error')
260
- err['database-error'] = 'some database error'
261
- err['commands'] = ['a', 'b', 'c']
262
- ```
263
-
264
- ### Creating metainformation
265
-
266
- The `#meta` method returns the `meta` element in the xeme hash, creating it if
267
- necessary. The hash will be automatically populated with a timestamp and a UUID.
268
- If you gave the xeme an identifier when you created it, that id will stored in
269
- the meta hash:
270
384
 
271
- ```ruby
272
- xeme = Xeme.new('my-xeme')
273
- puts xeme.meta
274
- ```
275
-
276
- This produces a `meta` hash like this:
277
-
278
- ```ruby
279
- {
280
- "uuid"=>"4e736a8f-314e-470a-8209-6811a7b2d38c",
281
- "timestamp"=>2023-05-29 19:22:37.26152866 -0400,
282
- "id"=>"my-xeme"
283
- }
284
- ```
285
-
286
- If you don't pass in an id then the meta hash isn't created. However, you can
287
- always create and use the meta hash by calling the `#meta` method. The timestamp
288
- and UUID will be automatically created.
289
-
290
- ```ruby
291
- xeme = Xeme.new
292
- xeme.meta['foo'] = 'bar'
293
- xeme.meta.class # => Hash
385
+ xeme.promise() do |child|
386
+ puts child.class # => Xeme::Promise
387
+ end
294
388
  ```
295
389
 
296
- ### Nesting xemes
297
-
298
- In complex testing situations it can be useful to nest results within other
299
- results. To nest a xeme within another xeme, use the `#nest` method:
300
-
301
- ```ruby
302
- xeme = Xeme.new('results')
303
- xeme.nest 'child-xeme'
304
- ```
390
+ #### Querying nested xemes
305
391
 
306
- You probably want to do something more than just create a nested xeme, so you
307
- can use a `do` block to work with the nested xeme:
392
+ Xeme provides several methods for traversing through a stack of nested xemes. In
393
+ the following examples, we'll use this structure:
308
394
 
309
395
  ```ruby
310
- xeme.nest('child-xeme') do |child|
311
- child.error 'child-error'
396
+ xeme = Xeme.new()
397
+ xeme.id = 'top'
398
+
399
+ xeme.nest() do |child|
400
+ child.id = 'foo'
401
+
402
+ child.nest() do |grandchild|
403
+ grandchild.id = 'bar'
404
+ grandchild.warning.id = 'my-warning'
405
+ grandchild.promise.id = 'my-promise'
406
+ grandchild.success
407
+ end
408
+
409
+ child.error.id = 'my-error'
410
+ child.note.id = 'my-note'
312
411
  end
313
412
  ```
314
413
 
315
- You can loop through all xemes, including the outermost xeme and all nested
316
- xemes, using the `#all` method.
414
+ The simplest is the `all` method, which returns the xeme itself and all nested
415
+ xemes as a locked array.
317
416
 
318
417
  ```ruby
319
418
  xeme.all.each do |x|
320
419
  puts x.id
321
420
  end
322
- ```
323
421
 
324
- **Nested messages**
422
+ # => top
423
+ # => foo
424
+ # => bar
425
+ # => my-warning
426
+ # => my-promise
427
+ # => my-error
428
+ # => my-note
429
+ ```
325
430
 
326
- The `#errors`, `#warnings`, `#notes`, and `#promises` methods return arrays of
327
- all messages within the xeme, including the outermost xeme and nested xemes.
431
+ There are several methods for selecting xemes based on their success status.
328
432
 
329
433
  ```ruby
330
- xeme = Xeme.new
331
- xeme.error 'outer-error'
332
-
333
- xeme.nest do |child|
334
- child.error 'child-error'
335
- end
434
+ # xemes marked as success=false
435
+ puts xeme.errors.length # => 3
336
436
 
337
- puts xeme.errors
437
+ # xemes marked as success=true
438
+ puts xeme.successes.length # => 1
338
439
 
339
- # => {"id"=>"outer-error"}
340
- # => {"id"=>"child-error"}
440
+ # xemes marked as success=null
441
+ # does not return advisory xemes
442
+ puts xeme.nils.length # => 2
341
443
  ```
342
444
 
343
- If you want to search for messages with a specific `id`, add that id to the
344
- messages method:
445
+ There are also several methods for selecting specific xemes based on their types.
345
446
 
346
447
  ```ruby
347
- puts xeme.errors('child-error') # => {"id"=>"child-error"}
448
+ puts xeme.warnings.length # => 1
449
+ puts xeme.notes.length # => 2
450
+ puts xeme.promises.length # => 1
348
451
  ```
349
452
 
350
- **Flatten**
453
+ ### resolve() and try_succeed()
351
454
 
352
- Finally, if you want to slurp up all messages into the outermost xeme and delete
353
- the nested xemes, use `#flatten`.
455
+ Xemes can be [resolved](#resolution) using the `resolve` method.
354
456
 
355
457
  ```ruby
356
- puts xeme['errors']
357
- # => {"id"=>"outer-error"}
358
-
359
- xeme.flatten
360
-
361
- puts xeme['errors']
362
- # => {"id"=>"outer-error"}
363
- # => {"id"=>"child-error"}
458
+ xeme.resolve
364
459
  ```
365
460
 
461
+ It's common that your process will get to a point, typically at the end of the
462
+ script, where you want to mark the process as successful, but only if there were
463
+ no errors. Use `try_succeed` for that. That method first resolves the xeme and
464
+ its descendents, then marks the xeme (and descendents) as successful if there
465
+ are no errors.
366
466
 
367
- ### Resolving xemes
368
-
369
- A xeme can contain contradictory information. For example, if `success` is true
370
- but there are errors, then the xeme should be considered as failed. If there are
371
- promises, then the xeme should not be considered as failed, although `success`
372
- may be set as nil.
373
-
374
- The `#resolve` method resolves those contradictions. Generally you won't have to
375
- call `#resolve` yourself, but it's worth understanding the rules:
376
-
377
- * A xeme can always be explicitly set to false, regardless of any other
378
- considerations. Resolution never changes a `success` of false.
379
-
380
- * If any nested xemes have `success` explicitly set to false, then the outermost
381
- xeme will be set to false.
382
-
383
- * If a xeme has errors, or any of its nested xemes has errors, then it is set to
384
- false.
385
-
386
- * If a xeme has promises, or any of its nested xemes do, then it cannot be set
387
- to true. If it is already false, then it stays false. Otherwise `success` is set
388
- to nil.
389
-
390
- * If any nested xemes have `success` set to nil, then the outermost xeme cannot
391
- be set to true.
467
+ ```ruby
468
+ xeme.try_succeed
469
+ puts xeme.success? # => true, false, or nil
470
+ ```
392
471
 
393
472
  ## The name
394
473
 
@@ -409,4 +488,6 @@ mike@idocs.com
409
488
  |---------|--------------|-------------------------------|
410
489
  | 0.1 | Jan 7, 2020 | Initial upload. |
411
490
  | 1.0 | May 29, 2023 | Complete overhaul. Not backward compatible. |
412
- | 1.1 | May 29, 2023 | Added and cleaned up documentation. No change to funcationality. |
491
+ | 1.1 | May 29, 2023 | Added and cleaned up documentation. No change to functionality. |
492
+ | 1.2 | May 29, 2023 | More cleanup to documentation. |
493
+ | 2.0 | Jun 22, 2023 | Another complete overhaul. This should be the last non-backwards compatible revision. |