bcdd-result 0.13.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -4
  3. data/CHANGELOG.md +46 -17
  4. data/README.md +381 -220
  5. data/Rakefile +1 -1
  6. data/Steepfile +1 -1
  7. data/examples/multiple_listeners/Rakefile +8 -8
  8. data/examples/multiple_listeners/app/models/account/owner_creation.rb +1 -1
  9. data/examples/multiple_listeners/app/models/user/creation.rb +1 -1
  10. data/examples/multiple_listeners/app/models/user/token/creation.rb +1 -1
  11. data/examples/multiple_listeners/config/initializers/bcdd.rb +0 -2
  12. data/examples/multiple_listeners/config.rb +3 -3
  13. data/examples/multiple_listeners/db/setup.rb +2 -3
  14. data/examples/multiple_listeners/lib/bcdd/result/event_logs_record.rb +27 -0
  15. data/examples/multiple_listeners/lib/event_logs_listener/stdout.rb +60 -0
  16. data/examples/multiple_listeners/lib/runtime_breaker.rb +1 -1
  17. data/examples/service_objects/Rakefile +36 -0
  18. data/examples/service_objects/app/models/account/member.rb +10 -0
  19. data/examples/service_objects/app/models/account.rb +11 -0
  20. data/examples/service_objects/app/models/user/token.rb +7 -0
  21. data/examples/service_objects/app/models/user.rb +15 -0
  22. data/examples/service_objects/app/services/account/owner_creation.rb +47 -0
  23. data/examples/service_objects/app/services/application_service.rb +79 -0
  24. data/examples/service_objects/app/services/user/creation.rb +56 -0
  25. data/examples/service_objects/app/services/user/token/creation.rb +37 -0
  26. data/examples/service_objects/config/boot.rb +17 -0
  27. data/examples/service_objects/config/initializers/bcdd.rb +9 -0
  28. data/examples/service_objects/config.rb +20 -0
  29. data/examples/service_objects/db/setup.rb +49 -0
  30. data/examples/single_listener/Rakefile +5 -5
  31. data/examples/single_listener/app/models/account/owner_creation.rb +1 -1
  32. data/examples/single_listener/app/models/user/creation.rb +1 -1
  33. data/examples/single_listener/app/models/user/token/creation.rb +1 -1
  34. data/examples/single_listener/config/initializers/bcdd.rb +0 -2
  35. data/examples/single_listener/config.rb +1 -1
  36. data/examples/single_listener/lib/{single_transitions_listener.rb → single_event_logs_listener.rb} +32 -23
  37. data/lib/bcdd/{result/context → context}/callable_and_then.rb +5 -4
  38. data/lib/bcdd/{result/context → context}/expectations/mixin.rb +1 -1
  39. data/lib/bcdd/{result/context → context}/expectations.rb +2 -2
  40. data/lib/bcdd/context/failure.rb +9 -0
  41. data/lib/bcdd/{result/context → context}/mixin.rb +2 -2
  42. data/lib/bcdd/{result/context → context}/success.rb +6 -6
  43. data/lib/bcdd/context.rb +91 -0
  44. data/lib/bcdd/failure.rb +23 -0
  45. data/lib/bcdd/result/_self.rb +198 -0
  46. data/lib/bcdd/result/callable_and_then/caller.rb +1 -1
  47. data/lib/bcdd/result/config/switchers/addons.rb +2 -2
  48. data/lib/bcdd/result/config/switchers/constant_aliases.rb +1 -3
  49. data/lib/bcdd/result/config/switchers/features.rb +5 -5
  50. data/lib/bcdd/result/config/switchers/pattern_matching.rb +1 -1
  51. data/lib/bcdd/result/config.rb +7 -5
  52. data/lib/bcdd/result/contract/type_checker.rb +4 -0
  53. data/lib/bcdd/result/{transitions → event_logs}/config.rb +5 -3
  54. data/lib/bcdd/result/{transitions → event_logs}/listener.rb +5 -5
  55. data/lib/bcdd/result/{transitions → event_logs}/listeners.rb +17 -17
  56. data/lib/bcdd/result/{transitions → event_logs}/tracking/disabled.rb +1 -1
  57. data/lib/bcdd/result/{transitions → event_logs}/tracking/enabled.rb +15 -13
  58. data/lib/bcdd/result/{transitions → event_logs}/tracking.rb +4 -3
  59. data/lib/bcdd/result/{transitions → event_logs}/tree.rb +27 -11
  60. data/lib/bcdd/result/event_logs.rb +27 -0
  61. data/lib/bcdd/result/failure.rb +1 -3
  62. data/lib/bcdd/result/success.rb +1 -3
  63. data/lib/bcdd/result/version.rb +1 -1
  64. data/lib/bcdd/result.rb +23 -191
  65. data/lib/bcdd/success.rb +23 -0
  66. data/sig/bcdd/context.rbs +175 -0
  67. data/sig/bcdd/failure.rbs +13 -0
  68. data/sig/bcdd/result/config.rbs +1 -3
  69. data/sig/bcdd/result/context.rbs +2 -174
  70. data/sig/bcdd/result/contract.rbs +1 -0
  71. data/sig/bcdd/result/{transitions.rbs → event_logs.rbs} +19 -19
  72. data/sig/bcdd/result.rbs +13 -31
  73. data/sig/bcdd/success.rbs +13 -0
  74. metadata +41 -24
  75. data/examples/multiple_listeners/lib/bcdd/result/transitions_record.rb +0 -28
  76. data/examples/multiple_listeners/lib/transitions_listener/stdout.rb +0 -54
  77. data/lib/bcdd/result/context/failure.rb +0 -9
  78. data/lib/bcdd/result/context.rb +0 -93
  79. data/lib/bcdd/result/failure/methods.rb +0 -21
  80. data/lib/bcdd/result/success/methods.rb +0 -21
  81. data/lib/bcdd/result/transitions.rb +0 -27
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  <h1 align="center" id="-bcddresult">🔀 BCDD::Result</h1>
3
3
  <p align="center"><i>Unleash a pragmatic and observable use of Result Pattern and Railway-Oriented Programming in Ruby.</i></p>
4
4
  <p align="center">
5
- <img src="https://img.shields.io/badge/ruby->%3D%202.7.0-ruby.svg?colorA=99004d&colorB=cc0066" alt="Ruby">
5
+ <img src="https://img.shields.io/badge/Ruby%20%3E%3D%202.7%2C%20%3C%3D%20Head-ruby.svg?colorA=444&colorB=333" alt="Ruby">
6
6
  <a href="https://rubygems.org/gems/bcdd-result"><img src="https://badge.fury.io/rb/bcdd-result.svg" alt="bcdd-result gem version" height="18"></a>
7
7
  <a href="https://codeclimate.com/github/B-CDD/result/maintainability"><img src="https://api.codeclimate.com/v1/badges/aa8360f8f012d7dedd62/maintainability" /></a>
8
8
  <a href="https://codeclimate.com/github/B-CDD/result/test_coverage"><img src="https://api.codeclimate.com/v1/badges/aa8360f8f012d7dedd62/test_coverage" /></a>
@@ -19,12 +19,13 @@ Furthermore, this abstraction exposes several features that will be useful to ma
19
19
 
20
20
  Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofit.com/rop/) pattern (superpower) in your code.
21
21
 
22
- - [Ruby Version](#ruby-version)
22
+ - [Supported Ruby](#supported-ruby)
23
23
  - [Installation](#installation)
24
24
  - [Usage](#usage)
25
25
  - [`BCDD::Result` *versus* `Result`](#bcddresult-versus-result)
26
26
  - [Reference](#reference)
27
- - [Result Attributes](#result-attributes)
27
+ - [Basic methods](#basic-methods)
28
+ - [Checking types with `result.is?` or `method missing`](#checking-types-with-resultis-or-method-missing)
28
29
  - [Checking types with `result.success?` or `result.failure?`](#checking-types-with-resultsuccess-or-resultfailure)
29
30
  - [Result Hooks](#result-hooks)
30
31
  - [`result.on`](#resulton)
@@ -37,9 +38,6 @@ Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofi
37
38
  - [`result.value_or`](#resultvalue_or)
38
39
  - [Result Data](#result-data)
39
40
  - [`result.data`](#resultdata)
40
- - [Pattern Matching](#pattern-matching)
41
- - [`Array`/`Find` patterns](#arrayfind-patterns)
42
- - [`Hash` patterns](#hash-patterns)
43
41
  - [Railway Oriented Programming](#railway-oriented-programming)
44
42
  - [`result.and_then`](#resultand_then)
45
43
  - [`BCDD::Result.mixin`](#bcddresultmixin)
@@ -63,17 +61,25 @@ Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofi
63
61
  - [Failure()](#failure)
64
62
  - [Pattern Matching Support](#pattern-matching-support)
65
63
  - [`BCDD::Result::Expectations.mixin` add-ons](#bcddresultexpectationsmixin-add-ons)
66
- - [`BCDD::Result::Context`](#bcddresultcontext)
64
+ - [`BCDD::Context`](#bcddcontext)
67
65
  - [Defining successes and failures](#defining-successes-and-failures)
68
66
  - [Constant aliases](#constant-aliases)
69
- - [`BCDD::Result::Context.mixin`](#bcddresultcontextmixin)
67
+ - [`BCDD::Context.mixin`](#bcddcontextmixin)
70
68
  - [Class example (Instance Methods)](#class-example-instance-methods-1)
71
69
  - [`and_expose`](#and_expose)
72
70
  - [Module example (Singleton Methods)](#module-example-singleton-methods-1)
73
- - [`BCDD::Result::Context::Expectations`](#bcddresultcontextexpectations)
71
+ - [`BCDD::Context::Expectations`](#bcddcontextexpectations)
74
72
  - [Mixin add-ons](#mixin-add-ons)
75
- - [`BCDD::Result.transitions`](#bcddresulttransitions)
76
- - [`ids_tree` *versus* `ids_matrix`](#ids_tree-versus-ids_matrix)
73
+ - [Pattern Matching](#pattern-matching)
74
+ - [`BCDD::Result`](#bcddresult)
75
+ - [`Array`/`Find` patterns](#arrayfind-patterns)
76
+ - [`Hash` patterns](#hash-patterns)
77
+ - [`BCDD::Context`](#bcddcontext-1)
78
+ - [`Array`/`Find` patterns](#arrayfind-patterns-1)
79
+ - [`Hash` patterns](#hash-patterns-1)
80
+ - [How to pattern match without the concept of success and failure](#how-to-pattern-match-without-the-concept-of-success-and-failure)
81
+ - [`BCDD::Result.event_logs`](#bcddresultevent_logs)
82
+ - [`metadata: {ids:}`](#metadata-ids)
77
83
  - [Configuration](#configuration)
78
84
  - [Turning on/off](#turning-onoff)
79
85
  - [Setting a `trace_id` fetcher](#setting-a-trace_id-fetcher)
@@ -93,9 +99,13 @@ Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofi
93
99
  - [License](#license)
94
100
  - [Code of Conduct](#code-of-conduct)
95
101
 
96
- ## Ruby Version
102
+ ## Supported Ruby
103
+
104
+ This library is tested against:
97
105
 
98
- `>= 2.7.0`
106
+ Version | 2.7 | 3.0 | 3.1 | 3.2 | 3.3 | Head
107
+ ---- | --- | --- | --- | --- | --- | ---
108
+ 100% Coverage | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
99
109
 
100
110
  ## Installation
101
111
 
@@ -167,7 +177,7 @@ There are other aliases and configurations available. Check the [BCDD::Result.co
167
177
 
168
178
  ## Reference
169
179
 
170
- ### Result Attributes
180
+ ### Basic methods
171
181
 
172
182
  Both `BCDD::Result::Success` and `BCDD::Result::Failure` are composed of the same methods. Look at the basic ones:
173
183
 
@@ -179,20 +189,22 @@ Both `BCDD::Result::Success` and `BCDD::Result::Failure` are composed of the sam
179
189
  ################
180
190
  result = BCDD::Result::Success(:ok, my: 'value')
181
191
 
182
- result.success? # true
183
- result.failure? # false
184
- result.type # :ok
185
- result.value # {:my => "value"}
192
+ result.success? # true
193
+ result.failure? # false
194
+ result.type?(:ok) # true
195
+ result.type # :ok
196
+ result.value # {:my => "value"}
186
197
 
187
198
  ###################
188
199
  # Without a value #
189
200
  ###################
190
201
  result = BCDD::Result::Success(:yes)
191
202
 
192
- result.success? # true
193
- result.failure? # false
194
- result.type # :yes
195
- result.value # nil
203
+ result.success? # true
204
+ result.failure? # false
205
+ result.type?(:yes) # true
206
+ result.type # :yes
207
+ result.value # nil
196
208
  ```
197
209
 
198
210
  **BCDD::Result::Failure**
@@ -203,26 +215,46 @@ result.value # nil
203
215
  ################
204
216
  result = BCDD::Result::Failure(:err, 'my_value')
205
217
 
206
- result.success? # false
207
- result.failure? # true
208
- result.type # :err
209
- result.value # "my_value"
218
+ result.success? # false
219
+ result.failure? # true
220
+ result.type?(:err) # true
221
+ result.type # :err
222
+ result.value # "my_value"
210
223
 
211
224
  ###################
212
225
  # Without a value #
213
226
  ###################
214
227
  result = BCDD::Result::Failure(:no)
215
228
 
216
- result.success? # false
217
- result.failure? # true
218
- result.type # :no
219
- result.value # nil
229
+ result.success? # false
230
+ result.failure? # true
231
+ result.type?(:no) # true
232
+ result.type # :no
233
+ result.value # nil
220
234
  ```
221
235
 
222
236
  In both cases, the `type` must be a symbol, and the `value` can be any kind of object.
223
237
 
224
238
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
225
239
 
240
+ #### Checking types with `result.is?` or `method missing`
241
+
242
+ Beyond the `type?` method, you can also use the `is?` method to check the result type. If you want to check the type directly, you can write the type using a method that ends with a question mark.
243
+
244
+ ```ruby
245
+ result = BCDD::Result::Success(:ok)
246
+
247
+ result.is?(:ok) # true
248
+ result.ok? # true
249
+
250
+ result = BCDD::Result::Failure(:err)
251
+
252
+ result.is?(:err) # true
253
+ result.err? # true
254
+ ```
255
+
256
+ <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
257
+
226
258
  #### Checking types with `result.success?` or `result.failure?`
227
259
 
228
260
  `BCDD::Result#success?` and `BCDD::Result#failure?` are methods that allow you to check if the result is a success or a failure.
@@ -533,67 +565,6 @@ print_to_hash(**success_data) # [:success, :ok, 1]
533
565
 
534
566
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
535
567
 
536
- ### Pattern Matching
537
-
538
- The `BCDD::Result` also provides support to pattern matching.
539
-
540
- In the further examples, I will use the `Divide` lambda to exemplify its usage.
541
-
542
- ```ruby
543
- Divide = lambda do |arg1, arg2|
544
- arg1.is_a?(::Numeric) or return BCDD::Result::Failure(:invalid_arg, 'arg1 must be numeric')
545
- arg2.is_a?(::Numeric) or return BCDD::Result::Failure(:invalid_arg, 'arg2 must be numeric')
546
-
547
- return BCDD::Result::Failure(:division_by_zero, 'arg2 must not be zero') if arg2.zero?
548
-
549
- BCDD::Result::Success(:division_completed, arg1 / arg2)
550
- end
551
- ```
552
-
553
- #### `Array`/`Find` patterns
554
-
555
- ```ruby
556
- case Divide.call(4, 2)
557
- in BCDD::Result::Failure[:invalid_arg, msg] then puts msg
558
- in BCDD::Result::Failure[:division_by_zero, msg] then puts msg
559
- in BCDD::Result::Success[:division_completed, value] then puts value
560
- end
561
-
562
- # The code above will print: 2
563
-
564
- case Divide.call(4, 0)
565
- in BCDD::Result::Failure[:invalid_arg, msg] then puts msg
566
- in BCDD::Result::Failure[:division_by_zero, msg] then puts msg
567
- in BCDD::Result::Success[:division_completed, value] then puts value
568
- end
569
-
570
- # The code above will print: arg2 must not be zero
571
- ```
572
-
573
- <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
574
-
575
- #### `Hash` patterns
576
-
577
- ```ruby
578
- case Divide.call(10, 2)
579
- in { failure: { invalid_arg: msg } } then puts msg
580
- in { failure: { division_by_zero: msg } } then puts msg
581
- in { success: { division_completed: value } } then puts value
582
- end
583
-
584
- # The code above will print: 5
585
-
586
- case Divide.call('10', 2)
587
- in { failure: { invalid_arg: msg } } then puts msg
588
- in { failure: { division_by_zero: msg } } then puts msg
589
- in { success: { division_completed: value } } then puts value
590
- end
591
-
592
- # The code above will print: arg1 must be numeric
593
- ```
594
-
595
- <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
596
-
597
568
  ### Railway Oriented Programming
598
569
 
599
570
  ["Railway Oriented Programming (ROP)"](https://fsharpforfunandprofit.com/rop/) is a programming technique that involves linking blocks together to form a sequence of operations, also known as a pipeline.
@@ -1429,45 +1400,45 @@ result.success?(:ok)
1429
1400
 
1430
1401
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1431
1402
 
1432
- ### `BCDD::Result::Context`
1403
+ ### `BCDD::Context`
1433
1404
 
1434
- The `BCDD::Result::Context` is a `BCDD::Result`, meaning it has all the features of the `BCDD::Result`. The main difference is that it only accepts keyword arguments as a value, which applies to the `and_then`: The called methods must receive keyword arguments, and the dependency injection will be performed through keyword arguments.
1405
+ The `BCDD::Context` is a `BCDD::Result`, meaning it has all the features of the `BCDD::Result`. The main difference is that it only accepts keyword arguments as a value, which applies to the `and_then`: The called methods must receive keyword arguments, and the dependency injection will be performed through keyword arguments.
1435
1406
 
1436
- As the input/output are hashes, the results of each `and_then` call will automatically accumulate. This is useful in operations chaining, as the result of the previous operations will be automatically available for the next one. Because of this behavior, the `BCDD::Result::Context` has the `#and_expose` method to expose only the desired keys from the accumulated result.
1407
+ As the input/output are hashes, the results of each `and_then` call will automatically accumulate. This is useful in operations chaining, as the result of the previous operations will be automatically available for the next one. Because of this behavior, the `BCDD::Context` has the `#and_expose` method to expose only the desired keys from the accumulated result.
1437
1408
 
1438
1409
  #### Defining successes and failures
1439
1410
 
1440
- As the `BCDD::Result`, you can declare success and failures directly from `BCDD::Result::Context`.
1411
+ As the `BCDD::Result`, you can declare success and failures directly from `BCDD::Context`.
1441
1412
 
1442
1413
  ```ruby
1443
- BCDD::Result::Context::Success(:ok, a: 1, b: 2)
1444
- #<BCDD::Result::Context::Success type=:ok value={:a=>1, :b=>2}>
1414
+ BCDD::Context::Success(:ok, a: 1, b: 2)
1415
+ #<BCDD::Context::Success type=:ok value={:a=>1, :b=>2}>
1445
1416
 
1446
- BCDD::Result::Context::Failure(:err, message: 'something went wrong')
1447
- #<BCDD::Result::Context::Failure type=:err value={:message=>"something went wrong"}>
1417
+ BCDD::Context::Failure(:err, message: 'something went wrong')
1418
+ #<BCDD::Context::Failure type=:err value={:message=>"something went wrong"}>
1448
1419
  ```
1449
1420
 
1450
- But different from `BCDD::Result` that accepts any value, the `BCDD::Result::Context` only takes keyword arguments.
1421
+ But different from `BCDD::Result` that accepts any value, the `BCDD::Context` only takes keyword arguments.
1451
1422
 
1452
1423
  ```ruby
1453
- BCDD::Result::Context::Success(:ok, [1, 2])
1424
+ BCDD::Context::Success(:ok, [1, 2])
1454
1425
  # wrong number of arguments (given 2, expected 1) (ArgumentError)
1455
1426
 
1456
- BCDD::Result::Context::Failure(:err, { message: 'something went wrong' })
1427
+ BCDD::Context::Failure(:err, { message: 'something went wrong' })
1457
1428
  # wrong number of arguments (given 2, expected 1) (ArgumentError)
1458
1429
 
1459
1430
  #
1460
1431
  # Use ** to convert a hash to keyword arguments
1461
1432
  #
1462
- BCDD::Result::Context::Success(:ok, **{ message: 'hashes can be converted to keyword arguments' })
1463
- #<BCDD::Result::Context::Success type=:ok value={:message=>"hashes can be converted to keyword arguments"}>
1433
+ BCDD::Context::Success(:ok, **{ message: 'hashes can be converted to keyword arguments' })
1434
+ #<BCDD::Context::Success type=:ok value={:message=>"hashes can be converted to keyword arguments"}>
1464
1435
  ```
1465
1436
 
1466
1437
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1467
1438
 
1468
1439
  #### Constant aliases
1469
1440
 
1470
- You can configure `Context` or `BCDD::Context` as an alias for `BCDD::Result::Context`. This is helpful to define a standard way to avoid the full constant name/path in your code.
1441
+ You can configure `Context` or `BCDD::Context` as an alias for `BCDD::Context`. This is helpful to define a standard way to avoid the full constant name/path in your code.
1471
1442
 
1472
1443
  ```ruby
1473
1444
  BCDD::Result.configuration do |config|
@@ -1481,9 +1452,9 @@ end
1481
1452
 
1482
1453
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1483
1454
 
1484
- #### `BCDD::Result::Context.mixin`
1455
+ #### `BCDD::Context.mixin`
1485
1456
 
1486
- As in the `BCDD::Result`, you can use the `BCDD::Result::Context.mixin` to add the `Success()` and `Failure()` methods to your classes/modules.
1457
+ As in the `BCDD::Result`, you can use the `BCDD::Context.mixin` to add the `Success()` and `Failure()` methods to your classes/modules.
1487
1458
 
1488
1459
  Let's see this feature and the data accumulation in action:
1489
1460
 
@@ -1493,7 +1464,7 @@ Let's see this feature and the data accumulation in action:
1493
1464
  require 'logger'
1494
1465
 
1495
1466
  class Divide
1496
- include BCDD::Result::Context.mixin
1467
+ include BCDD::Context.mixin
1497
1468
 
1498
1469
  def call(arg1, arg2, logger: ::Logger.new(STDOUT))
1499
1470
  validate_numbers(arg1, arg2)
@@ -1530,29 +1501,29 @@ end
1530
1501
 
1531
1502
  Divide.new.call(10, 5)
1532
1503
  # I, [2023-10-27T01:51:46.905004 #76915] INFO -- : The division result is 2
1533
- #<BCDD::Result::Context::Success type=:ok value={:number=>2}>
1504
+ #<BCDD::Context::Success type=:ok value={:number=>2}>
1534
1505
 
1535
1506
  Divide.new.call('10', 5)
1536
- #<BCDD::Result::Context::Failure type=:err value={:message=>"arg1 must be numeric"}>
1507
+ #<BCDD::Context::Failure type=:err value={:message=>"arg1 must be numeric"}>
1537
1508
 
1538
1509
  Divide.new.call(10, '5')
1539
- #<BCDD::Result::Context::Failure type=:err value={:message=>"arg2 must be numeric"}>
1510
+ #<BCDD::Context::Failure type=:err value={:message=>"arg2 must be numeric"}>
1540
1511
 
1541
1512
  Divide.new.call(10, 0)
1542
- #<BCDD::Result::Context::Failure type=:err value={:message=>"arg2 must not be zero"}>
1513
+ #<BCDD::Context::Failure type=:err value={:message=>"arg2 must not be zero"}>
1543
1514
  ```
1544
1515
 
1545
1516
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1546
1517
 
1547
1518
  ##### `and_expose`
1548
1519
 
1549
- This allows you to expose only the desired keys from the accumulated result. It can be used with any `BCDD::Result::Context` object.
1520
+ This allows you to expose only the desired keys from the accumulated result. It can be used with any `BCDD::Context` object.
1550
1521
 
1551
1522
  Let's add it to the previous example:
1552
1523
 
1553
1524
  ```ruby
1554
1525
  class Divide
1555
- include BCDD::Result::Context.mixin
1526
+ include BCDD::Context.mixin
1556
1527
 
1557
1528
  def call(arg1, arg2)
1558
1529
  validate_numbers(arg1, arg2)
@@ -1582,7 +1553,7 @@ class Divide
1582
1553
  end
1583
1554
 
1584
1555
  Divide.new.call(10, 5)
1585
- #<BCDD::Result::Context::Success type=:division_completed value={:number=>2}>
1556
+ #<BCDD::Context::Success type=:division_completed value={:number=>2}>
1586
1557
  ```
1587
1558
 
1588
1559
  As you can see, even with `divide` success exposing the division number with all the accumulated data (`**input`), the `#and_expose` could generate a new success with a new type and only with the desired keys.
@@ -1591,7 +1562,7 @@ Remove the `#and_expose` call to see the difference. This will be the outcome:
1591
1562
 
1592
1563
  ```ruby
1593
1564
  Divide.new.call(10, 5)
1594
- #<BCDD::Result::Context::Success type=:ok value={:number=>2, :number1=>10, :number2=>5}>
1565
+ #<BCDD::Context::Success type=:ok value={:number=>2, :number1=>10, :number2=>5}>
1595
1566
  ```
1596
1567
 
1597
1568
  > PS: The `#and_expose` produces a terminal success by default. This means the next step will not be executed even if you call `#and_then` after `#and_expose`. To change this behavior, you can pass `terminal: false` to `#and_expose`.
@@ -1600,11 +1571,11 @@ Divide.new.call(10, 5)
1600
1571
 
1601
1572
  ##### Module example (Singleton Methods)
1602
1573
 
1603
- `BCDD::Result::Context.mixin` can also produce singleton methods. Below is an example using a module (but it could be a class, too).
1574
+ `BCDD::Context.mixin` can also produce singleton methods. Below is an example using a module (but it could be a class, too).
1604
1575
 
1605
1576
  ```ruby
1606
1577
  module Divide
1607
- extend self, BCDD::Result::Context.mixin
1578
+ extend self, BCDD::Context.mixin
1608
1579
 
1609
1580
  def call(arg1, arg2)
1610
1581
  validate_numbers(arg1, arg2)
@@ -1634,29 +1605,29 @@ module Divide
1634
1605
  end
1635
1606
 
1636
1607
  Divide.call(10, 5)
1637
- #<BCDD::Result::Context::Success type=:division_completed value={:number=>2}>
1608
+ #<BCDD::Context::Success type=:division_completed value={:number=>2}>
1638
1609
 
1639
1610
  Divide.call('10', 5)
1640
- #<BCDD::Result::Context::Failure type=:err value={:message=>"arg1 must be numeric"}>
1611
+ #<BCDD::Context::Failure type=:err value={:message=>"arg1 must be numeric"}>
1641
1612
 
1642
1613
  Divide.call(10, '5')
1643
- #<BCDD::Result::Context::Failure type=:err value={:message=>"arg2 must be numeric"}>
1614
+ #<BCDD::Context::Failure type=:err value={:message=>"arg2 must be numeric"}>
1644
1615
 
1645
1616
  Divide.call(10, 0)
1646
- #<BCDD::Result::Context::Failure type=:err value={:message=>"arg2 must not be zero"}>
1617
+ #<BCDD::Context::Failure type=:err value={:message=>"arg2 must not be zero"}>
1647
1618
  ```
1648
1619
 
1649
1620
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1650
1621
 
1651
- #### `BCDD::Result::Context::Expectations`
1622
+ #### `BCDD::Context::Expectations`
1652
1623
 
1653
- The `BCDD::Result::Context::Expectations` is a `BCDD::Result::Expectations` with the `BCDD::Result::Context` features.
1624
+ The `BCDD::Context::Expectations` is a `BCDD::Result::Expectations` with the `BCDD::Context` features.
1654
1625
 
1655
1626
  This is an example using the mixin mode, but the standalone mode is also supported.
1656
1627
 
1657
1628
  ```ruby
1658
1629
  class Divide
1659
- include BCDD::Result::Context::Expectations.mixin(
1630
+ include BCDD::Context::Expectations.mixin(
1660
1631
  config: {
1661
1632
  pattern_matching: { nil_as_valid_value_checking: true }
1662
1633
  },
@@ -1680,16 +1651,16 @@ class Divide
1680
1651
  end
1681
1652
 
1682
1653
  Divide.new.call(10, 5)
1683
- #<BCDD::Result::Context::Success type=:division_completed value={:number=>2}>
1654
+ #<BCDD::Context::Success type=:division_completed value={:number=>2}>
1684
1655
  ```
1685
1656
 
1686
- As in the `BCDD::Result::Expectations.mixin`, the `BCDD::Result::Context::Expectations.mixin` will add a Result constant in the target class. It can generate success/failure results, which ensure the mixin expectations.
1657
+ As in the `BCDD::Result::Expectations.mixin`, the `BCDD::Context::Expectations.mixin` will add a Result constant in the target class. It can generate success/failure results, which ensure the mixin expectations.
1687
1658
 
1688
1659
  Let's see this using the previous example:
1689
1660
 
1690
1661
  ```ruby
1691
1662
  Divide::Result::Success(:division_completed, number: 2)
1692
- #<BCDD::Result::Context::Success type=:division_completed value={:number=>2}>
1663
+ #<BCDD::Context::Success type=:division_completed value={:number=>2}>
1693
1664
 
1694
1665
  Divide::Result::Success(:division_completed, number: '2')
1695
1666
  # value {:number=>"2"} is not allowed for :division_completed type ({:number=>"2"}: Numeric === "2" does not return true) (BCDD::Result::Contract::Error::UnexpectedValue)
@@ -1699,7 +1670,7 @@ Divide::Result::Success(:division_completed, number: '2')
1699
1670
 
1700
1671
  #### Mixin add-ons
1701
1672
 
1702
- The `BCDD::Result::Context.mixin` and `BCDD::Result::Context::Expectations.mixin` also accepts the `config:` argument. And it works the same way as the `BCDD::Result` mixins.
1673
+ The `BCDD::Context.mixin` and `BCDD::Context::Expectations.mixin` also accepts the `config:` argument. And it works the same way as the `BCDD::Result` mixins.
1703
1674
 
1704
1675
  **given**
1705
1676
 
@@ -1707,21 +1678,21 @@ This addon is enabled by default. It will create the `Given(*value)` method. Use
1707
1678
 
1708
1679
  You can turn it off by passing `given: false` to the `config:` argument or using the `BCDD::Result.configuration`.
1709
1680
 
1710
- The `Given()` addon for a BCDD::Result::Context can be called with one or more arguments. The arguments will be converted to a hash (`to_h`) and merged to define the first value of the result chain.
1681
+ The `Given()` addon for a BCDD::Context can be called with one or more arguments. The arguments will be converted to a hash (`to_h`) and merged to define the first value of the result chain.
1711
1682
 
1712
1683
  **continue**
1713
1684
 
1714
- The `BCDD::Result::Context.mixin(config: { addon: { continue: true } })` or `BCDD::Result::Context::Expectations.mixin(config: { addon: { continue: true } })` creates the `Continue(value)` method and change the `Success()` behavior to terminate the step chain.
1685
+ The `BCDD::Context.mixin(config: { addon: { continue: true } })` or `BCDD::Context::Expectations.mixin(config: { addon: { continue: true } })` creates the `Continue(value)` method and change the `Success()` behavior to terminate the step chain.
1715
1686
 
1716
1687
  So, if you want to advance to the next step, you must use `Continue(**value)` instead of `Success(type, **value)`. Otherwise, the step chain will be terminated.
1717
1688
 
1718
- Let's use a mix of `BCDD::Result::Context` features to see in action with this add-on:
1689
+ Let's use a mix of `BCDD::Context` features to see in action with this add-on:
1719
1690
 
1720
1691
  ```ruby
1721
1692
  module Division
1722
1693
  require 'logger'
1723
1694
 
1724
- extend self, BCDD::Result::Context::Expectations.mixin(
1695
+ extend self, BCDD::Context::Expectations.mixin(
1725
1696
  config: {
1726
1697
  addon: { continue: true },
1727
1698
  pattern_matching: { nil_as_valid_value_checking: true }
@@ -1771,35 +1742,193 @@ end
1771
1742
 
1772
1743
  Division.call(14, 2)
1773
1744
  # I, [2023-10-27T02:01:05.812388 #77823] INFO -- : The division result is 7
1774
- #<BCDD::Result::Context::Success type=:division_completed value={:number=>7}>
1745
+ #<BCDD::Context::Success type=:division_completed value={:number=>7}>
1775
1746
 
1776
1747
  Division.call(0, 2)
1777
- ##<BCDD::Result::Context::Success type=:division_completed value={:number=>0}>
1748
+ ##<BCDD::Context::Success type=:division_completed value={:number=>0}>
1778
1749
 
1779
1750
  Division.call('14', 2)
1780
- #<BCDD::Result::Context::Failure type=:invalid_arg value={:message=>"arg1 must be numeric"}>
1751
+ #<BCDD::Context::Failure type=:invalid_arg value={:message=>"arg1 must be numeric"}>
1781
1752
 
1782
1753
  Division.call(14, '2')
1783
- #<BCDD::Result::Context::Failure type=:invalid_arg value={:message=>"arg2 must be numeric"}>
1754
+ #<BCDD::Context::Failure type=:invalid_arg value={:message=>"arg2 must be numeric"}>
1784
1755
 
1785
1756
  Division.call(14, 0)
1786
- #<BCDD::Result::Context::Failure type=:division_by_zero value={:message=>"arg2 must not be zero"}>
1757
+ #<BCDD::Context::Failure type=:division_by_zero value={:message=>"arg2 must not be zero"}>
1758
+ ```
1759
+
1760
+ <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1761
+
1762
+ ## Pattern Matching
1763
+
1764
+ The `BCDD::Result` and `BCDD::Context` also provides support to pattern matching.
1765
+
1766
+ ### `BCDD::Result`
1767
+
1768
+ In the further examples, I will use the `Divide` lambda to exemplify its usage.
1769
+
1770
+ ```ruby
1771
+ Divide = lambda do |arg1, arg2|
1772
+ arg1.is_a?(::Numeric) or return BCDD::Result::Failure(:invalid_arg, 'arg1 must be numeric')
1773
+ arg2.is_a?(::Numeric) or return BCDD::Result::Failure(:invalid_arg, 'arg2 must be numeric')
1774
+
1775
+ return BCDD::Result::Failure(:division_by_zero, 'arg2 must not be zero') if arg2.zero?
1776
+
1777
+ BCDD::Result::Success(:division_completed, arg1 / arg2)
1778
+ end
1779
+ ```
1780
+
1781
+ #### `Array`/`Find` patterns
1782
+
1783
+ ```ruby
1784
+ case Divide.call(4, 2)
1785
+ in BCDD::Failure[:invalid_arg, msg] then puts msg
1786
+ in BCDD::Failure[:division_by_zero, msg] then puts msg
1787
+ in BCDD::Success[:division_completed, num] then puts num
1788
+ end
1789
+
1790
+ # The code above will print: 2
1791
+
1792
+ case Divide.call(4, 0)
1793
+ in BCDD::Failure[:invalid_arg, msg] then puts msg
1794
+ in BCDD::Failure[:division_by_zero, msg] then puts msg
1795
+ in BCDD::Success[:division_completed, num] then puts num
1796
+ end
1797
+
1798
+ # The code above will print: arg2 must not be zero
1799
+ ```
1800
+
1801
+ <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1802
+
1803
+ #### `Hash` patterns
1804
+
1805
+ ```ruby
1806
+ case Divide.call(10, 2)
1807
+ in BCDD::Failure(type: :invalid_arg, value: msg) then puts msg
1808
+ in BCDD::Failure(type: :division_by_zero, value: msg) then puts msg
1809
+ in BCDD::Success(type: :division_completed, value: num) then puts num
1810
+ end
1811
+
1812
+ # The code above will print: 5
1813
+
1814
+ case Divide.call('10', 2)
1815
+ in BCDD::Failure(type: :invalid_arg, value: msg) then puts msg
1816
+ in BCDD::Failure(type: :division_by_zero, value: msg) then puts msg
1817
+ in BCDD::Success(type: :division_completed, value: num) then puts num
1818
+ end
1819
+
1820
+ # The code above will print: arg1 must be numeric
1821
+ ```
1822
+
1823
+ You can also use `BCDD::Result::Success` and `BCDD::Result::Failure` as patterns.
1824
+
1825
+ <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1826
+
1827
+
1828
+ ### `BCDD::Context`
1829
+
1830
+ In the further examples, I will use the `Divide` lambda to exemplify its usage.
1831
+
1832
+ ```ruby
1833
+ Divide = lambda do |arg1, arg2|
1834
+ arg1.is_a?(::Numeric) or return BCDD::Context::Failure(:invalid_arg, err: 'arg1 must be numeric')
1835
+ arg2.is_a?(::Numeric) or return BCDD::Context::Failure(:invalid_arg, err: 'arg2 must be numeric')
1836
+
1837
+ return BCDD::Context::Failure(:division_by_zero, err: 'arg2 must not be zero') if arg2.zero?
1838
+
1839
+ BCDD::Context::Success(:division_completed, num: arg1 / arg2)
1840
+ end
1841
+ ```
1842
+
1843
+ #### `Array`/`Find` patterns
1844
+
1845
+ ```ruby
1846
+ case Divide.call(4, 2)
1847
+ in BCDD::Failure[:invalid_arg, {msg:}] then puts msg
1848
+ in BCDD::Failure[:division_by_zero, {msg:}] then puts msg
1849
+ in BCDD::Success[:division_completed, {num:}] then puts num
1850
+ end
1851
+
1852
+ # The code above will print: 2
1853
+
1854
+ case Divide.call(4, 0)
1855
+ in BCDD::Failure[:invalid_arg, {msg:}] then puts msg
1856
+ in BCDD::Failure[:division_by_zero, {msg:}] then puts msg
1857
+ in BCDD::Success[:division_completed, {num:}] then puts num
1858
+ end
1859
+
1860
+ # The code above will print: arg2 must not be zero
1861
+ ```
1862
+
1863
+ <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1864
+
1865
+ #### `Hash` patterns
1866
+
1867
+ If you don't provide the keys :type and :value, the pattern will match the result value.
1868
+
1869
+ ```ruby
1870
+ case Divide.call(10, 2)
1871
+ in BCDD::Failure({msg:}) then puts msg
1872
+ in BCDD::Success({num:}) then puts num
1873
+ end
1874
+ ```
1875
+
1876
+ ```ruby
1877
+ case Divide.call(10, 2)
1878
+ in BCDD::Failure(type: :invalid_arg, value: {msg:}) then puts msg
1879
+ in BCDD::Failure(type: :division_by_zero, value: {msg:}) then puts msg
1880
+ in BCDD::Success(type: :division_completed, value: {num:}) then puts num
1881
+ end
1882
+
1883
+ # The code above will print: 5
1884
+
1885
+ case Divide.call('10', 2)
1886
+ in BCDD::Failure(type: :invalid_arg, value: {msg:}) then puts {msg:}
1887
+ in BCDD::Failure(type: :division_by_zero, value: {msg:}) then puts msg
1888
+ in BCDD::Success(type: :division_completed, value: {num:}) then puts num
1889
+ end
1890
+
1891
+ # The code above will print: arg1 must be numeric
1787
1892
  ```
1788
1893
 
1894
+ You can also use `BCDD::Context::Success` and `BCDD::Context::Failure` as patterns.
1895
+
1789
1896
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1790
1897
 
1791
- ## `BCDD::Result.transitions`
1898
+ ### How to pattern match without the concept of success and failure
1899
+
1900
+ You can use the classes `BCDD::Result` and `BCDD::Context` as patterns, and the pattern matching will work without the concept of success and failure.
1901
+
1902
+ ```ruby
1903
+ case Divide.call(10, 2)
1904
+ in BCDD::Context(:invalid_arg, {msg:}) then puts msg
1905
+ in BCDD::Context(:division_by_zero, {msg:}) then puts msg
1906
+ in BCDD::Context(:division_completed, {num:}) then puts num
1907
+ end
1908
+
1909
+ case Divide.call(10, 2)
1910
+ in BCDD::Result(:invalid_arg, msg) then puts msg
1911
+ in BCDD::Result(:division_by_zero, msg) then puts msg
1912
+ in BCDD::Result(:division_completed, num) then puts num
1913
+ end
1914
+ ```
1792
1915
 
1793
- Use `BCDD::Result.transitions(&block)` to track all transitions in the same or between different operations (it works with `BCDD::Result` and `BCDD::Result::Context`). When there is a nesting of transition blocks, this mechanism will be able to correlate parent and child blocks and present the duration of all operations in milliseconds.
1916
+ The `BCDD::Result` will also work with the `BCDD::Context`, but the opposite won't.
1794
1917
 
1795
- When you wrap the creation of the result with `BCDD::Result.transitions`, the final result will expose all the transition records through the `BCDD::Result#transitions` method.
1918
+ <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1919
+
1920
+ ## `BCDD::Result.event_logs`
1921
+
1922
+ Use `BCDD::Result.event_logs(&block)` to track all the results produced in the same or between different operations (it works with `BCDD::Result` and `BCDD::Context`). When there is a nesting of `event_logs` blocks, this mechanism will be able to correlate parent and child blocks and present the duration of all operations in milliseconds.
1923
+
1924
+ When you wrap the creation of the result with `BCDD::Result.event_logs`, the final one will expose all the event log records through the `BCDD::Result#event_logs` method.
1796
1925
 
1797
1926
  ```ruby
1798
1927
  class Division
1799
1928
  include BCDD::Result.mixin(config: { addon: { continue: true } })
1800
1929
 
1801
1930
  def call(arg1, arg2)
1802
- BCDD::Result.transitions(name: 'Division', desc: 'divide two numbers') do
1931
+ BCDD::Result.event_logs(name: 'Division', desc: 'divide two numbers') do
1803
1932
  Given([arg1, arg2])
1804
1933
  .and_then(:require_numbers)
1805
1934
  .and_then(:check_for_zeros)
@@ -1835,7 +1964,7 @@ module SumDivisionsByTwo
1835
1964
  extend self, BCDD::Result.mixin
1836
1965
 
1837
1966
  def call(*numbers)
1838
- BCDD::Result.transitions(name: 'SumDivisionsByTwo') do
1967
+ BCDD::Result.event_logs(name: 'SumDivisionsByTwo') do
1839
1968
  divisions = numbers.map { |number| Division.new.call(number, 2) }
1840
1969
 
1841
1970
  if divisions.any?(&:failure?)
@@ -1854,14 +1983,17 @@ Let's see the result of the `SumDivisionsByTwo` call:
1854
1983
  result = SumDivisionsByTwo.call(20, 10)
1855
1984
  # => #<BCDD::Result::Success type=:sum value=15>
1856
1985
 
1857
- result.transitions
1986
+ result.event_logs
1858
1987
  {
1859
1988
  :version => 1,
1860
1989
  :metadata => {
1861
1990
  :duration => 0, # milliseconds
1862
1991
  :trace_id => nil, # can be set through configuration
1863
- :ids_tree => [0, [[1, []], [2, []]]],
1864
- :ids_matrix => {0 => [0, 0], 1 => [1, 1], 2 => [2, 1]}
1992
+ :ids => {
1993
+ :tree => [0, [[1, []], [2, []]]],
1994
+ :matrix => { 0 => [0, 0], 1 => [1, 1], 2 => [2, 1]},
1995
+ :level_parent => { 0 => [0, 0], 1 => [1, 0], 2 => [1, 0]}
1996
+ }
1865
1997
  },
1866
1998
  :records=> [
1867
1999
  {
@@ -1942,18 +2074,21 @@ result.transitions
1942
2074
 
1943
2075
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1944
2076
 
1945
- ### `ids_tree` *versus* `ids_matrix`
1946
-
1947
- The `:ids_matrix`. It is a simplification of the `:ids_tree` property (a graph/tree representation of the transitions ids).
2077
+ ### `metadata: {ids:}`
1948
2078
 
1949
- The matrix rows are the direct transitions from the root transition block, and the columns are the transitions nested from the direct transitions.
2079
+ The `:ids` metadata property is a hash with three properties:
2080
+ - `:tree`, a graph/tree representation of the id of each `event_logs` block.
2081
+ - `:level_parent`, a hash with the level (depth) of each block and its parent id.
2082
+ - `:matrix`, a matrix representation of the event logs ids. It is a simplification of the `:tree` property.
1950
2083
 
1951
- Use these data structures to build your own visualization of the transitions.
2084
+ Use these data structures to build your own visualization.
1952
2085
 
1953
- > Check out [Transitions Listener example](examples/single_listener/lib/single_transitions_listener.rb) to see how a listener can be used to build a visualization of the transitions, using these properties.
2086
+ > Check out [Event Logs Listener example](examples/single_listener/lib/single_event_logs_listener.rb) to see how a listener can be used to build a STDOUT visualization, using these properties.
1954
2087
 
1955
2088
  ```ruby
1956
- # ids_tree #
2089
+ # tree:
2090
+ # A graph representation (array of arrays) of the each event logs block id.
2091
+ #
1957
2092
  0 # [0, [
1958
2093
  |- 1 # [1, [[2, []]]],
1959
2094
  | |- 2 # [3, []],
@@ -1964,7 +2099,24 @@ Use these data structures to build your own visualization of the transitions.
1964
2099
  | |- 7 # [8, []]
1965
2100
  |- 8 # ]]
1966
2101
 
1967
- # ids_matrix # {
2102
+ # level_parent:
2103
+ # The event logs ids are the keys, and the level (depth) and parent id the values.
2104
+ # {
2105
+ 0 # 0 => [0, 0],
2106
+ |- 1 # 1 => [1, 0],
2107
+ | |- 2 # 2 => [2, 1],
2108
+ |- 3 # 3 => [1, 0],
2109
+ |- 4 # 4 => [1, 0],
2110
+ | |- 5 # 5 => [2, 4],
2111
+ | |- 6 # 6 => [2, 4],
2112
+ | |- 7 # 7 => [3, 6],
2113
+ |- 8 # 8 => [1, 0]
2114
+ # }
2115
+
2116
+ # matrix:
2117
+ # The rows are the direct blocks from the root block,
2118
+ # and the columns are the nested blocks from the direct ones.
2119
+ # {
1968
2120
  0 | 1 | 2 | 3 | 4 # 0 => [0, 0],
1969
2121
  - | - | - | - | - # 1 => [1, 1],
1970
2122
  0 | | | | # 2 => [1, 2],
@@ -1983,78 +2135,84 @@ Use these data structures to build your own visualization of the transitions.
1983
2135
 
1984
2136
  #### Turning on/off
1985
2137
 
1986
- You can use `BCDD::Result.config.feature.disable!(:transitions)` and `BCDD::Result.config.feature.enable!(:transitions)` to turn on/off the `BCDD::Result.transitions` feature.
2138
+ You can use `BCDD::Result.config.feature.disable!(event_logs)` and `BCDD::Result.config.feature.enable!(event_logs)` to turn on/off the `BCDD::Result.event_logs` feature.
1987
2139
 
1988
2140
  ```ruby
1989
2141
  BCDD::Result.configuration do |config|
1990
- config.feature.disable!(:transitions)
2142
+ config.feature.disable!(event_logs)
1991
2143
  end
1992
2144
 
1993
2145
  result = SumDivisionsByTwo.call(20, 10)
1994
2146
  # => #<BCDD::Result::Success type=:sum value=15>
1995
2147
 
1996
- result.transitions
1997
-
1998
- {:version=>1, :records=>[], :metadata=>{:duration=>0, :ids_tree=>[]}}
2148
+ result.event_logs
2149
+ {
2150
+ :version=>1,
2151
+ :records=>[],
2152
+ :metadata=>{
2153
+ :duration=>0,
2154
+ :ids=>{:tree=>[], :matrix=>{}, :level_parent=>{}}, :trace_id=>nil
2155
+ }
2156
+ }
1999
2157
  ```
2000
2158
 
2001
2159
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
2002
2160
 
2003
2161
  #### Setting a `trace_id` fetcher
2004
2162
 
2005
- You can define a lambda (arity 0) to fetch the trace_id. This lambda will be called before the first transition and will be used to set the `:trace_id` in the `:metadata` property.
2163
+ You can define a lambda (arity 0) to fetch the trace_id. This lambda will be called before the first event logs block and will be used to set the `:trace_id` in the `:metadata` property.
2006
2164
 
2007
2165
  Use to correlate different or the same operation (executed multiple times).
2008
2166
 
2009
2167
  ```ruby
2010
- BCDD::Result.config.transitions.trace_id = -> { Thread.current[:bcdd_result_transitions_trace_id] }
2168
+ BCDD::Result.config.event_logs.trace_id = -> { Thread.current[:bcdd_result_event_logs_trace_id] }
2011
2169
  ```
2012
2170
 
2013
2171
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
2014
2172
 
2015
2173
  #### Setting a `listener`
2016
2174
 
2017
- You can define a listener to be called during the result transitions tracking (check out [this example](examples/single_listener/lib/single_transitions_listener.rb)). It must be a class that includes `BCDD::Result::Transitions::Listener`.
2175
+ You can define a listener to be called during the event logs tracking (check out [this example](examples/single_listener/lib/single_event_logs_listener.rb)). It must be a class that includes `BCDD::Result::EventLogs::Listener`.
2018
2176
 
2019
- Use it to build your additional logic on top of the transitions tracking. Examples:
2020
- - Log the transitions.
2021
- - Perform a trace of the transitions.
2022
- - Instrument the transitions (measure/report).
2023
- - Build a visualization of the transitions (Diagrams, using the `records` + `:ids_tree` and `:ids_matrix` properties).
2177
+ Use it to build your additional logic on top of the tracking. Examples:
2178
+ - Log the event logs.
2179
+ - Perform the tracing.
2180
+ - Instrument the event logs (measure/report).
2181
+ - Build a visualization (Diagrams, using the `records:` + `metadata: {ids:}` properties).
2024
2182
 
2025
- After implementing your listener, you can set it to the `BCDD::Result.config.transitions.listener=`:
2183
+ After implementing your listener, you can set it to the `BCDD::Result.config.event_logs.listener=`:
2026
2184
 
2027
2185
  ```ruby
2028
- BCDD::Result.config.transitions.listener = MyTransitionsListener
2186
+ BCDD::Result.config.event_logs.listener = MyEventLogsListener
2029
2187
  ```
2030
2188
 
2031
2189
  See the example below to understand how to implement one:
2032
2190
 
2033
2191
  ```ruby
2034
- class MyTransitionsListener
2035
- include BCDD::Result::Transitions::Listener
2192
+ class MyEventLogsListener
2193
+ include BCDD::Result::EventLogs::Listener
2036
2194
 
2037
- # A listener will be initialized before the first transition, and it is discarded after the last one.
2195
+ # A listener will be initialized before the first event logs block, and it is discarded after the last one.
2038
2196
  def initialize
2039
2197
  end
2040
2198
 
2041
- # This method will be called before each transition block.
2042
- # The parent transition block will be called first in the case of nested transition blocks.
2199
+ # This method will be called before each event logs block.
2200
+ # The parent block will be called first in the case of nested ones.
2043
2201
  #
2044
2202
  # @param scope: {:id=>1, :name=>"SomeOperation", :desc=>"Optional description"}
2045
2203
  def on_start(scope:)
2046
2204
  end
2047
2205
 
2048
- # This method will wrap all the transitions in the same block.
2049
- # It can be used to perform an instrumentation (measure/report) of the transitions.
2206
+ # This method will wrap all the event logs in the same block.
2207
+ # It can be used to perform an instrumentation (measure/report).
2050
2208
  #
2051
2209
  # @param scope: {:id=>1, :name=>"SomeOperation", :desc=>"Optional description"}
2052
- def around_transitions(scope:)
2210
+ def around_event_logs(scope:)
2053
2211
  yield
2054
2212
  end
2055
2213
 
2056
2214
  # This method will wrap each and_then call.
2057
- # It can be used to perform an instrumentation (measure/report) of the and_then calls.
2215
+ # It can be used to perform an instrumentation of the and_then calls.
2058
2216
  #
2059
2217
  # @param scope: {:id=>1, :name=>"SomeOperation", :desc=>"Optional description"}
2060
2218
  # @param and_then:
@@ -2078,29 +2236,32 @@ class MyTransitionsListener
2078
2236
  def on_record(record:)
2079
2237
  end
2080
2238
 
2081
- # This method will be called at the end of the transitions tracking.
2239
+ # This method will be called at the end of the event logs tracking.
2082
2240
  #
2083
- # @param transitions:
2241
+ # @param event_logs:
2084
2242
  # {
2085
2243
  # :version => 1,
2086
2244
  # :metadata => {
2087
2245
  # :duration => 0,
2088
2246
  # :trace_id => nil,
2089
- # :ids_tree => [0, [[1, []], [2, []]]],
2090
- # :ids_matrix => {0 => [0, 0], 1 => [1, 1], 2 => [2, 1]}
2247
+ # :ids => {
2248
+ # :tree => [0, [[1, []], [2, []]]],
2249
+ # :matrix => { 0 => [0, 0], 1 => [1, 1], 2 => [2, 1]},
2250
+ # :level_parent => { 0 => [0, 0], 1 => [1, 0], 2 => [1, 0]}
2251
+ # }
2091
2252
  # },
2092
2253
  # :records => [
2093
2254
  # # ...
2094
2255
  # ]
2095
2256
  # }
2096
- def on_finish(transitions:)
2257
+ def on_finish(event_logs:)
2097
2258
  end
2098
2259
 
2099
- # This method will be called when an exception is raised during the transitions tracking.
2260
+ # This method will be called when an exception is raised during the event logs tracking.
2100
2261
  #
2101
2262
  # @param exception: Exception
2102
- # @param transitions: Hash
2103
- def before_interruption(exception:, transitions:)
2263
+ # @param event_logs: Hash
2264
+ def before_interruption(exception:, event_logs:)
2104
2265
  end
2105
2266
  end
2106
2267
  ```
@@ -2109,15 +2270,15 @@ end
2109
2270
 
2110
2271
  #### Setting multiple `listeners`
2111
2272
 
2112
- You can use `BCDD::Result::Transitions::Listeners[]` to creates a listener of listeners (check out [this example](examples/multiple_listeners/Rakefile)), which will be called in the order they were added.
2273
+ You can use `BCDD::Result::EventLogs::Listeners[]` to creates a listener of listeners (check out [this example](examples/multiple_listeners/Rakefile)), which will be called in the order they were added.
2113
2274
 
2114
- **Attention:** It only allows one listener to handle `around_and_then` and another `around_transitions` events.
2275
+ **Attention:** It only allows one listener to handle `around_and_then` and another `around_event_logs` records.
2115
2276
 
2116
- > The example below defines different listeners to handle `around_and_then` and `around_transitions,` but it is also possible to define a listener to handle both.
2277
+ > The example below defines different listeners to handle `around_and_then` and `around_event_logs,` but it is also possible to define a listener to handle both.
2117
2278
 
2118
2279
  ```ruby
2119
2280
  class AroundAndThenListener
2120
- include BCDD::Result::Transitions::Listener
2281
+ include BCDD::Result::EventLogs::Listener
2121
2282
 
2122
2283
  # It must be a static/singleton method.
2123
2284
  def self.around_and_then?
@@ -2129,21 +2290,21 @@ class AroundAndThenListener
2129
2290
  end
2130
2291
  end
2131
2292
 
2132
- class AroundTransitionsListener
2133
- include BCDD::Result::Transitions::Listener
2293
+ class AroundEventLogsListener
2294
+ include BCDD::Result::EventLogs::Listener
2134
2295
 
2135
2296
  # It must be a static/singleton method.
2136
- def self.around_transitions?
2297
+ def self.around_event_logs?
2137
2298
  true
2138
2299
  end
2139
2300
 
2140
- def around_transitions(scope:)
2301
+ def around_event_logs(scope:)
2141
2302
  #...
2142
2303
  end
2143
2304
  end
2144
2305
 
2145
- class MyTransitionsListener
2146
- include BCDD::Result::Transitions::Listener
2306
+ class MyEventLogsListener
2307
+ include BCDD::Result::EventLogs::Listener
2147
2308
  end
2148
2309
  ```
2149
2310
 
@@ -2151,20 +2312,20 @@ How to use it:
2151
2312
 
2152
2313
  ```ruby
2153
2314
  # The listeners will be called in the order they were added.
2154
- BCDD::Result.config.transitions.listener = BCDD::Result::Transitions::Listeners[
2155
- MyTransitionsListener,
2315
+ BCDD::Result.config.event_logs.listener = BCDD::Result::EventLogs::Listeners[
2316
+ MyEventLogsListener,
2156
2317
  AroundAndThenListener,
2157
- AroundTransitionsListener
2318
+ AroundEventLogsListener
2158
2319
  ]
2159
2320
  ```
2160
2321
 
2161
- > Check out [this example](examples/multiple_listeners) to see a listener to print the transitions and another to store them in the database.
2322
+ > Check out [this example](examples/multiple_listeners) to see a listener to print the event logs and another to store them in the database.
2162
2323
 
2163
2324
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
2164
2325
 
2165
2326
  ## `BCDD::Result.configuration`
2166
2327
 
2167
- The `BCDD::Result.configuration` allows you to configure default behaviors for `BCDD::Result` and `BCDD::Result::Context` through a configuration block. After using it, the configuration is frozen, ensuring the expected behaviors for your application.
2328
+ The `BCDD::Result.configuration` allows you to configure default behaviors for `BCDD::Result` and `BCDD::Context` through a configuration block. After using it, the configuration is frozen, ensuring the expected behaviors for your application.
2168
2329
 
2169
2330
  > Note: You can use `BCDD::Result.configuration(freeze: false) {}` to avoid the freezing. This can be useful in tests. Please be sure to use it with caution.
2170
2331
 
@@ -2186,13 +2347,13 @@ Let's see what each configuration in the example above does:
2186
2347
 
2187
2348
  ### `config.addon.enable!(:given, :continue)` <!-- omit in toc -->
2188
2349
 
2189
- This configuration enables the `Continue()` method for `BCDD::Result.mixin`, `BCDD::Result::Context.mixin`, `BCDD::Result::Expectation.mixin`, and `BCDD::Result::Context::Expectation.mixin`. Link to documentations: [(1)](#add-ons) [(2)](#mixin-add-ons).
2350
+ This configuration enables the `Continue()` method for `BCDD::Result.mixin`, `BCDD::Context.mixin`, `BCDD::Result::Expectation.mixin`, and `BCDD::Context::Expectation.mixin`. Link to documentations: [(1)](#add-ons) [(2)](#mixin-add-ons).
2190
2351
 
2191
2352
  It is also enabling the `Given()` which is already enabled by default. Link to documentation: [(1)](#add-ons) [(2)](#mixin-add-ons).
2192
2353
 
2193
2354
  ### `config.constant_alias.enable!('Result', 'BCDD::Context')` <!-- omit in toc -->
2194
2355
 
2195
- This configuration make `Result` a constant alias for `BCDD::Result`, and `BCDD::Context` a constant alias for `BCDD::Result::Context`.
2356
+ This configuration make `Result` a constant alias for `BCDD::Result`, and `BCDD::Context` a constant alias for `BCDD::Context`.
2196
2357
 
2197
2358
  Link to documentations:
2198
2359
  - [Result alias](#bcddresult-versus-result)
@@ -2200,11 +2361,11 @@ Link to documentations:
2200
2361
 
2201
2362
  ### `config.pattern_matching.disable!(:nil_as_valid_value_checking)` <!-- omit in toc -->
2202
2363
 
2203
- This configuration disables the `nil_as_valid_value_checking` for `BCDD::Result` and `BCDD::Result::Context`. Link to [documentation](#pattern-matching-support).
2364
+ This configuration disables the `nil_as_valid_value_checking` for `BCDD::Result` and `BCDD::Context`. Link to [documentation](#pattern-matching-support).
2204
2365
 
2205
2366
  ### `config.feature.disable!(:expectations)` <!-- omit in toc -->
2206
2367
 
2207
- This configuration turns off the expectations for `BCDD::Result` and `BCDD::Result::Context`. The expectations are helpful in development and test environments, but they can be disabled in production environments for performance gain.
2368
+ This configuration turns off the expectations for `BCDD::Result` and `BCDD::Context`. The expectations are helpful in development and test environments, but they can be disabled in production environments for performance gain.
2208
2369
 
2209
2370
  PS: I'm using `::Rails.env.production?` to check the environment, but you can use any logic you want.
2210
2371
 
@@ -2226,18 +2387,18 @@ BCDD::Result.config.addon.options
2226
2387
  # :enabled=>false,
2227
2388
  # :affects=>[
2228
2389
  # "BCDD::Result.mixin",
2229
- # "BCDD::Result::Context.mixin",
2390
+ # "BCDD::Context.mixin",
2230
2391
  # "BCDD::Result::Expectations.mixin",
2231
- # "BCDD::Result::Context::Expectations.mixin"
2392
+ # "BCDD::Context::Expectations.mixin"
2232
2393
  # ]
2233
2394
  # },
2234
2395
  # :given=>{
2235
2396
  # :enabled=>true,
2236
2397
  # :affects=>[
2237
2398
  # "BCDD::Result.mixin",
2238
- # "BCDD::Result::Context.mixin",
2399
+ # "BCDD::Context.mixin",
2239
2400
  # "BCDD::Result::Expectations.mixin",
2240
- # "BCDD::Result::Context::Expectations.mixin"
2401
+ # "BCDD::Context::Expectations.mixin"
2241
2402
  # ]
2242
2403
  # }
2243
2404
  # }
@@ -2269,7 +2430,7 @@ BCDD::Result.config.pattern_matching.options
2269
2430
  # :enabled=>false,
2270
2431
  # :affects=>[
2271
2432
  # "BCDD::Result::Expectations,
2272
- # "BCDD::Result::Context::Expectations"
2433
+ # "BCDD::Context::Expectations"
2273
2434
  # ]
2274
2435
  # }
2275
2436
  # }
@@ -2286,21 +2447,21 @@ BCDD::Result.config.feature.options
2286
2447
  # :enabled=>true,
2287
2448
  # :affects=>[
2288
2449
  # "BCDD::Result::Expectations,
2289
- # "BCDD::Result::Context::Expectations"
2450
+ # "BCDD::Context::Expectations"
2290
2451
  # ]
2291
2452
  # },
2292
- # :transitions=>{
2453
+ # event_logs=>{
2293
2454
  # :enabled=>true,
2294
2455
  # :affects=>[
2295
2456
  # "BCDD::Result",
2296
- # "BCDD::Result::Context"
2457
+ # "BCDD::Context"
2297
2458
  # ]
2298
2459
  # },
2299
2460
  # :and_then!=>{
2300
2461
  # :enabled=>false,
2301
2462
  # :affects=>[
2302
2463
  # "BCDD::Result",
2303
- # "BCDD::Result::Context"
2464
+ # "BCDD::Context"
2304
2465
  # ]
2305
2466
  # },
2306
2467
  # }
@@ -2343,7 +2504,7 @@ class PlaceOrder < Micro::Case
2343
2504
  end
2344
2505
  ```
2345
2506
 
2346
- To facilitate migration for users accustomed to the above approaches, `bcdd-result` includes the `BCDD::Result#and_then!`/`BCDD::Result::Context#and_then!` methods, which will invoke the method `call` of the given operation and expect it to return a `BCDD::Result`/`BCDD::Result::Context` object.
2507
+ To facilitate migration for users accustomed to the above approaches, `bcdd-result` includes the `BCDD::Result#and_then!`/`BCDD::Context#and_then!` methods, which will invoke the method `call` of the given operation and expect it to return a `BCDD::Result`/`BCDD::Context` object.
2347
2508
 
2348
2509
  ```ruby
2349
2510
  BCDD::Result.configure do |config|
@@ -2351,7 +2512,7 @@ BCDD::Result.configure do |config|
2351
2512
  end
2352
2513
 
2353
2514
  class PlaceOrder
2354
- include BCDD::Result::Context.mixin
2515
+ include BCDD::Context.mixin
2355
2516
 
2356
2517
  def call(**input)
2357
2518
  Given(input)
@@ -2383,11 +2544,11 @@ class PlaceOrder
2383
2544
  end
2384
2545
  ```
2385
2546
 
2386
- **In BCDD::Result::Context**
2547
+ **In BCDD::Context**
2387
2548
 
2388
2549
  ```ruby
2389
2550
  class PlaceOrder
2390
- include BCDD::Result::Context.mixin
2551
+ include BCDD::Context.mixin
2391
2552
 
2392
2553
  def call(logger:, **input)
2393
2554
  Given(input)
@@ -2441,7 +2602,7 @@ Attention: to ensure the correct behavior, do not mix `#and_then` and `#and_then
2441
2602
 
2442
2603
  #### Analysis: Why is `#and_then` the antidote/standard?
2443
2604
 
2444
- The `BCDD::Result#and_then`/`BCDD::Result::Context#and_then` methods diverge from the above approach by requiring explicit invocation and mapping of the outcomes at each process step. This approach has the following advantages:
2605
+ The `BCDD::Result#and_then`/`BCDD::Context#and_then` methods diverge from the above approach by requiring explicit invocation and mapping of the outcomes at each process step. This approach has the following advantages:
2445
2606
 
2446
2607
  - **Clarity:** The input/output relationship between the steps is apparent and highly understandable.
2447
2608
 
@@ -2451,7 +2612,7 @@ See this example to understand what your code should look like:
2451
2612
 
2452
2613
  ```ruby
2453
2614
  class PlaceOrder
2454
- include BCDD::Result::Context.mixin(config: { addon: { continue: true } })
2615
+ include BCDD::Context.mixin(config: { addon: { continue: true } })
2455
2616
 
2456
2617
  def call(**input)
2457
2618
  Given(input)