bcdd-result 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bf2a03ac7efd3e75e03b2f5617518cb07f40e03cc970c612f3d4dfcdad153ad
4
- data.tar.gz: 2717e6e600101401f420164aed020689e9c07dd7f7296c78ec5290562620ca3c
3
+ metadata.gz: c0043be8de0b26bac0d803f067537fbc65e4a54f3a38a2644c01bd987d87c7b5
4
+ data.tar.gz: f152ac78abb8847721f2b2ec3c3fd1db66016c421f5348f038a79501a86f761a
5
5
  SHA512:
6
- metadata.gz: c1761571f7d0c0a6fd4601a9f8a4c8c18688085226cd061057f95c93737da80ac58e0a99a3803a0e0f93aa5040530975d9b16a7b54df79487ca625fd67d405d6
7
- data.tar.gz: 4b22f37d2282de4c0a6e3781e86c9c63457efa83a7d5dc07db4288b9fe19c5b3868cd13a34a1cfc515776cf466e2095bde9d10503f87b8f546ceab9408ef9617
6
+ metadata.gz: 17abccc11ad3c7ccd2cedc6f9634659decee457e08ef1c8dfb13d59d2afc7390fdeb6fc1d48749362d691815c41b789197d2bf79b5f57f9e7e07ad770ddbb304
7
+ data.tar.gz: 2e0b67fbc99ef2a3a8187a2d42212e8cbadca22a2c2625c3be8e7bbfb5d2b92689b9a27b7592a295863e89437e912d34cb8f6e5a2e77e9c0afdbcbf7c4591bd6
data/CHANGELOG.md CHANGED
@@ -1,38 +1,55 @@
1
1
  - [\[Unreleased\]](#unreleased)
2
- - [\[0.10.0\] - 2023-12-31](#0100---2023-12-31)
2
+ - [\[0.11.0\] - 2024-01-02](#0110---2024-01-02)
3
3
  - [Added](#added)
4
- - [\[0.9.1\] - 2023-12-12](#091---2023-12-12)
5
4
  - [Changed](#changed)
6
- - [Fixed](#fixed)
7
- - [\[0.9.0\] - 2023-12-12](#090---2023-12-12)
5
+ - [\[0.10.0\] - 2023-12-31](#0100---2023-12-31)
8
6
  - [Added](#added-1)
7
+ - [\[0.9.1\] - 2023-12-12](#091---2023-12-12)
9
8
  - [Changed](#changed-1)
10
- - [\[0.8.0\] - 2023-12-11](#080---2023-12-11)
9
+ - [Fixed](#fixed)
10
+ - [\[0.9.0\] - 2023-12-12](#090---2023-12-12)
11
11
  - [Added](#added-2)
12
12
  - [Changed](#changed-2)
13
- - [Removed](#removed)
14
- - [\[0.7.0\] - 2023-10-27](#070---2023-10-27)
13
+ - [\[0.8.0\] - 2023-12-11](#080---2023-12-11)
15
14
  - [Added](#added-3)
16
15
  - [Changed](#changed-3)
17
- - [\[0.6.0\] - 2023-10-11](#060---2023-10-11)
16
+ - [Removed](#removed)
17
+ - [\[0.7.0\] - 2023-10-27](#070---2023-10-27)
18
18
  - [Added](#added-4)
19
19
  - [Changed](#changed-4)
20
- - [\[0.5.0\] - 2023-10-09](#050---2023-10-09)
20
+ - [\[0.6.0\] - 2023-10-11](#060---2023-10-11)
21
21
  - [Added](#added-5)
22
- - [\[0.4.0\] - 2023-09-28](#040---2023-09-28)
23
- - [Added](#added-6)
24
22
  - [Changed](#changed-5)
23
+ - [\[0.5.0\] - 2023-10-09](#050---2023-10-09)
24
+ - [Added](#added-6)
25
+ - [\[0.4.0\] - 2023-09-28](#040---2023-09-28)
26
+ - [Added](#added-7)
27
+ - [Changed](#changed-6)
25
28
  - [Removed](#removed-1)
26
29
  - [\[0.3.0\] - 2023-09-26](#030---2023-09-26)
27
- - [Added](#added-7)
28
- - [\[0.2.0\] - 2023-09-26](#020---2023-09-26)
29
30
  - [Added](#added-8)
31
+ - [\[0.2.0\] - 2023-09-26](#020---2023-09-26)
32
+ - [Added](#added-9)
30
33
  - [Removed](#removed-2)
31
34
  - [\[0.1.0\] - 2023-09-25](#010---2023-09-25)
32
- - [Added](#added-9)
35
+ - [Added](#added-10)
33
36
 
34
37
  ## [Unreleased]
35
38
 
39
+ ## [0.11.0] - 2024-01-02
40
+
41
+ ### Added
42
+
43
+ - Add the `Given()` addon to produce a `Success(:given, value)` result. As the `Continue()` addon, it is ignored by the expectations. Use it to add a value to the result chain and invoke the next step (through `and_then`).
44
+
45
+ ### Changed
46
+
47
+ - **(BREAKING)** Rename halted concept to terminal. Failures are terminal by default, but you can make a success terminal by enabling the `:continue` addon.
48
+
49
+ - **(BREAKING)** Rename `BCDD::Result::Context::Success#and_expose` halted keyword argument to `terminal`.
50
+
51
+ - **(BREAKING)** Rename `BCDD::Result#halted?` to `BCDD::Result#terminal?`.
52
+
36
53
  ## [0.10.0] - 2023-12-31
37
54
 
38
55
  ### Added
@@ -45,7 +62,7 @@
45
62
 
46
63
  ### Changed
47
64
 
48
- - **(BREAKING)** Make `BCDD::Result::Context::Success#and_expose()` to produce a halted success by default. You can turn this off by passing `halted: false`.
65
+ - **(BREAKING)** Make `BCDD::Result::Context::Success#and_expose()` to produce a terminal success by default. You can turn this off by passing `halted: false`.
49
66
 
50
67
  ### Fixed
51
68
 
data/README.md CHANGED
@@ -73,7 +73,7 @@ Use it to enable the [Railway Oriented Programming](https://fsharpforfunandprofi
73
73
  - [`BCDD::Result.transitions`](#bcddresulttransitions)
74
74
  - [Configuration](#configuration)
75
75
  - [`BCDD::Result.configuration`](#bcddresultconfiguration)
76
- - [`config.addon.enable!(:continue)`](#configaddonenablecontinue)
76
+ - [`config.addon.enable!(:given, :continue)`](#configaddonenablegiven-continue)
77
77
  - [`config.constant_alias.enable!('Result', 'BCDD::Context')`](#configconstant_aliasenableresult-bcddcontext)
78
78
  - [`config.pattern_matching.disable!(:nil_as_valid_value_checking)`](#configpattern_matchingdisablenil_as_valid_value_checking)
79
79
  - [`config.feature.disable!(:expectations)`](#configfeaturedisableexpectations)
@@ -918,35 +918,48 @@ Divide.call(4, 2, logger: Logger.new(IO::NULL))
918
918
 
919
919
  The `BCDD::Result.mixin` also accepts the `config:` argument. It is a hash that will be used to define custom behaviors for the mixin.
920
920
 
921
+ **given**
922
+
923
+ This addon is enabled by default. It will create the `Given(value)` method. Use it to add a value to the result chain and invoke the next step (through `and_then`).
924
+
925
+ You can turn it off by passing `given: false` to the `config:` argument or using the `BCDD::Result.configuration`.
926
+
921
927
  **continue**
922
928
 
923
- This addon will create the `Continue(value)` method and change the `Success()` behavior to halt the step chain.
929
+ This addon will create the `Continue(value)` method and change the `Success()` behavior to terminate the step chain.
930
+
931
+ 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.
924
932
 
925
- 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 halted.
933
+ In this example below, the `validate_nonzero` will return a `Success(:division_completed, 0)` and terminate the chain if the first number is zero.
926
934
 
927
935
  ```ruby
928
936
  module Divide
929
937
  extend self, BCDD::Result.mixin(config: { addon: { continue: true } })
930
938
 
931
939
  def call(arg1, arg2)
932
- validate_numbers(arg1, arg2)
940
+ Given([arg1, arg2])
941
+ .and_then(:validate_numbers)
933
942
  .and_then(:validate_nonzero)
934
943
  .and_then(:divide)
935
944
  end
936
945
 
937
946
  private
938
947
 
939
- def validate_numbers(arg1, arg2)
940
- arg1.is_a?(::Numeric) or return Failure(:invalid_arg, 'arg1 must be numeric')
941
- arg2.is_a?(::Numeric) or return Failure(:invalid_arg, 'arg2 must be numeric')
948
+ def validate_numbers(numbers)
949
+ number1, number2 = numbers
942
950
 
943
- Continue([arg1, arg2])
951
+ number1.is_a?(::Numeric) or return Failure(:invalid_arg, 'arg1 must be numeric')
952
+ number2.is_a?(::Numeric) or return Failure(:invalid_arg, 'arg2 must be numeric')
953
+
954
+ Continue(numbers)
944
955
  end
945
956
 
946
957
  def validate_nonzero(numbers)
947
- return Continue(numbers) unless numbers.last.zero?
958
+ return Failure(:division_by_zero, 'arg2 must not be zero') if numbers.last.zero?
948
959
 
949
- Failure(:division_by_zero, 'arg2 must not be zero')
960
+ return Success(:division_completed, 0) if numbers.first.zero?
961
+
962
+ Continue(numbers)
950
963
  end
951
964
 
952
965
  def divide((number1, number2))
@@ -1571,7 +1584,7 @@ Divide.new.call(10, 5)
1571
1584
  #<BCDD::Result::Context::Success type=:ok value={:number=>2, :number1=>10, :number2=>5}>
1572
1585
  ```
1573
1586
 
1574
- > PS: The `#and_expose` produces a halted 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 `halted: false` to `#and_expose`.
1587
+ > 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`.
1575
1588
 
1576
1589
  <p align="right"><a href="#-bcddresult">⬆️ &nbsp;back to top</a></p>
1577
1590
 
@@ -1678,16 +1691,24 @@ Divide::Result::Success(:division_completed, number: '2')
1678
1691
 
1679
1692
  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.
1680
1693
 
1681
- **Continue**
1694
+ **given**
1695
+
1696
+ This addon is enabled by default. It will create the `Given(*value)` method. Use it to add a value to the result chain and invoke the next step (through `and_then`).
1697
+
1698
+ You can turn it off by passing `given: false` to the `config:` argument or using the `BCDD::Result.configuration`.
1699
+
1700
+ 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.
1701
+
1702
+ **continue**
1682
1703
 
1683
- 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 halt the step chain.
1704
+ 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.
1684
1705
 
1685
- 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 halted.
1706
+ 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.
1686
1707
 
1687
1708
  Let's use a mix of `BCDD::Result::Context` features to see in action with this add-on:
1688
1709
 
1689
1710
  ```ruby
1690
- module Divide
1711
+ module Division
1691
1712
  require 'logger'
1692
1713
 
1693
1714
  extend self, BCDD::Result::Context::Expectations.mixin(
@@ -1705,25 +1726,28 @@ module Divide
1705
1726
  )
1706
1727
 
1707
1728
  def call(arg1, arg2, logger: ::Logger.new(STDOUT))
1708
- validate_numbers(arg1, arg2)
1709
- .and_then(:validate_nonzero)
1729
+ Given(number1: arg1, number2: arg2)
1730
+ .and_then(:require_numbers)
1731
+ .and_then(:check_for_zeros)
1710
1732
  .and_then(:divide, logger: logger)
1711
1733
  .and_expose(:division_completed, [:number])
1712
1734
  end
1713
1735
 
1714
1736
  private
1715
1737
 
1716
- def validate_numbers(arg1, arg2)
1717
- arg1.is_a?(::Numeric) or return Failure(:invalid_arg, message: 'arg1 must be numeric')
1718
- arg2.is_a?(::Numeric) or return Failure(:invalid_arg, message: 'arg2 must be numeric')
1738
+ def require_numbers(number1:, number2:)
1739
+ number1.is_a?(::Numeric) or return Failure(:invalid_arg, message: 'arg1 must be numeric')
1740
+ number2.is_a?(::Numeric) or return Failure(:invalid_arg, message: 'arg2 must be numeric')
1719
1741
 
1720
- Continue(number1: arg1, number2: arg2)
1742
+ Continue()
1721
1743
  end
1722
1744
 
1723
- def validate_nonzero(number2:, **)
1724
- return Continue() if number2.nonzero?
1745
+ def check_for_zeros(number1:, number2:)
1746
+ return Failure(:division_by_zero, message: 'arg2 must not be zero') if number2.zero?
1747
+
1748
+ return Success(:division_completed, number: 0) if number1.zero?
1725
1749
 
1726
- Failure(:division_by_zero, message: 'arg2 must not be zero')
1750
+ Continue()
1727
1751
  end
1728
1752
 
1729
1753
  def divide(number1:, number2:, logger:)
@@ -1735,23 +1759,26 @@ module Divide
1735
1759
  end
1736
1760
  end
1737
1761
 
1738
- Divide.call(14, 2)
1762
+ Division.call(14, 2)
1739
1763
  # I, [2023-10-27T02:01:05.812388 #77823] INFO -- : The division result is 7
1740
1764
  #<BCDD::Result::Context::Success type=:division_completed value={:number=>7}>
1741
1765
 
1742
- Divide.call('14', 2)
1766
+ Division.call(0, 2)
1767
+ ##<BCDD::Result::Context::Success type=:division_completed value={:number=>0}>
1768
+
1769
+ Division.call('14', 2)
1743
1770
  #<BCDD::Result::Context::Failure type=:invalid_arg value={:message=>"arg1 must be numeric"}>
1744
1771
 
1745
- Divide.call(14, '2')
1772
+ Division.call(14, '2')
1746
1773
  #<BCDD::Result::Context::Failure type=:invalid_arg value={:message=>"arg2 must be numeric"}>
1747
1774
 
1748
- Divide.call(14, 0)
1775
+ Division.call(14, 0)
1749
1776
  #<BCDD::Result::Context::Failure type=:division_by_zero value={:message=>"arg2 must not be zero"}>
1750
1777
  ```
1751
1778
 
1752
1779
  ### `BCDD::Result.transitions`
1753
1780
 
1754
- Use `BCDD::Result.transitions(&block)` to track all transitions in the same or between different operations. 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.
1781
+ 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.
1755
1782
 
1756
1783
  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.
1757
1784
 
@@ -1761,7 +1788,8 @@ class Division
1761
1788
 
1762
1789
  def call(arg1, arg2)
1763
1790
  BCDD::Result.transitions(name: 'Division', desc: 'divide two numbers') do
1764
- require_numbers(arg1, arg2)
1791
+ Given([arg1, arg2])
1792
+ .and_then(:require_numbers)
1765
1793
  .and_then(:check_for_zeros)
1766
1794
  .and_then(:divide)
1767
1795
  end
@@ -1771,7 +1799,7 @@ class Division
1771
1799
 
1772
1800
  ValidNumber = ->(arg) { arg.is_a?(Numeric) && arg != Float::NAN && arg != Float::INFINITY }
1773
1801
 
1774
- def require_numbers(arg1, arg2)
1802
+ def require_numbers((arg1, arg2))
1775
1803
  ValidNumber[arg1] or return Failure(:invalid_arg, 'arg1 must be a valid number')
1776
1804
  ValidNumber[arg2] or return Failure(:invalid_arg, 'arg2 must be a valid number')
1777
1805
 
@@ -1823,52 +1851,68 @@ result.transitions
1823
1851
  },
1824
1852
  :records => [
1825
1853
  {
1826
- :root => {:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1827
- :parent => {:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1828
- :current => {:id=>1, :name=>"Division", :desc=>"divide two numbers"},
1829
- :result => {:kind=>:success, :type=>:continued, :value=>[20, 2]},
1830
- :and_then => {},
1831
- :time => 2023-12-31 22:19:33.281619 UTC
1854
+ :root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1855
+ :parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1856
+ :current=>{:id=>1, :name=>"Division", :desc=>"divide two numbers"},
1857
+ :result=>{:kind=>:success, :type=>:given, :value=>[20, 2]},
1858
+ :and_then=>{},
1859
+ :time=>2024-01-02 03:35:11.248418 UTC
1832
1860
  },
1833
1861
  {
1834
1862
  :root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1835
1863
  :parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1836
1864
  :current=>{:id=>1, :name=>"Division", :desc=>"divide two numbers"},
1837
1865
  :result=>{:kind=>:success, :type=>:continued, :value=>[20, 2]},
1838
- :and_then=>{:type=>:method, :arg=>nil, :subject=>#<Division:0x0000000103e5f7c8>, :method_name=>:check_for_zeros},
1839
- :time=>2023-12-31 22:19:33.281693 UTC
1866
+ :and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106099028>, :method_name=>:require_numbers},
1867
+ :time=>2024-01-02 03:35:11.248558 UTC
1868
+ },
1869
+ {
1870
+ :root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1871
+ :parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1872
+ :current=>{:id=>1, :name=>"Division", :desc=>"divide two numbers"},
1873
+ :result=>{:kind=>:success, :type=>:continued, :value=>[20, 2]},
1874
+ :and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106099028>, :method_name=>:check_for_zeros},
1875
+ :time=>2024-01-02 03:35:11.248587 UTC
1840
1876
  },
1841
1877
  {
1842
1878
  :root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1843
1879
  :parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1844
1880
  :current=>{:id=>1, :name=>"Division", :desc=>"divide two numbers"},
1845
1881
  :result=>{:kind=>:success, :type=>:division_completed, :value=>10},
1846
- :and_then=>{:type=>:method, :arg=>nil, :subject=>#<Division:0x0000000103e5f7c8>, :method_name=>:divide},
1847
- :time=>2023-12-31 22:19:33.281715 UTC
1882
+ :and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106099028>, :method_name=>:divide},
1883
+ :time=>2024-01-02 03:35:11.248607 UTC
1848
1884
  },
1849
1885
  {
1850
1886
  :root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1851
1887
  :parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1852
1888
  :current=>{:id=>2, :name=>"Division", :desc=>"divide two numbers"},
1853
- :result=>{:kind=>:success, :type=>:continued, :value=>[10, 2]},
1889
+ :result=>{:kind=>:success, :type=>:given, :value=>[10, 2]},
1854
1890
  :and_then=>{},
1855
- :time=>2023-12-31 22:19:33.281747 UTC
1891
+ :time=>2024-01-02 03:35:11.24865 UTC
1856
1892
  },
1857
1893
  {
1858
1894
  :root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1859
1895
  :parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1860
1896
  :current=>{:id=>2, :name=>"Division", :desc=>"divide two numbers"},
1861
1897
  :result=>{:kind=>:success, :type=>:continued, :value=>[10, 2]},
1862
- :and_then=>{:type=>:method, :arg=>nil, :subject=>#<Division:0x0000000103e5f1b0>, :method_name=>:check_for_zeros},
1863
- :time=>2023-12-31 22:19:33.281755 UTC
1898
+ :and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106097ed0>, :method_name=>:require_numbers},
1899
+ :time=>2024-01-02 03:35:11.248661 UTC
1900
+ },
1901
+ {
1902
+ :root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1903
+ :parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1904
+ :current=>{:id=>2, :name=>"Division", :desc=>"divide two numbers"},
1905
+ :result=>{:kind=>:success, :type=>:continued, :value=>[10, 2]},
1906
+ :and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106097ed0>, :method_name=>:check_for_zeros},
1907
+ :time=>2024-01-02 03:35:11.248672 UTC
1864
1908
  },
1865
1909
  {
1866
1910
  :root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1867
1911
  :parent=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1868
1912
  :current=>{:id=>2, :name=>"Division", :desc=>"divide two numbers"},
1869
1913
  :result=>{:kind=>:success, :type=>:division_completed, :value=>5},
1870
- :and_then=>{:type=>:method, :arg=>nil, :subject=>#<Division:0x0000000103e5f1b0>, :method_name=>:divide},
1871
- :time=>2023-12-31 22:19:33.281763 UTC
1914
+ :and_then=>{:type=>:method, :arg=>nil, :subject=><Division:0x0000000106097ed0>, :method_name=>:divide},
1915
+ :time=>2024-01-02 03:35:11.248682 UTC
1872
1916
  },
1873
1917
  {
1874
1918
  :root=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
@@ -1876,7 +1920,7 @@ result.transitions
1876
1920
  :current=>{:id=>0, :name=>"SumDivisionsByTwo", :desc=>nil},
1877
1921
  :result=>{:kind=>:success, :type=>:sum, :value=>15},
1878
1922
  :and_then=>{},
1879
- :time=>2023-12-31 22:19:33.281784 UTC
1923
+ :time=>2024-01-02 03:35:11.248721 UTC
1880
1924
  }
1881
1925
  ]
1882
1926
  }
@@ -1909,7 +1953,7 @@ The `BCDD::Result.configuration` allows you to configure default behaviors for `
1909
1953
 
1910
1954
  ```ruby
1911
1955
  BCDD::Result.configuration do |config|
1912
- config.addon.enable!(:continue)
1956
+ config.addon.enable!(:given, :continue)
1913
1957
 
1914
1958
  config.constant_alias.enable!('Result', 'BCDD::Context')
1915
1959
 
@@ -1923,9 +1967,11 @@ Use `disable!` to disable a feature and `enable!` to enable it.
1923
1967
 
1924
1968
  Let's see what each configuration in the example above does:
1925
1969
 
1926
- #### `config.addon.enable!(:continue)`
1970
+ #### `config.addon.enable!(:given, :continue)`
1971
+
1972
+ 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).
1927
1973
 
1928
- This configuration enables the `Continue()` method for `BCDD::Result`, `BCDD::Result::Context`, `BCDD::Result::Expectation`, and `BCDD::Result::Context::Expectation`. Link to documentations: [(1)](#add-ons) [(2)](#mixin-add-ons).
1974
+ It is also enabling the `Given()` which is already enabled by default. Link to documentation: [(1)](#add-ons) [(2)](#mixin-add-ons).
1929
1975
 
1930
1976
  #### `config.constant_alias.enable!('Result', 'BCDD::Context')`
1931
1977
 
@@ -1955,16 +2001,26 @@ The `BCDD::Result.config` allows you to access the current configuration.
1955
2001
 
1956
2002
  ```ruby
1957
2003
  BCDD::Result.config.addon.enabled?(:continue)
2004
+ BCDD::Result.config.addon.enabled?(:given)
1958
2005
 
1959
2006
  BCDD::Result.config.addon.options
1960
2007
  # {
1961
2008
  # :continue=>{
1962
2009
  # :enabled=>false,
1963
2010
  # :affects=>[
1964
- # "BCDD::Result",
1965
- # "BCDD::Result::Context",
1966
- # "BCDD::Result::Expectations",
1967
- # "BCDD::Result::Context::Expectations"
2011
+ # "BCDD::Result.mixin",
2012
+ # "BCDD::Result::Context.mixin",
2013
+ # "BCDD::Result::Expectations.mixin",
2014
+ # "BCDD::Result::Context::Expectations.mixin"
2015
+ # ]
2016
+ # },
2017
+ # :given=>{
2018
+ # :enabled=>true,
2019
+ # :affects=>[
2020
+ # "BCDD::Result.mixin",
2021
+ # "BCDD::Result::Context.mixin",
2022
+ # "BCDD::Result::Expectations.mixin",
2023
+ # "BCDD::Result::Context::Expectations.mixin"
1968
2024
  # ]
1969
2025
  # }
1970
2026
  # }
data/Rakefile CHANGED
@@ -3,16 +3,22 @@
3
3
  require 'bundler/gem_tasks'
4
4
  require 'rake/testtask'
5
5
 
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs += %w[lib test]
8
+
9
+ t.test_files = FileList.new('test/**/*_test.rb')
10
+ end
11
+
6
12
  Rake::TestTask.new(:test_configuration) do |t|
7
13
  t.libs += %w[lib test]
8
14
 
9
15
  t.test_files = FileList.new('test/**/configuration_test.rb')
10
16
  end
11
17
 
12
- Rake::TestTask.new(:test) do |t|
18
+ Rake::TestTask.new(:test_transitions_duration) do |t|
13
19
  t.libs += %w[lib test]
14
20
 
15
- t.test_files = FileList.new('test/**/*_test.rb')
21
+ t.test_files = FileList.new('test/**/duration_test.rb')
16
22
  end
17
23
 
18
24
  require 'rubocop/rake_task'
@@ -3,11 +3,16 @@
3
3
  class BCDD::Result
4
4
  class Config
5
5
  module Addons
6
+ AFFECTS = %w[
7
+ BCDD::Result.mixin
8
+ BCDD::Result::Context.mixin
9
+ BCDD::Result::Expectations.mixin
10
+ BCDD::Result::Context::Expectations.mixin
11
+ ].freeze
12
+
6
13
  OPTIONS = {
7
- continue: {
8
- default: false,
9
- affects: %w[BCDD::Result BCDD::Result::Context BCDD::Result::Expectations BCDD::Result::Context::Expectations]
10
- }
14
+ continue: { default: false, affects: AFFECTS },
15
+ given: { default: true, affects: AFFECTS }
11
16
  }.transform_values!(&:freeze).freeze
12
17
 
13
18
  def self.switcher
@@ -7,13 +7,21 @@ class BCDD::Result::Context
7
7
  Methods = BCDD::Result::Expectations::Mixin::Methods
8
8
 
9
9
  module Addons
10
- module Continuable
10
+ module Continue
11
11
  private def Continue(**value)
12
12
  Success.new(type: :continued, value: value, subject: self)
13
13
  end
14
14
  end
15
15
 
16
- OPTIONS = { continue: Continuable }.freeze
16
+ module Given
17
+ private def Given(*values)
18
+ value = values.map(&:to_h).reduce({}) { |acc, val| acc.merge(val) }
19
+
20
+ Success.new(type: :given, value: value, subject: self)
21
+ end
22
+ end
23
+
24
+ OPTIONS = { continue: Continue, given: Given }.freeze
17
25
 
18
26
  def self.options(config_flags)
19
27
  ::BCDD::Result::Config::Options.addon(map: config_flags, from: OPTIONS)
@@ -13,15 +13,15 @@ class BCDD::Result::Context
13
13
  _ResultAs(Failure, type, value)
14
14
  end
15
15
 
16
- private def _ResultAs(kind_class, type, value, halted: nil)
17
- kind_class.new(type: type, value: value, subject: self, halted: halted)
16
+ private def _ResultAs(kind_class, type, value, terminal: nil)
17
+ kind_class.new(type: type, value: value, subject: self, terminal: terminal)
18
18
  end
19
19
  end
20
20
 
21
21
  module Addons
22
- module Continuable
22
+ module Continue
23
23
  def Success(type, **value)
24
- _ResultAs(Success, type, value, halted: true)
24
+ _ResultAs(Success, type, value, terminal: true)
25
25
  end
26
26
 
27
27
  private def Continue(**value)
@@ -29,7 +29,15 @@ class BCDD::Result::Context
29
29
  end
30
30
  end
31
31
 
32
- OPTIONS = { continue: Continuable }.freeze
32
+ module Given
33
+ private def Given(*values)
34
+ value = values.map(&:to_h).reduce({}) { |acc, val| acc.merge(val) }
35
+
36
+ _ResultAs(Success, :given, value)
37
+ end
38
+ end
39
+
40
+ OPTIONS = { continue: Continue, given: Given }.freeze
33
41
 
34
42
  def self.options(config_flags)
35
43
  ::BCDD::Result::Config::Options.addon(map: config_flags, from: OPTIONS)
@@ -3,13 +3,13 @@
3
3
  class BCDD::Result::Context::Success < BCDD::Result::Context
4
4
  include ::BCDD::Result::Success::Methods
5
5
 
6
- def and_expose(type, keys, halted: true)
6
+ def and_expose(type, keys, terminal: true)
7
7
  unless keys.is_a?(::Array) && !keys.empty? && keys.all?(::Symbol)
8
8
  raise ::ArgumentError, 'keys must be an Array of Symbols'
9
9
  end
10
10
 
11
11
  exposed_value = acc.merge(value).slice(*keys)
12
12
 
13
- self.class.new(type: type, value: exposed_value, subject: subject, halted: halted)
13
+ self.class.new(type: type, value: exposed_value, subject: subject, terminal: terminal)
14
14
  end
15
15
  end
@@ -15,7 +15,7 @@ class BCDD::Result
15
15
  Failure.new(type: type, value: value)
16
16
  end
17
17
 
18
- def initialize(type:, value:, subject: nil, expectations: nil, halted: nil)
18
+ def initialize(type:, value:, subject: nil, expectations: nil, terminal: nil)
19
19
  value.is_a?(::Hash) or raise ::ArgumentError, 'value must be a Hash'
20
20
 
21
21
  @acc = {}
@@ -24,25 +24,31 @@ class BCDD::Result
24
24
 
25
25
  FACTORY = <<~RUBY
26
26
  private def _Result
27
- @_Result ||= Result.with(subject: self, halted: %<halted>s)
27
+ @_Result ||= Result.with(subject: self, terminal: %<terminal>s)
28
28
  end
29
29
  RUBY
30
30
 
31
31
  def self.to_eval(addons)
32
- halted = addons.key?(:continue) ? 'true' : 'nil'
32
+ terminal = addons.key?(:continue) ? 'true' : 'nil'
33
33
 
34
- "#{BASE}\n#{format(FACTORY, halted: halted)}"
34
+ "#{BASE}\n#{format(FACTORY, terminal: terminal)}"
35
35
  end
36
36
  end
37
37
 
38
38
  module Addons
39
- module Continuable
39
+ module Continue
40
40
  private def Continue(value)
41
41
  Success.new(type: :continued, value: value, subject: self)
42
42
  end
43
43
  end
44
44
 
45
- OPTIONS = { continue: Continuable }.freeze
45
+ module Given
46
+ private def Given(value)
47
+ Success.new(type: :given, value: value, subject: self)
48
+ end
49
+ end
50
+
51
+ OPTIONS = { continue: Continue, given: Given }.freeze
46
52
 
47
53
  def self.options(config_flags)
48
54
  Config::Options.addon(map: config_flags, from: OPTIONS)
@@ -38,8 +38,8 @@ class BCDD::Result
38
38
 
39
39
  private_class_method :mixin!, :mixin_module, :result_factory_without_expectations
40
40
 
41
- def initialize(subject: nil, contract: nil, halted: nil, **options)
42
- @halted = halted
41
+ def initialize(subject: nil, contract: nil, terminal: nil, **options)
42
+ @terminal = terminal
43
43
 
44
44
  @subject = subject
45
45
 
@@ -60,16 +60,16 @@ class BCDD::Result
60
60
  _ResultAs(Failure, type, value)
61
61
  end
62
62
 
63
- def with(subject:, halted: nil)
64
- self.class.new(subject: subject, halted: halted, contract: contract)
63
+ def with(subject:, terminal: nil)
64
+ self.class.new(subject: subject, terminal: terminal, contract: contract)
65
65
  end
66
66
 
67
67
  private
68
68
 
69
69
  def _ResultAs(kind_class, type, value)
70
- kind_class.new(type: type, value: value, subject: subject, expectations: contract, halted: halted)
70
+ kind_class.new(type: type, value: value, subject: subject, expectations: contract, terminal: terminal)
71
71
  end
72
72
 
73
- attr_reader :subject, :halted, :contract
73
+ attr_reader :subject, :terminal, :contract
74
74
  end
75
75
  end
@@ -20,15 +20,15 @@ class BCDD::Result
20
20
  _ResultAs(Failure, type, value)
21
21
  end
22
22
 
23
- private def _ResultAs(kind_class, type, value, halted: nil)
24
- kind_class.new(type: type, value: value, subject: self, halted: halted)
23
+ private def _ResultAs(kind_class, type, value, terminal: nil)
24
+ kind_class.new(type: type, value: value, subject: self, terminal: terminal)
25
25
  end
26
26
  end
27
27
 
28
28
  module Addons
29
- module Continuable
29
+ module Continue
30
30
  def Success(type, value = nil)
31
- _ResultAs(Success, type, value, halted: true)
31
+ _ResultAs(Success, type, value, terminal: true)
32
32
  end
33
33
 
34
34
  private def Continue(value)
@@ -36,7 +36,13 @@ class BCDD::Result
36
36
  end
37
37
  end
38
38
 
39
- OPTIONS = { continue: Continuable }.freeze
39
+ module Given
40
+ private def Given(value)
41
+ _ResultAs(Success, :given, value)
42
+ end
43
+ end
44
+
45
+ OPTIONS = { continue: Continue, given: Given }.freeze
40
46
 
41
47
  def self.options(config_flags)
42
48
  Config::Options.addon(map: config_flags, from: OPTIONS)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module BCDD
4
4
  class Result
5
- VERSION = '0.10.0'
5
+ VERSION = '0.11.0'
6
6
  end
7
7
  end
data/lib/bcdd/result.rb CHANGED
@@ -16,7 +16,7 @@ require_relative 'result/config'
16
16
  class BCDD::Result
17
17
  attr_accessor :unknown, :transitions
18
18
 
19
- attr_reader :subject, :data, :type_checker, :halted
19
+ attr_reader :subject, :data, :type_checker, :terminal
20
20
 
21
21
  protected :subject
22
22
 
@@ -32,12 +32,12 @@ class BCDD::Result
32
32
  config.freeze
33
33
  end
34
34
 
35
- def initialize(type:, value:, subject: nil, expectations: nil, halted: nil)
35
+ def initialize(type:, value:, subject: nil, expectations: nil, terminal: nil)
36
36
  data = Data.new(kind, type, value)
37
37
 
38
38
  @type_checker = Contract.evaluate(data, expectations)
39
39
  @subject = subject
40
- @halted = halted || kind == :failure
40
+ @terminal = terminal || kind == :failure
41
41
  @data = data
42
42
 
43
43
  self.unknown = true
@@ -46,8 +46,8 @@ class BCDD::Result
46
46
  Transitions.tracking.record(self)
47
47
  end
48
48
 
49
- def halted?
50
- halted
49
+ def terminal?
50
+ terminal
51
51
  end
52
52
 
53
53
  def type
@@ -89,7 +89,7 @@ class BCDD::Result
89
89
  end
90
90
 
91
91
  def and_then(method_name = nil, context = nil, &block)
92
- return self if halted?
92
+ return self if terminal?
93
93
 
94
94
  method_name && block and raise ::ArgumentError, 'method_name and block are mutually exclusive'
95
95
 
@@ -73,6 +73,7 @@ class BCDD::Result::Config::Switcher
73
73
  end
74
74
 
75
75
  module BCDD::Result::Config::Addons
76
+ AFFECTS: Array[String]
76
77
  OPTIONS: Hash[String, Hash[Symbol, untyped]]
77
78
 
78
79
  def self.switcher: -> BCDD::Result::Config::Switcher
@@ -10,7 +10,7 @@ class BCDD::Result::Context < BCDD::Result
10
10
  value: untyped,
11
11
  ?subject: untyped,
12
12
  ?expectations: BCDD::Result::Contract::Evaluator,
13
- ?halted: bool
13
+ ?terminal: bool
14
14
  ) -> void
15
15
 
16
16
  def and_then: (?Symbol, **untyped) ?{ (Hash[Symbol, untyped]) -> untyped } -> BCDD::Result::Context
@@ -27,7 +27,7 @@ class BCDD::Result::Context
27
27
  class Success < BCDD::Result::Context
28
28
  include BCDD::Result::Success::Methods
29
29
 
30
- def and_expose: (Symbol, Array[Symbol], halted: bool) -> BCDD::Result::Context::Success
30
+ def and_expose: (Symbol, Array[Symbol], terminal: bool) -> BCDD::Result::Context::Success
31
31
  end
32
32
 
33
33
  def self.Success: (Symbol, **untyped) -> BCDD::Result::Context::Success
@@ -54,11 +54,11 @@ class BCDD::Result::Context
54
54
 
55
55
  private
56
56
 
57
- def _ResultAs: (singleton(BCDD::Result::Context), Symbol, untyped, ?halted: bool) -> untyped
57
+ def _ResultAs: (singleton(BCDD::Result::Context), Symbol, untyped, ?terminal: bool) -> untyped
58
58
  end
59
59
 
60
60
  module Addons
61
- module Continuable
61
+ module Continue
62
62
  include BCDD::Result::Context::Mixin::Methods
63
63
 
64
64
  private
@@ -66,6 +66,14 @@ class BCDD::Result::Context
66
66
  def Continue: (**untyped) -> BCDD::Result::Context::Success
67
67
  end
68
68
 
69
+ module Given
70
+ include BCDD::Result::Context::Mixin::Methods
71
+
72
+ private
73
+
74
+ def Given: (*untyped) -> BCDD::Result::Context::Success
75
+ end
76
+
69
77
  OPTIONS: Hash[Symbol, Module]
70
78
 
71
79
  def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
@@ -91,10 +99,14 @@ module BCDD::Result::Context::Expectations::Mixin
91
99
  Factory: singleton(BCDD::Result::Expectations::Mixin::Factory)
92
100
 
93
101
  module Addons
94
- module Continuable
102
+ module Continue
95
103
  private def Continue: (**untyped) -> BCDD::Result::Context::Success
96
104
  end
97
105
 
106
+ module Given
107
+ private def Given: (*untyped) -> BCDD::Result::Context::Success
108
+ end
109
+
98
110
  OPTIONS: Hash[Symbol, Module]
99
111
 
100
112
  def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
@@ -18,14 +18,14 @@ class BCDD::Result::Expectations
18
18
  def self.new: (
19
19
  ?subject: untyped,
20
20
  ?contract: BCDD::Result::Contract::Evaluator,
21
- ?halted: bool,
21
+ ?terminal: bool,
22
22
  **untyped
23
23
  ) -> (BCDD::Result::Expectations | untyped)
24
24
 
25
25
  def initialize: (
26
26
  ?subject: untyped,
27
27
  ?contract: BCDD::Result::Contract::Evaluator,
28
- ?halted: bool,
28
+ ?terminal: bool,
29
29
  **untyped
30
30
  ) -> void
31
31
 
@@ -40,7 +40,7 @@ class BCDD::Result::Expectations
40
40
 
41
41
  attr_reader subject: untyped
42
42
  attr_reader contract: BCDD::Result::Contract::Evaluator
43
- attr_reader halted: bool
43
+ attr_reader terminal: bool
44
44
  end
45
45
 
46
46
  module BCDD::Result::Expectations::Mixin
@@ -56,10 +56,14 @@ module BCDD::Result::Expectations::Mixin
56
56
  end
57
57
 
58
58
  module Addons
59
- module Continuable
59
+ module Continue
60
60
  private def Continue: (untyped) -> BCDD::Result::Success
61
61
  end
62
62
 
63
+ module Given
64
+ private def Given: (untyped) -> BCDD::Result::Success
65
+ end
66
+
63
67
  OPTIONS: Hash[Symbol, Module]
64
68
 
65
69
  def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
@@ -11,11 +11,11 @@ class BCDD::Result
11
11
 
12
12
  private
13
13
 
14
- def _ResultAs: (singleton(BCDD::Result), Symbol, untyped, ?halted: bool) -> untyped
14
+ def _ResultAs: (singleton(BCDD::Result), Symbol, untyped, ?terminal: bool) -> untyped
15
15
  end
16
16
 
17
17
  module Addons
18
- module Continuable
18
+ module Continue
19
19
  include BCDD::Result::Mixin::Methods
20
20
 
21
21
  private
@@ -23,6 +23,14 @@ class BCDD::Result
23
23
  def Continue: (untyped) -> BCDD::Result::Success
24
24
  end
25
25
 
26
+ module Given
27
+ include BCDD::Result::Mixin::Methods
28
+
29
+ private
30
+
31
+ def Given: (untyped) -> BCDD::Result::Success
32
+ end
33
+
26
34
  OPTIONS: Hash[Symbol, Module]
27
35
 
28
36
  def self.options: (Hash[Symbol, Hash[Symbol, bool]]) -> Hash[Symbol, Module]
data/sig/bcdd/result.rbs CHANGED
@@ -5,7 +5,7 @@ class BCDD::Result
5
5
 
6
6
  attr_reader data: BCDD::Result::Data
7
7
  attr_reader subject: untyped
8
- attr_reader halted: bool
8
+ attr_reader terminal: bool
9
9
  attr_reader transitions: Hash[Symbol, untyped]
10
10
 
11
11
  def self.config: -> BCDD::Result::Config
@@ -16,13 +16,13 @@ class BCDD::Result
16
16
  value: untyped,
17
17
  ?subject: untyped,
18
18
  ?expectations: BCDD::Result::Contract::Evaluator,
19
- ?halted: bool
19
+ ?terminal: bool
20
20
  ) -> void
21
21
 
22
22
  def type: -> Symbol
23
23
  def value: -> untyped
24
24
 
25
- def halted?: -> bool
25
+ def terminal?: -> bool
26
26
  def success?: (?Symbol type) -> bool
27
27
  def failure?: (?Symbol type) -> bool
28
28
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bcdd-result
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-31 00:00:00.000000000 Z
11
+ date: 2024-01-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Empower Ruby apps with pragmatic use of Result pattern (monad), Railway
14
14
  Oriented Programming, and B/CDD.