gourmet 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6659e4dffae66db91fc4833868d9f83634655827
4
+ data.tar.gz: 52e3c88d9f2acead46810501b3279d06293c5a07
5
+ SHA512:
6
+ metadata.gz: 6b623272ac38a717582dd20b4ba7e39c2c448ef2c12df84b8ef16db92c7ef0e3b88df9049a85f8ffe4be8b592690f91bc0599e404865a5306989d40e464ec711
7
+ data.tar.gz: b4ca53b0c7426759acf0e1a8a108142965c104fdcb3666946418e7c29cf5720c64f607418b06b602ea224af223b70dcca44213bc67b78511308e07bd37ddb3d9
@@ -0,0 +1,45 @@
1
+ # Numerous always-ignore extensions
2
+ *.diff
3
+ *.err
4
+ *.orig
5
+ *.log
6
+ *.rej
7
+ *.swo
8
+ *.swp
9
+ *.vi
10
+ *~
11
+ *.sass-cache
12
+
13
+ # OS or Editor folders
14
+ .DS_Store
15
+ .cache
16
+ .project
17
+ .settings
18
+ .tmproj
19
+ nbproject
20
+ Thumbs.db
21
+
22
+ # Dreamweaver added files
23
+ _notes
24
+ dwsync.xml
25
+
26
+ # Komodo
27
+ *.komodoproject
28
+ .komodotools
29
+
30
+ # Folders to ignore
31
+ .hg
32
+ .svn
33
+ .CVS
34
+ intermediate
35
+ publish
36
+ .idea
37
+ .bundle
38
+ db/*.sqlite3
39
+ log/*.log
40
+ tmp/
41
+ .sass-cache/
42
+ dump.rdb
43
+ *.gem
44
+ Makefile
45
+
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1 @@
1
+ 2.1.0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ gourmet (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rspec (3.0.0)
11
+ rspec-core (~> 3.0.0)
12
+ rspec-expectations (~> 3.0.0)
13
+ rspec-mocks (~> 3.0.0)
14
+ rspec-core (3.0.2)
15
+ rspec-support (~> 3.0.0)
16
+ rspec-expectations (3.0.2)
17
+ diff-lcs (>= 1.2.0, < 2.0)
18
+ rspec-support (~> 3.0.0)
19
+ rspec-mocks (3.0.2)
20
+ rspec-support (~> 3.0.0)
21
+ rspec-support (3.0.2)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ gourmet!
28
+ rspec (~> 3.0.0)
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Andrew Berls
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,68 @@
1
+ # Gourmet
2
+
3
+ Service Objects for Rails. Useful for extracting functionality out of long controller actions.
4
+ Credit goes to [Philippe Creux](https://twitter.com/pcreux) for his original description of 'Gourmet Service Objects' in
5
+ [this blog post](http://brewhouse.io/blog/2014/04/30/gourmet-service-objects.html).
6
+
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'gourmet'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install gourmet
21
+
22
+
23
+
24
+ ## Usage
25
+
26
+ Services are defined by subclassing `Gourmet::Service` and implementing a `#call` method. That's it! Service are an extremely thin wrapper over
27
+ plain old Ruby objects, which make them easy to reason about and test in isolation.
28
+
29
+ TODO: examples coming soon
30
+
31
+
32
+ ### Handling complex return values
33
+
34
+ Gourmet ships with a built-in helper class `Gourmet::Result` for handling actions that may or may not succeed.
35
+ `Result` has two subclasses `Success` and `Failure` (similar to Scala's Option library, or the [Possibly](https://github.com/rap1ds/ruby-possibly) gem in Ruby),
36
+ which are instantiated using helper methods of the same name. Result objects implement `#success?` and `#failure?` query methods, and can also act as a wrapper
37
+ for some value. To demonstrate:
38
+
39
+ ```ruby
40
+ class DoWork < Gourmet::Service
41
+ def call(magic_number)
42
+ if magic_number == 7
43
+ Success(magic_number)
44
+ else
45
+ Failure()
46
+ end
47
+ end
48
+ end
49
+
50
+ result = DoWork.call(7)
51
+ result.success? # => true
52
+ result.value # => 7
53
+
54
+ result = DoWork.call(2)
55
+ result.failure? # => true
56
+ ```
57
+
58
+ Note that the use of the `Result` class and methods is completely optional - you're free to substitute your own mechanism for handling complex results,
59
+ or forego it entirely.
60
+
61
+
62
+ ## Contributing
63
+
64
+ 1. Fork it ( http://github.com/andrewberls/gourmet/fork )
65
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
66
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
67
+ 4. Push to the branch (`git push origin my-new-feature`)
68
+ 5. Create new Pull Request
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gourmet/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'gourmet'
8
+ spec.version = Gourmet::VERSION
9
+ spec.authors = ['Andrew Berls']
10
+ spec.email = ['andrew.berls@gmail.com']
11
+ spec.summary = %q{Gourmet Service Objects for Rails}
12
+ spec.description = %q{An implementation of Service Objects for extracting functionality out of Rails controllers. Originally described by Philippe Creux in http://brewhouse.io/blog/2014/04/30/gourmet-service-objects.html}
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'rspec', '~> 3.0.0'
22
+ end
@@ -0,0 +1,5 @@
1
+ module Gourmet
2
+ end
3
+
4
+ require 'gourmet/service'
5
+ require 'gourmet/result'
@@ -0,0 +1,21 @@
1
+ module Gourmet
2
+ class Result
3
+ attr_reader :value
4
+
5
+ def success?
6
+ is_a?(Success)
7
+ end
8
+
9
+ def failure?
10
+ is_a?(Failure)
11
+ end
12
+
13
+ def initialize(value)
14
+ @value = value
15
+ end
16
+ end
17
+
18
+
19
+ class Success < Result; end
20
+ class Failure < Result; end
21
+ end
@@ -0,0 +1,44 @@
1
+ module Gourmet
2
+ class Service
3
+
4
+ def self.call(*args)
5
+ new.call(*args)
6
+ end
7
+
8
+ def call
9
+ raise "You must override #call in class #{self.class.name}"
10
+ end
11
+
12
+
13
+ # Helper methods for instantiating Success/Failure result objects
14
+ # inside Services
15
+ #
16
+ # Example:
17
+ #
18
+ # class DoWork < Gourmet::Service
19
+ # def call(magic_number)
20
+ # if magic_number == 7
21
+ # Success(magic_number)
22
+ # else
23
+ # Failure()
24
+ # end
25
+ # end
26
+ # end
27
+ #
28
+ # result = DoWork.call(7)
29
+ # result.success? # => true
30
+ # result.value # => 7
31
+ #
32
+ # result = DoWork.call(2)
33
+ # result.failure? # => true
34
+
35
+ def Success(value = nil)
36
+ Gourmet::Success.new(value)
37
+ end
38
+
39
+ def Failure(value = nil)
40
+ Gourmet::Failure.new(value)
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module Gourmet
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ class SucceedingService < Gourmet::Service
4
+ def call(value)
5
+ Success(value)
6
+ end
7
+ end
8
+
9
+ class FailingService < Gourmet::Service
10
+ def call(value)
11
+ Failure()
12
+ end
13
+ end
14
+
15
+
16
+ describe Gourmet::Result do
17
+ context '#success?' do
18
+ it 'is true for Gourmet::Success results' do
19
+ result = SucceedingService.call('test')
20
+ expect(result.success?).to eq true
21
+ expect(result.value).to eq 'test'
22
+ end
23
+
24
+ it 'is false for Gourmet::Failure results' do
25
+ result = FailingService.call('test')
26
+ expect(result.success?).to eq false
27
+ end
28
+ end
29
+
30
+
31
+ context '#failure?' do
32
+ it 'is false for Gourmet::Success results' do
33
+ result = SucceedingService.call('test')
34
+ expect(result.failure?).to eq false
35
+ end
36
+
37
+ it 'is true for Gourmet::Failure results' do
38
+ result = FailingService.call('test')
39
+ expect(result.failure?).to eq true
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ class DoWork < Gourmet::Service
4
+ def call(value)
5
+ value
6
+ end
7
+ end
8
+
9
+ describe Gourmet::Service do
10
+ context '.call' do
11
+ it 'delegates to #call' do
12
+ expect(DoWork.call(2)).to eq 2
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ lib = File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'gourmet'
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gourmet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Berls
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.0
27
+ description: An implementation of Service Objects for extracting functionality out
28
+ of Rails controllers. Originally described by Philippe Creux in http://brewhouse.io/blog/2014/04/30/gourmet-service-objects.html
29
+ email:
30
+ - andrew.berls@gmail.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - ".rspec"
37
+ - ".ruby-version"
38
+ - Gemfile
39
+ - Gemfile.lock
40
+ - LICENSE.txt
41
+ - README.md
42
+ - gourmet.gemspec
43
+ - lib/gourmet.rb
44
+ - lib/gourmet/result.rb
45
+ - lib/gourmet/service.rb
46
+ - lib/gourmet/version.rb
47
+ - spec/result_spec.rb
48
+ - spec/service_spec.rb
49
+ - spec/spec_helper.rb
50
+ homepage: ''
51
+ licenses:
52
+ - MIT
53
+ metadata: {}
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 2.2.0
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: Gourmet Service Objects for Rails
74
+ test_files:
75
+ - spec/result_spec.rb
76
+ - spec/service_spec.rb
77
+ - spec/spec_helper.rb