to-result 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc48c861de210a05cba164c61710457447f04b60b492ef15791ab7e5c28a3375
4
- data.tar.gz: fb5802866e75958e710ec9a0be23584f8f737101ef8afd18c5b212a775539c1c
3
+ metadata.gz: d9f9dde009ad8e058a1b645888a53f768c8d2571cd91266f77b1017c8aa469ff
4
+ data.tar.gz: fcbd389f7a3f8d0ddf101cb1064a70a225c039f3cc41c19ca64cac3229469fb9
5
5
  SHA512:
6
- metadata.gz: 60728e022ce553988082effc1ab86a3260cf399a464bddea06d936e6428bf54f0604a8b86638ee7932526a20d72b3c80bcc491f6d816d6d17bdd93326c11b2ce
7
- data.tar.gz: 959d7af9b3eb1367269c6650ca9c9babedd8c3cfd6e36403d3d4f01b750219dc7781cec78e4bc2a4972ce34e230d157dbd17a8bee70b7c9cc24c407fb71f5bc3
6
+ metadata.gz: '08e53f93d442d8d5570cb03eac07df8865f6cb4c14bf1daf0eb9f0db064553d879473379cffdc2cd3707100a690d2aebd26340b69d8faea087c9eb17251e5c71'
7
+ data.tar.gz: 435173009f18e28de610c30424070814b4550e4bb13f5359fda42130eb5fc32887c6004cc6c6aa02b7799b29d74f5b3824b782fdf9c235d90ef5fbd4559dbd07
data/Gemfile CHANGED
@@ -5,10 +5,8 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in pulsarcli.gemspec
6
6
  gemspec
7
7
 
8
- gem 'dry-monads', '~> 1.5'
8
+ gem 'dry-monads', '~> 1.6'
9
9
 
10
10
  gem 'byebug', '~> 11.1'
11
11
 
12
- gem 'minitest', '~> 5.16'
13
-
14
- gem 'mocha', '~> 1.15'
12
+ gem 'rspec'
data/Gemfile.lock CHANGED
@@ -1,33 +1,44 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- to-result (0.1.1)
4
+ to-result (0.2.0)
5
5
  dry-monads (~> 1.5)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  byebug (11.1.3)
11
- concurrent-ruby (1.1.10)
12
- dry-core (0.9.1)
11
+ concurrent-ruby (1.2.2)
12
+ diff-lcs (1.5.0)
13
+ dry-core (1.0.1)
13
14
  concurrent-ruby (~> 1.0)
14
15
  zeitwerk (~> 2.6)
15
- dry-monads (1.5.0)
16
+ dry-monads (1.6.0)
16
17
  concurrent-ruby (~> 1.0)
17
- dry-core (~> 0.9, >= 0.9)
18
+ dry-core (~> 1.0, < 2)
18
19
  zeitwerk (~> 2.6)
19
- minitest (5.16.3)
20
- mocha (1.15.0)
21
- zeitwerk (2.6.1)
20
+ rspec (3.12.0)
21
+ rspec-core (~> 3.12.0)
22
+ rspec-expectations (~> 3.12.0)
23
+ rspec-mocks (~> 3.12.0)
24
+ rspec-core (3.12.2)
25
+ rspec-support (~> 3.12.0)
26
+ rspec-expectations (3.12.3)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.12.0)
29
+ rspec-mocks (3.12.6)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.12.0)
32
+ rspec-support (3.12.1)
33
+ zeitwerk (2.6.11)
22
34
 
23
35
  PLATFORMS
24
36
  ruby
25
37
 
26
38
  DEPENDENCIES
27
39
  byebug (~> 11.1)
28
- dry-monads (~> 1.5)
29
- minitest (~> 5.16)
30
- mocha (~> 1.15)
40
+ dry-monads (~> 1.6)
41
+ rspec
31
42
  to-result!
32
43
 
33
44
  BUNDLED WITH
data/README.md CHANGED
@@ -180,6 +180,13 @@ e.g. sending the log to Airbrake or whathever service you are using
180
180
  - [x] transform/process the catched error => this can be handled with `alt_map` or other methods already available in `dry-monads`
181
181
  - [ ] any type of suggestion is appreciated 😁
182
182
 
183
+ ## Relasing a new version
184
+
185
+ ```
186
+ gem build to-result
187
+ gem push to-result-<version>.gem
188
+ ```
189
+
183
190
  ## Authors
184
191
 
185
192
  - [@a-chris](https://www.github.com/a-chris)
data/lib/to-result.rb CHANGED
@@ -7,7 +7,7 @@ module ToResultMixin
7
7
  attr_accessor :on_error
8
8
 
9
9
  def on_error=(value)
10
- raise TypeError.new('on_error is expected to be a callable object') unless value.respond_to?(:call)
10
+ raise TypeError, 'on_error is expected to be a callable object' unless value.respond_to?(:call)
11
11
 
12
12
  @on_error = value
13
13
  end
@@ -39,14 +39,14 @@ module ToResultMixin
39
39
  # @return [Success]
40
40
  # @return [Failure]
41
41
  #
42
- def ToResult(only: [StandardError], **args, &f)
42
+ def ToResult(only: [StandardError], **args, &block)
43
43
  # on_error included in args so we can distinguish when it's passed but it's nil
44
44
  # from when it's not passed at all
45
45
  on_error ||= args.key?(:on_error) ? args[:on_error] : @@configuration.on_error
46
46
 
47
- f_wrapper =
48
- Proc.new do
49
- f.call
47
+ block_wrapper =
48
+ proc do
49
+ block.call
50
50
  rescue Dry::Monads::Do::Halt => e
51
51
  failure = error = e.result
52
52
  error = error.failure if error.respond_to?(:failure)
@@ -57,6 +57,6 @@ module ToResultMixin
57
57
  raise e
58
58
  end
59
59
 
60
- Try.run(only, f_wrapper).to_result
60
+ Try.run(only, block_wrapper).to_result
61
61
  end
62
62
  end
@@ -0,0 +1,15 @@
1
+ class FakeObject
2
+ extend ToResultMixin
3
+
4
+ def self.log_error(e)
5
+ e
6
+ end
7
+
8
+ def self.log_error_copy(e)
9
+ e
10
+ end
11
+
12
+ def self.raise_do_halt_error(failure, on_error: nil)
13
+ ToResult(on_error: on_error) { yield failure }
14
+ end
15
+ end
@@ -0,0 +1,116 @@
1
+ require 'byebug'
2
+
3
+ require './lib/to-result'
4
+ require './spec/support/fake_object'
5
+
6
+
7
+ RSpec.describe ToResultMixin do
8
+ include ToResultMixin
9
+
10
+ let(:value) { 'hello world!' }
11
+
12
+ before do
13
+ # reset the configuration before each test
14
+ ToResultMixin.configure { |c| c = {} }
15
+ end
16
+
17
+ describe 'result handling' do
18
+ it 'returns a Success with the value of the block' do
19
+ expect(ToResult { value }).to eq(Success(value))
20
+ end
21
+
22
+ it 'returns a Success without the Success of the block' do
23
+ expected = Success(value)
24
+ expect(ToResult { expected }).to eq(Success(expected))
25
+ end
26
+
27
+ it 'returns a Failure with the exception raised by the block' do
28
+ expected = StandardError.new(value)
29
+ expect(ToResult { raise expected }).to eq(Failure(expected))
30
+ end
31
+
32
+ it 'returns a Failure if the error class is included in `only`' do
33
+ expected = ArgumentError.new(value)
34
+ expect(ToResult(only: [ArgumentError]) { raise expected }).to eq(Failure(expected))
35
+ end
36
+
37
+ it 'raises an error if the error class is not included in `only`' do
38
+ expected = NameError.new(value)
39
+ expect { ToResult(only: [ArgumentError]) { raise expected } }.to raise_error(NameError)
40
+ end
41
+
42
+ it 'returns Failure if the block raises a Dry::Monads::Do::Halt error' do
43
+ expected = Dry::Monads::Failure(StandardError.new(value))
44
+ # it equals to ToResult { yield expected }
45
+ expect(FakeObject.raise_do_halt_error(expected)).to eq(expected)
46
+ end
47
+ end
48
+
49
+ describe 'on_error' do
50
+ it 'passes the unwrapped error to on_error' do
51
+ local_on_error = proc { |e| FakeObject.log_error(e) }
52
+
53
+ expected = StandardError.new(value)
54
+ failure = Failure(expected)
55
+ expect(FakeObject).to receive(:log_error).and_return(expected).once
56
+ # it equals to ToResult { yield expected }
57
+ expect(FakeObject.raise_do_halt_error(failure, on_error: local_on_error)).to eq(Dry::Monads::Failure.new(expected))
58
+ end
59
+
60
+ context 'when gloval callback is not defiend' do
61
+ it 'uses the local on_error' do
62
+ local_on_error = proc { |e| FakeObject.log_error(e) }
63
+
64
+ expected = StandardError.new(value)
65
+ expect(FakeObject).to receive(:log_error).and_return(expected).once
66
+ expect(ToResult(on_error: local_on_error) { raise expected }).to eq(Failure(expected))
67
+ end
68
+
69
+ it 'does not raise error if local on_error is not a proc' do
70
+ local_on_error = 'not a proc'
71
+
72
+ expected = StandardError.new(value)
73
+ FakeObject.methods(false).each { |m| expect(FakeObject).to receive(m).never }
74
+ expect(ToResult(on_error: local_on_error) { raise expected }).to eq(Failure(expected))
75
+ end
76
+ end
77
+
78
+ context 'when global callback is invalid' do
79
+ it 'raises an error' do
80
+ expect do
81
+ ToResultMixin.configure { |c| c.on_error = 'invalid value, should be a proc' }
82
+ end.to raise_error(TypeError)
83
+ end
84
+ end
85
+
86
+ context 'when global callback if valid and defined globally' do
87
+ before do
88
+ ToResultMixin.configure do |c|
89
+ c.on_error = proc { |e| FakeObject.log_error(e) }
90
+ end
91
+ end
92
+
93
+ it 'calls the global callback' do
94
+ expected = StandardError.new(value)
95
+ expect(FakeObject).to receive(:log_error).with(expected).once
96
+ expect(ToResult { raise expected }).to eq(Failure(expected))
97
+ end
98
+
99
+ it 'uses local on_error over the global one' do
100
+ local_on_error = Proc.new { |e| FakeObject.log_error_copy(e) }
101
+
102
+ expected = StandardError.new(value)
103
+ expect(FakeObject).to receive(:log_error_copy).with(expected).once
104
+ expect(ToResult(on_error: local_on_error) { raise expected }).to eq(Failure(expected))
105
+ end
106
+
107
+ it 'uses local on_error over the global one even if nil' do
108
+ local_on_error = nil
109
+
110
+ expected = StandardError.new(value)
111
+ FakeObject.methods(false).each { |m| expect(FakeObject).to receive(m).never }
112
+ expect(ToResult(on_error: local_on_error) { raise expected }).to eq(Failure(expected))
113
+ end
114
+ end
115
+ end
116
+ end
data/to-result.gemspec CHANGED
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = 'to-result'
8
- s.version = '0.1.1'
8
+ s.version = '0.2.0'
9
9
  s.summary = 'A wrapper over dry-monads to offer a handy and consistent way to implement the Railway pattern.'
10
10
  s.description = 'A wrapper over dry-monads to offer a handy and consistent way to implement the Railway pattern.'
11
11
  s.authors = ['Christian Toscano']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: to-result
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Toscano
@@ -38,8 +38,8 @@ files:
38
38
  - README.md
39
39
  - bin/console
40
40
  - lib/to-result.rb
41
- - tests/support/fake_logger.rb
42
- - tests/to_result_test.rb
41
+ - spec/support/fake_object.rb
42
+ - spec/to_result_spec.rb
43
43
  - to-result.gemspec
44
44
  homepage: https://github.com/a-chris/to-result
45
45
  licenses:
@@ -1,9 +0,0 @@
1
- class FakeLogger
2
- def self.log_error(e)
3
- e
4
- end
5
-
6
- def self.return_error(e)
7
- e
8
- end
9
- end
@@ -1,114 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'mocha/minitest'
3
- require 'byebug'
4
-
5
- require './lib/to-result'
6
- require './tests/support/fake_logger'
7
-
8
- class ToResultTest < Minitest::Test
9
- include ToResultMixin
10
-
11
- def setup
12
- super
13
- @value = 'hello world!'
14
- end
15
-
16
- def teardown
17
- super
18
-
19
- # reset the configuration after each test
20
- ToResultMixin.configure { |c| c = {} }
21
- end
22
-
23
- def test_string
24
- assert ToResult { @value } == Success(@value)
25
- end
26
-
27
- def test_success
28
- expected = Success(@value)
29
- assert ToResult { expected } == Success(expected)
30
- end
31
-
32
- def test_exception
33
- expected = StandardError.new(@value)
34
- assert ToResult { raise expected } == Failure(expected)
35
- end
36
-
37
- def test_exception_included_in_exceptions_list
38
- expected = ArgumentError.new(@value)
39
- assert ToResult(only: [ArgumentError]) { raise expected } == Failure(expected)
40
- end
41
-
42
- def test_exception_not_included_in_exceptions_list
43
- expected = NameError.new(@value)
44
- assert_raises(NameError) { ToResult(only: [ArgumentError]) { raise expected } }
45
- end
46
-
47
- def test_yield_failure
48
- expected = Failure(@value)
49
- # this will raise a Dry::Monads::Do::Halt exception
50
- assert ToResult { yield expected } == expected
51
- end
52
-
53
- def test_yield_failure_exception
54
- expected = Failure(StandardError.new(@value))
55
- # this will raise a Dry::Monads::Do::Halt exception
56
- assert ToResult { yield expected } == expected
57
- end
58
-
59
- def test_invalid_global_on_error
60
- assert_raises(TypeError) do
61
- ToResultMixin.configure { |c| c.on_error = 'invalid value' }
62
- end
63
- end
64
-
65
- def setup_global_on_error
66
- # creating a clean room just for testing purpose
67
- clean_room = Class.new(Object)
68
- clean_room.new.instance_eval do
69
- ToResultMixin.configure do |c|
70
- c.on_error = Proc.new { |e| FakeLogger.log_error(e) }
71
- end
72
- end
73
- end
74
-
75
- def test_global_on_error
76
- setup_global_on_error
77
-
78
- FakeLogger.expects(:log_error).once
79
-
80
- expected = StandardError.new(@value)
81
-
82
- assert ToResult { raise expected } == Failure(expected)
83
- end
84
-
85
- def test_local_on_error_overrides_global
86
- setup_global_on_error
87
-
88
- FakeLogger.expects(:log_error).once
89
-
90
- local_on_error = Proc.new { FakeLogger.log_error }
91
-
92
- expected = StandardError.new(@value)
93
- assert ToResult(on_error: local_on_error) { raise expected } == Failure(expected)
94
- end
95
-
96
- def test_local_on_error_overrides_global_nil
97
- setup_global_on_error
98
-
99
- FakeLogger.expects(:log_error).never
100
-
101
- local_on_error = nil
102
-
103
- expected = StandardError.new(@value)
104
- assert ToResult(on_error: local_on_error) { raise expected } == Failure(expected)
105
- end
106
-
107
- def test_local_on_error_without_global
108
- local_on_error = Proc.new { |e| FakeLogger.return_error(e) }
109
-
110
- expected = StandardError.new(@value)
111
- FakeLogger.expects(:return_error).with(expected).returns(expected).once
112
- assert ToResult(on_error: local_on_error) { yield Failure(expected) } == Failure(expected)
113
- end
114
- end