use_case_pattern 1.0.0 → 1.0.1

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
  SHA1:
3
- metadata.gz: a796de4be01c7ff1d29ac4b4a5be9cf14509f647
4
- data.tar.gz: 95cbe71afd5dda0f93b6d537e2bbb782fbcab41a
3
+ metadata.gz: 0197a45aa4b6b6aa27b43d0887d884950636bcb6
4
+ data.tar.gz: 5441894af403f3c87f1c63127d647528ca84e1c7
5
5
  SHA512:
6
- metadata.gz: 4878b19038885f4654482ec655aaf340d931edb8a98d9ac280f7830adff2987c8f846981baaca2651b2e1db3121fadada88641ea19b46b02ab8f631877ef0978
7
- data.tar.gz: f1e7b6b0ba605777cca19d621f89345aee70bf4135738b0ba2c7b28cba97b96a4d2021e0e843a40c557e61653110995cf3024b9581e2f1d2fbbcdbf0fc7fa499
6
+ metadata.gz: 7646d2e26a134e69f196366eaa34440bc10bbfc3c0ddf23045156463482fcd01c34ec635671a3fd448e02960f5128524ff566105e966815dab5d988640ed6f0b
7
+ data.tar.gz: 074c32d9931fb4df34311a999a50acb845aca8b89f964ae901155de40c038d74b4af1b7faea99f857621351a9eabf0a4016dada3ae3f3ccd961580fb4c5bf88a
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ *.gem
data/.travis.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.2.2
4
+ - 2.2.5
5
+ - 2.3.1
5
6
  before_install: gem install bundler -v 1.13.1
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # AddressFinder 1.0.1 (October 12, 2016) #
2
+
3
+ * Declare support for activemodel/activesupport version 4.0 or better
4
+
5
+ # AddressFinder 1.0.0 (September 25, 2016) #
6
+
7
+ * Initial release
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # UseCasePattern
2
2
 
3
+ [![Build Status](https://travis-ci.org/AbleTech/use_case_pattern.svg?branch=master)](https://travis-ci.org/AbleTech/use_case_pattern)
4
+
3
5
  A module that helps you to implement the Use Case design pattern.
4
6
 
5
- This pattern is widely used by the teams at Abletech. We were first introduced to this pattern by Shevaun Coker at RubyConf AU 2015 in Melbourne, Australia. You can read more about this pattern in her blog post A [Case for Use Cases](http://webuild.envato.com/blog/a-case-for-use-cases/), and also in the [video of the presentation](https://rubyconf.eventer.com/rubyconf-australia-2015-1223/a-case-for-use-cases-by-shevaun-coker-1734) that she gave.
7
+ This pattern is widely used by the teams at Abletech. We were first introduced to this pattern by Shevaun Coker at RubyConf AU 2015 in Melbourne, Australia. You can read more about this pattern in her blog post A [Case for Use Cases](http://webuild.envato.com/blog/a-case-for-use-cases/), and also in the [video of the presentation](https://rubyconf.eventer.com/rubyconf-australia-2015-1223/a-case-for-use-cases-by-shevaun-coker-1734) that she gave.
6
8
 
7
9
  ## Installation
8
10
 
@@ -24,28 +26,22 @@ Or install it yourself as:
24
26
 
25
27
  When you follow the use case design pattern, you normally define a class with a constructor, and a perform method. You should include the `UseCasePattern` module. Here is a simple example:
26
28
 
27
- ```ruby
29
+ ```ruby
28
30
  class NumberMultiplier
29
31
  include UseCasePattern
30
32
 
31
33
  attr_reader :product
32
-
34
+
33
35
  validates :number1, :number2, presence: true
34
36
 
35
37
  def initialize(number1, number2)
36
38
  @number1 = number1
37
39
  @number2 = number2
38
40
  end
39
-
41
+
40
42
  def perform
41
- if valid?
42
- @product = number1 * number2
43
- end
43
+ @product = @number1 * @number2
44
44
  end
45
-
46
- private
47
-
48
- attr_reader :number1, :number2
49
45
  end
50
46
  ```
51
47
 
@@ -54,7 +50,7 @@ You could call this simple example from a Rails Controller, or anywhere else rea
54
50
  ```ruby
55
51
  def multiply
56
52
  multiplier = NumberMultiplier.perform(params[:number1], params[:number2])
57
-
53
+
58
54
  if multiplier.success?
59
55
  @result = multiplier.result
60
56
  else
@@ -63,6 +59,40 @@ You could call this simple example from a Rails Controller, or anywhere else rea
63
59
  end
64
60
  ```
65
61
 
62
+ ## Normal workflow
63
+
64
+ This section defines the expected approach to implementing a class which uses the use case pattern.
65
+
66
+ ### Initialisation
67
+
68
+ You would normally define a constructor for your use case. The constructor should store any supplied parameters as instance variables. You shouldn't perform any processing or business logic in the constructor.
69
+
70
+ The constructor is called with the parameters that are passed to the `perform` class method. For example, using the NumberMultiplier defined above, making a call to `NumberMultiplier.perform(1, 2)` will result in the initialiser being called as `initialize(1, 2)`.
71
+
72
+ ### Validation
73
+
74
+ You should use ActiveModel validators to check that supplied parameters and any other dependencies are correct. You can also write custom validation methods using the [validate method](http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validate). Following the standard validation approach, you should add to the `errors` collection if validation fails.
75
+
76
+ ### Execution
77
+
78
+ The `perform` method is where the execution of the use case should happen. In this method, you should perform all of the processing and business logic of your use case. Results of the execution should be stored as instance variables.
79
+
80
+ Sometimes during the execution of the `perform` method, an error may occur. You could choose to add to the errors collection or alternatively raise an exception. You should only add to the errors collection if you expect the caller to handle the error.
81
+
82
+ You should note that the value returned from the perform method is discarded. This encourages the caller to make use of the public accessor methods to access the results of the operation.
83
+
84
+ #### The alternative `perform!` method
85
+
86
+ The `perform!` method works in a similar manner to the ActiveRecord `save!` method. Should a validation or other error occur, an exception is raised. This method should be used in scenarios where the caller does not expect any errors to occur. One example of this is when the parameters have been pre-checked by a controller class or similar.
87
+
88
+ ### Post-execution
89
+
90
+ During the `perform` method, you should have stored the results as instance variables. You would normally make these publicly accessible using a `attr_reader` method declaration. You should avoid declaring public methods that further process the output of the `perform` method.
91
+
92
+ #### Checking for errors
93
+
94
+ The caller can check the success or failure of the use case by calling the `success?` and `failure?` helper methods. If the use case has had a failure, the errors will be available on the standard `errors` collection.
95
+
66
96
  ## Development
67
97
 
68
98
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/examples/harvest.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  require 'nokogiri'
2
2
 
3
+ # Queries weather station data provided by harvestelectronics.com
3
4
  class Harvest
4
5
  include UseCasePattern
5
6
 
7
+ validates :station_id, presence: true
8
+
6
9
  def initialize(station_id:)
7
10
  @station_id = station_id.to_i
8
11
  end
@@ -30,3 +30,13 @@ class ThingSpeakReporter
30
30
  params.merge(api_key: api_key)
31
31
  end
32
32
  end
33
+
34
+ # example usage
35
+
36
+ reporter = ThingSpeakReporter.perform(api_key: 'XZY123', params: {indoor_temperature: 22, outdoor_temperature: 15})
37
+
38
+ if reporter.success?
39
+ puts "Temperature saved"
40
+ else
41
+ puts "Oh dear, there is a problem: #{reporter.errors.full_messages.join('; ')}"
42
+ end
@@ -9,10 +9,14 @@ module UseCasePattern
9
9
  module ClassMethods
10
10
  # The perform method of a UseCase should always return itself
11
11
  def perform(*args)
12
- new(*args).tap { |use_case| use_case.perform }
12
+ new(*args).tap do |use_case|
13
+ if use_case.valid?
14
+ use_case.perform
15
+ end
16
+ end
13
17
  end
14
18
 
15
- # Raise an exception if perform generates any errors
19
+ # Raise a validation error if perform has created any errors
16
20
  def perform!(*args)
17
21
  new(*args).tap { |use_case| use_case.perform! }
18
22
  end
@@ -24,19 +28,21 @@ module UseCasePattern
24
28
  end
25
29
 
26
30
  def perform!
27
- perform
31
+ if valid?
32
+ perform
33
+ end
28
34
 
29
35
  if failure?
30
36
  raise_validation_error
31
37
  end
32
38
  end
33
39
 
34
- # Has this use case performed its task successfully?
40
+ # Did the use case performed its task without errors?
35
41
  def success?
36
42
  errors.none?
37
43
  end
38
44
 
39
- # Did this use case have any errors?
45
+ # Did the use case have any errors?
40
46
  def failure?
41
47
  errors.any?
42
48
  end
@@ -1,3 +1,3 @@
1
1
  module UseCasePattern
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -20,10 +20,10 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.required_ruby_version = '~> 2.0'
23
+ spec.required_ruby_version = '~> 2.2'
24
24
 
25
- spec.add_runtime_dependency "activemodel", [">= 4.0.0", "~> 5.0.0"]
26
- spec.add_runtime_dependency "activesupport", [">= 4.0.0", "~> 5.0.0"]
25
+ spec.add_runtime_dependency "activemodel", [">= 4.0.0"]
26
+ spec.add_runtime_dependency "activesupport", [">= 4.0.0"]
27
27
 
28
28
  spec.add_development_dependency "bundler", "~> 1.13"
29
29
  spec.add_development_dependency "rake", "~> 10.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: use_case_pattern
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nigel Ramsay
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-25 00:00:00.000000000 Z
11
+ date: 2016-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -17,9 +17,6 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 4.0.0
20
- - - "~>"
21
- - !ruby/object:Gem::Version
22
- version: 5.0.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,9 +24,6 @@ dependencies:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 4.0.0
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: 5.0.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: activesupport
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -37,9 +31,6 @@ dependencies:
37
31
  - - ">="
38
32
  - !ruby/object:Gem::Version
39
33
  version: 4.0.0
40
- - - "~>"
41
- - !ruby/object:Gem::Version
42
- version: 5.0.0
43
34
  type: :runtime
44
35
  prerelease: false
45
36
  version_requirements: !ruby/object:Gem::Requirement
@@ -47,9 +38,6 @@ dependencies:
47
38
  - - ">="
48
39
  - !ruby/object:Gem::Version
49
40
  version: 4.0.0
50
- - - "~>"
51
- - !ruby/object:Gem::Version
52
- version: 5.0.0
53
41
  - !ruby/object:Gem::Dependency
54
42
  name: bundler
55
43
  requirement: !ruby/object:Gem::Requirement
@@ -102,6 +90,7 @@ files:
102
90
  - ".gitignore"
103
91
  - ".rspec"
104
92
  - ".travis.yml"
93
+ - CHANGELOG.md
105
94
  - Gemfile
106
95
  - README.md
107
96
  - Rakefile
@@ -125,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
114
  requirements:
126
115
  - - "~>"
127
116
  - !ruby/object:Gem::Version
128
- version: '2.0'
117
+ version: '2.2'
129
118
  required_rubygems_version: !ruby/object:Gem::Requirement
130
119
  requirements:
131
120
  - - ">="
@@ -133,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
122
  version: '0'
134
123
  requirements: []
135
124
  rubyforge_project:
136
- rubygems_version: 2.4.8
125
+ rubygems_version: 2.5.1
137
126
  signing_key:
138
127
  specification_version: 4
139
128
  summary: A module that helps you to implement the Use Case design pattern