action_case 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/Guardfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +137 -0
- data/Rakefile +6 -0
- data/action_case.gemspec +27 -0
- data/lib/action_case.rb +9 -0
- data/lib/action_case/base.rb +50 -0
- data/lib/action_case/version.rb +3 -0
- data/spec/action_case/base_spec.rb +146 -0
- data/spec/spec_helper.rb +1 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ffed6d5cb843ec416c48865277de0d4b5ce894a3
|
4
|
+
data.tar.gz: 9292fd2b0a872331447cdee2de14ceb422de2ab9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d76cc46be8db56ca2c8eb87cec55aa4ee6ef67fad36775cdca897f457fc1f88c27c61b97c624336282812b45a268938ca3bf9cca8045a02dc08eac8a9d47611d
|
7
|
+
data.tar.gz: 2c04454834cb8adddaba211cee287cf429f5003f3b6d125084ae47707cefdbacf1a2bec2111393d53a6205addf31eb540964b9afb9deb95445a61409ff2cbd16
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Winton DeShong
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
# ActionCase
|
2
|
+
|
3
|
+
Implementation of use-case driven design for ruby projects. Keep your business logic in the right place!
|
4
|
+
|
5
|
+
Supports: Ruby 1.9.3 +
|
6
|
+
|
7
|
+
[](https://travis-ci.org/wintondeshong/action_case)
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'action_case'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install action_case
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
There are a variety of classes available to implement use-case driven design principles and patterns in your project.
|
26
|
+
|
27
|
+
### Creating use-case class
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
# /app/use_cases/survey_exporter.rb
|
31
|
+
require "csv"
|
32
|
+
|
33
|
+
module UseCases
|
34
|
+
module Surveys
|
35
|
+
class SurveyExporter < ActionCase::Base
|
36
|
+
|
37
|
+
def export_csv survey_id
|
38
|
+
begin
|
39
|
+
survey = resource.find(survey_id)
|
40
|
+
|
41
|
+
return respond CSV.generate({}) { |csv|
|
42
|
+
csv << [:id, :title, :created_at]
|
43
|
+
survey.entries.each do |entry|
|
44
|
+
csv << [entry.id, entry.title, entry.created_at]
|
45
|
+
end
|
46
|
+
}
|
47
|
+
rescue Exception => exception
|
48
|
+
log :error, exception.message
|
49
|
+
end
|
50
|
+
|
51
|
+
respond "Unable to export the survey due to errors", false
|
52
|
+
end
|
53
|
+
|
54
|
+
def resource
|
55
|
+
Survey
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
#### Items of note:
|
64
|
+
1. Injection of concrete implementation via 'resource'
|
65
|
+
2. Use of #resource in #export_csv method, not concrete implementation
|
66
|
+
3. Use of inherited respond method to handle both successful and error responses
|
67
|
+
4. While it isn't required, it is recommended to namespace your use-cases with a [matching folder structure](http://cl.ly/image/1K3U120I1k0j).
|
68
|
+
|
69
|
+
### Leveraging Use-case (perhaps in a Rails controller)
|
70
|
+
|
71
|
+
#### Generic Handler Syntax
|
72
|
+
In many cases, you'll only have one operation in a given use case. When that is the case, you can cut down on verbosity by using the generic handler syntax.
|
73
|
+
Format: ```[use_case_class_name_snake_cased]_[success_or_error]```
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
# /app/controllers/surveys_controller.rb
|
77
|
+
|
78
|
+
class SurveyController < ActionController::Base
|
79
|
+
|
80
|
+
# POST /surveys/:id/export
|
81
|
+
def export
|
82
|
+
UseCases::Surveys::SurveyExporter.new(self).export_csv params[:id]
|
83
|
+
end
|
84
|
+
|
85
|
+
def survey_exporter_success csv_output
|
86
|
+
flash[:notice] = "Survey successfully exported!"
|
87
|
+
send_data csv_output, type: "text/plain", filename: "survey-export.csv", disposition: "attachment"
|
88
|
+
end
|
89
|
+
|
90
|
+
def survey_exporter_error error_output
|
91
|
+
flash[:alert] = "There were issues exporting the survey - #{error_output}"
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
#### Items of note:
|
98
|
+
1. We set the controller as the listener for the use-case, via 'self'
|
99
|
+
2. SurveyController#export stays short, sweet and to the point.
|
100
|
+
3. We avoid coupling by using a very event-like callback (tell don't ask) communication pattern.
|
101
|
+
|
102
|
+
#### Explicit Handler Syntax
|
103
|
+
As your application scales and business rules change, you may have related but slightly different method signatures on a given use-case with each requiring different responses. In those cases the more verbose explicit handler syntax is necessary.
|
104
|
+
Format: ```[class_name_snake_cased]_[method_name_snake_cased]_[success_or_error]```
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
# /app/controllers/surveys_controller.rb
|
108
|
+
|
109
|
+
class SurveyController < ActionController::Base
|
110
|
+
|
111
|
+
# POST /surveys/:id/export
|
112
|
+
def export
|
113
|
+
UseCases::Surveys::SurveyExporter.new(self).export_csv params[:id]
|
114
|
+
end
|
115
|
+
|
116
|
+
def survey_exporter_export_csv_success csv_output
|
117
|
+
flash[:notice] = "Survey successfully exported!"
|
118
|
+
send_data csv_output, type: "text/plain", filename: "survey-export.csv", disposition: "attachment"
|
119
|
+
end
|
120
|
+
|
121
|
+
def survey_exporter_export_csv_error error_output
|
122
|
+
flash[:alert] = "There were issues exporting the survey - #{error_output}"
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
```
|
127
|
+
#### Items of note:
|
128
|
+
1. The expanded method signatures including the ```_export_csv``` component
|
129
|
+
|
130
|
+
|
131
|
+
## Contributing
|
132
|
+
|
133
|
+
1. Fork it
|
134
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
135
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
136
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
137
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/action_case.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "action_case/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "action_case"
|
8
|
+
gem.version = ActionCase::VERSION
|
9
|
+
gem.authors = ["Winton DeShong"]
|
10
|
+
gem.email = ["contact@wintondeshong.com"]
|
11
|
+
gem.description = %q{Use-case driven design for ruby projects. Keeps your business logic in the right place!}
|
12
|
+
gem.summary = %q{Use-case driven design for ruby projects. Keeps your business logic in the right place!}
|
13
|
+
gem.homepage = "https://github.com/wintondeshong/action_case"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split("\n")
|
16
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "activesupport"
|
21
|
+
|
22
|
+
gem.add_development_dependency "guard"
|
23
|
+
gem.add_development_dependency "guard-rspec"
|
24
|
+
gem.add_development_dependency "rake"
|
25
|
+
gem.add_development_dependency "rspec"
|
26
|
+
gem.add_development_dependency "travis-lint"
|
27
|
+
end
|
data/lib/action_case.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module ActionCase
|
2
|
+
class Base
|
3
|
+
|
4
|
+
attr_accessor :listener
|
5
|
+
|
6
|
+
def initialize(listener = nil)
|
7
|
+
@listener = listener
|
8
|
+
end
|
9
|
+
|
10
|
+
def resource
|
11
|
+
raise "ActionCase::Base#resource must be overridden"
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
#####################################
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
#####################################
|
20
|
+
|
21
|
+
def get_class_name
|
22
|
+
self.class.name.underscore.split("/").last # accounts for namespaces
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_explicit_handler(method_name, is_success = true)
|
26
|
+
"#{get_class_name}_#{method_name}_#{is_success ? "success" : "error"}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_generic_handler(is_success = true)
|
30
|
+
"#{get_class_name}_#{is_success ? "success" : "error"}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def respond(response, is_success = true)
|
34
|
+
return response if @listener.nil?
|
35
|
+
|
36
|
+
caller_name = defined?(caller_locations) ? caller_locations(1,1)[0].label : caller[0][/`([^']*)'/, 1] # we use the ruby 2.0+ approach whenever possible being it is significantly faster
|
37
|
+
generic_handler_name = get_generic_handler(is_success)
|
38
|
+
explicit_handler_name = get_explicit_handler(caller_name, is_success)
|
39
|
+
|
40
|
+
if @listener.respond_to?(explicit_handler_name)
|
41
|
+
@listener.send explicit_handler_name, response
|
42
|
+
elsif @listener.respond_to?(generic_handler_name)
|
43
|
+
@listener.send generic_handler_name, response
|
44
|
+
else
|
45
|
+
response
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActionCase::Base do
|
4
|
+
|
5
|
+
# Mocks
|
6
|
+
# -----
|
7
|
+
|
8
|
+
class NonOverriddenUseCase < ActionCase::Base
|
9
|
+
end
|
10
|
+
|
11
|
+
class TestUseCase < ActionCase::Base
|
12
|
+
def method_that_succeeds
|
13
|
+
respond "some-successful-value"
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_that_fails
|
17
|
+
respond "some-error-message", false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Namespaced
|
22
|
+
class TestUseCase < TestUseCase
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class TestListenerWithGenericHandlers
|
27
|
+
def test_use_case_success response
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_use_case_error response
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class TestListenerWithExplicitHandlers
|
35
|
+
def test_use_case_method_that_succeeds_success response
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_use_case_method_that_fails_error response
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class TestListenerWithoutHandlers
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# Tests
|
47
|
+
# -----
|
48
|
+
|
49
|
+
context "#initialize" do
|
50
|
+
it "sets listener to nil by default" do
|
51
|
+
use_case = NonOverriddenUseCase.new
|
52
|
+
expect(use_case.listener).to be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it "sets listener to supplied object" do
|
56
|
+
use_case = NonOverriddenUseCase.new(10)
|
57
|
+
expect(use_case.listener).to eq 10
|
58
|
+
end
|
59
|
+
end # initialize
|
60
|
+
|
61
|
+
context "#listener" do
|
62
|
+
let(:use_case) { TestUseCase.new }
|
63
|
+
|
64
|
+
describe "when listener provided" do
|
65
|
+
describe "contains catch-all handler methods" do
|
66
|
+
let(:listener) { TestListenerWithGenericHandlers.new }
|
67
|
+
|
68
|
+
before(:each) do
|
69
|
+
use_case.listener = listener
|
70
|
+
end
|
71
|
+
|
72
|
+
it "invokes success properly" do
|
73
|
+
expect(listener).to receive(:test_use_case_success).with("some-successful-value")
|
74
|
+
use_case.method_that_succeeds
|
75
|
+
end
|
76
|
+
|
77
|
+
it "invokes error properly" do
|
78
|
+
expect(listener).to receive(:test_use_case_error).with("some-error-message")
|
79
|
+
use_case.method_that_fails
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "contains explicit handler methods" do
|
84
|
+
describe "when use-case not namespaced" do
|
85
|
+
let(:listener) { TestListenerWithExplicitHandlers.new }
|
86
|
+
|
87
|
+
before(:each) do
|
88
|
+
use_case.listener = listener
|
89
|
+
end
|
90
|
+
|
91
|
+
it "invokes success properly" do
|
92
|
+
expect(listener).to receive(:test_use_case_method_that_succeeds_success).with("some-successful-value")
|
93
|
+
use_case.method_that_succeeds
|
94
|
+
end
|
95
|
+
|
96
|
+
it "invokes error properly" do
|
97
|
+
expect(listener).to receive(:test_use_case_method_that_fails_error).with("some-error-message")
|
98
|
+
use_case.method_that_fails
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "when use-case not namespaced" do
|
103
|
+
let(:listener) { TestListenerWithExplicitHandlers.new }
|
104
|
+
let(:use_case) { Namespaced::TestUseCase.new }
|
105
|
+
|
106
|
+
before(:each) do
|
107
|
+
use_case.listener = listener
|
108
|
+
end
|
109
|
+
|
110
|
+
it "invokes success properly" do
|
111
|
+
expect(listener).to receive(:test_use_case_method_that_succeeds_success).with("some-successful-value")
|
112
|
+
use_case.method_that_succeeds
|
113
|
+
end
|
114
|
+
|
115
|
+
it "invokes error properly" do
|
116
|
+
expect(listener).to receive(:test_use_case_method_that_fails_error).with("some-error-message")
|
117
|
+
use_case.method_that_fails
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "hasn't supplied handler methods" do
|
123
|
+
it "returns immediate result" do
|
124
|
+
use_case.listener = TestListenerWithoutHandlers.new
|
125
|
+
expect(use_case.method_that_succeeds).to eq "some-successful-value"
|
126
|
+
expect(use_case.method_that_fails).to eq "some-error-message"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "when listener nil" do
|
132
|
+
it "returns immediate result" do
|
133
|
+
expect(use_case.method_that_succeeds).to eq "some-successful-value"
|
134
|
+
expect(use_case.method_that_fails).to eq "some-error-message"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end # listener
|
138
|
+
|
139
|
+
context "#resource" do
|
140
|
+
it "when not overridden it raises an exception" do
|
141
|
+
use_case = NonOverriddenUseCase.new
|
142
|
+
expect{ use_case.resource }.to raise_error
|
143
|
+
end
|
144
|
+
end # resource
|
145
|
+
|
146
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "action_case"
|
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: action_case
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Winton DeShong
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: guard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: guard-rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: travis-lint
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Use-case driven design for ruby projects. Keeps your business logic in
|
98
|
+
the right place!
|
99
|
+
email:
|
100
|
+
- contact@wintondeshong.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rspec"
|
107
|
+
- ".travis.yml"
|
108
|
+
- Gemfile
|
109
|
+
- Guardfile
|
110
|
+
- LICENSE.txt
|
111
|
+
- README.md
|
112
|
+
- Rakefile
|
113
|
+
- action_case.gemspec
|
114
|
+
- lib/action_case.rb
|
115
|
+
- lib/action_case/base.rb
|
116
|
+
- lib/action_case/version.rb
|
117
|
+
- spec/action_case/base_spec.rb
|
118
|
+
- spec/spec_helper.rb
|
119
|
+
homepage: https://github.com/wintondeshong/action_case
|
120
|
+
licenses: []
|
121
|
+
metadata: {}
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 2.4.6
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: Use-case driven design for ruby projects. Keeps your business logic in the
|
142
|
+
right place!
|
143
|
+
test_files:
|
144
|
+
- spec/action_case/base_spec.rb
|
145
|
+
- spec/spec_helper.rb
|