solid_use_case 2.0.1 → 2.0.2

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
  SHA1:
3
- metadata.gz: 2623d1e04af22ee51de1e4746582707b9c5229d2
4
- data.tar.gz: 7f9546142427b3e95209b807d3f55107f6c18057
3
+ metadata.gz: 6ddf3a778dbf1eb61bc2f63319813267790aa806
4
+ data.tar.gz: 11b3e39668ca2ca7502255f90999eb2b8181753e
5
5
  SHA512:
6
- metadata.gz: 878297f0a78c9f4b558a2a18daf8358c12320aa031bf6268f0e311ff411280e55e73e66ecd5f24680604aa11bb80f95e86e1e4db24d0b27be45be67d9bf42957
7
- data.tar.gz: 1ad7e0f4eeebb337bc12ab21723185d939ec78171f3bba1cd5f43c31624a83fc11c1dacb5f87d124f7aaef8626a8a93c4ab2b42b5dbd14ad1b3d3979db9314b1
6
+ metadata.gz: 9c6177ff65b30961fce7808ecce96401259926075f8d55340767efc6ff104180728e00365fce5044a24dbf4413b8ae08a8df65229e604e61366f98930c57d589
7
+ data.tar.gz: 77ff94dd60cb46f013ae170e92863c1c60f027d8dd74817676b644f6385863ac71039f7353c1e7c7cc799691b1bc273ad6838089823acea803a46b04d67def49
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  Add this line to your application's Gemfile:
8
8
 
9
- gem 'solid_use_case', '~> 2.0.1'
9
+ gem 'solid_use_case', '~> 2.0.2'
10
10
 
11
11
  And then execute:
12
12
 
@@ -93,6 +93,47 @@ class UsersController < ApplicationController
93
93
  end
94
94
  ```
95
95
 
96
+ ## Control Flow Helpers
97
+
98
+ `check_exists` (alias `maybe_continue`) allows you to implicitly return a failure when a value is nil:
99
+
100
+ ```ruby
101
+ # NOTE: The following assumes that #post_comment returns a Success or Failure
102
+ video = Video.find_by_id(params[:video_id])
103
+ check_exists(video).and_then { post_comment(params) }
104
+
105
+ # NOTE: The following assumes that #find_tag and #create_tag both return a Success or Failure
106
+ check_exists(Tag.find_by(name: tag)).or_else { create_tag(tag) }.and_then { ... }
107
+
108
+ # If you wanted, you could refactor the above to use a method:
109
+ def find_tag(name)
110
+ maybe_continue(Tag.find_by(name: name))
111
+ end
112
+
113
+ # Then, elsewhere...
114
+ find_tag(tag)
115
+ .or_else { create_tag(tag) }
116
+ .and_then do |active_record_tag|
117
+ # At this point you can safely assume you have a tag :)
118
+ end
119
+ ```
120
+
121
+ `attempt` allows you to catch an exception. It's useful when you want to attempt something that might fail, but don't want to write all that exception-handling boilerplate.
122
+
123
+ `attempt` also **auto-wraps your values**; in other words, the inner code does **not** have to return a success or failure.
124
+
125
+ For example, a Stripe API call:
126
+
127
+ ```ruby
128
+ # Goal: Only charge customer if he/she exists
129
+ attempt {
130
+ Stripe::Customer.retrieve(some_id)
131
+ }
132
+ .and_then do |stripe_customer|
133
+ stripe_customer.charge(...)
134
+ end
135
+ ```
136
+
96
137
  ## RSpec Matchers
97
138
 
98
139
  If you're using RSpec, Solid Use Case provides some helpful matchers for testing.
@@ -32,11 +32,26 @@ module SolidUseCase
32
32
  # Helpers #
33
33
  # # # # # #
34
34
 
35
+ def check_exists(val, error=:not_found)
36
+ if val.nil?
37
+ fail(error)
38
+ else
39
+ continue(val)
40
+ end
41
+ end
42
+
43
+ def attempt
44
+ attempt_all do
45
+ try { yield }
46
+ end
47
+ end
48
+
35
49
  def fail(type, data={})
36
50
  data[:type] = type
37
51
  Failure(ErrorStruct.new(data))
38
52
  end
39
53
 
54
+ alias :maybe_continue :check_exists
40
55
  alias :continue :Success
41
56
  end
42
57
  end
@@ -1,3 +1,3 @@
1
1
  module SolidUseCase
2
- VERSION = "2.0.1"
2
+ VERSION = "2.0.2"
3
3
  end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Control Flow Helpers" do
4
+
5
+ describe '#check_exists' do
6
+ class FloodGate
7
+ include SolidUseCase::Composable
8
+
9
+ def basic(input)
10
+ check_exists(input).and_then {|x| Success(x * 2) }
11
+ end
12
+
13
+ def alias(input)
14
+ maybe_continue(input)
15
+ end
16
+
17
+ def custom_error(input, err)
18
+ check_exists(input, err)
19
+ end
20
+ end
21
+
22
+ it "stops when the value is nil" do
23
+ result = FloodGate.new.basic(nil)
24
+ expect(result).to fail_with(:not_found)
25
+ end
26
+
27
+ it "continues when the value is not nil" do
28
+ result = FloodGate.new.basic(17)
29
+ expect(result).to be_a_success
30
+ expect(result.value).to eq 34
31
+ end
32
+
33
+ it "has an alias" do
34
+ result = FloodGate.new.basic(17)
35
+ expect(result).to be_a_success
36
+ expect(result.value).to eq 34
37
+ end
38
+
39
+ it "allows a custom error" do
40
+ result = FloodGate.new.custom_error(nil, :my_error)
41
+ expect(result).to fail_with(:my_error)
42
+ end
43
+ end
44
+
45
+ describe '#attempt' do
46
+ class Bubble
47
+ include SolidUseCase::Composable
48
+
49
+ def pop1
50
+ attempt { "pop!" }
51
+ end
52
+
53
+ def pop2
54
+ attempt { raise NoMethodError.new("oops") }
55
+ end
56
+ end
57
+
58
+ it "succeeds when no exceptions happen" do
59
+ expect(Bubble.new.pop1).to be_a_success
60
+ end
61
+
62
+ it "catches exceptions" do
63
+ result = Bubble.new.pop2
64
+ expect(result).to_not be_a_success
65
+ expect(result.value).to be_a NoMethodError
66
+ end
67
+ end
68
+
69
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_use_case
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gilbert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-10 00:00:00.000000000 Z
11
+ date: 2014-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deterministic
@@ -89,6 +89,7 @@ files:
89
89
  - lib/solid_use_case/version.rb
90
90
  - solid_use_case.gemspec
91
91
  - spec/composable_spec.rb
92
+ - spec/control_flow_spec.rb
92
93
  - spec/rspec_matchers_spec.rb
93
94
  - spec/spec_helper.rb
94
95
  homepage: https://github.com/mindeavor/solid_use_case
@@ -117,6 +118,7 @@ specification_version: 4
117
118
  summary: A flexible UseCase pattern that works *with* your workflow, not against it.
118
119
  test_files:
119
120
  - spec/composable_spec.rb
121
+ - spec/control_flow_spec.rb
120
122
  - spec/rspec_matchers_spec.rb
121
123
  - spec/spec_helper.rb
122
124
  has_rdoc: