pay_dirt 1.0.7 → 1.0.8
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 +4 -4
- data/.travis.yml +1 -2
- data/README.md +78 -12
- data/lib/pay_dirt/version.rb +1 -1
- data/pay_dirt.thor +147 -37
- data/test/unit/pay_dirt/base_test.rb +6 -6
- data/test/unit/pay_dirt/result_test.rb +4 -4
- data/test/unit/pay_dirt/use_case_test.rb +11 -11
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: deb62d56966b35151bb79ca90be9ef8782668bb7
|
4
|
+
data.tar.gz: daec7ce9dc30b8c260de4e0eabac949c92e24401
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55677cf4e2a832677f672c8b9e332a2f40ca3df46c1c517bbc0cef4365f5c90b4726da53b4cd4f48a556f3e83596860d98c08f9db4ca377ffbef765c8292f43a
|
7
|
+
data.tar.gz: b422b2fbf53018bd23d471cfebb351645d845459fe1298d225ea4ee643ed6f184c1c7e71dfbfbc92b5e1cd4dae57bc8bf058a3ab0cf90c7400e80e848147803c
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,33 @@
|
|
1
1
|
## pay_dirt [](http://badge.fury.io/rb/pay_dirt) [](https://travis-ci.org/rthbound/pay_dirt) [](https://coveralls.io/r/rthbound/pay_dirt?branch=master) [](https://codeclimate.com/github/rthbound/pay_dirt)
|
2
2
|
|
3
|
-
#### A Ruby gem based on the "use case" pattern set forth in [opencurriculum-flashcards](https://github.com/isotope11/opencurriculum-flashcards)
|
4
|
-
|
5
3
|
Provides the basic building blocks of a pattern capable of reducing a towering codebase to modular rubble (or more Ruby gems)
|
6
4
|
|
5
|
+
### What is PayDirt
|
6
|
+
|
7
|
+
PayDirt gets its name from an 18th century gold mining idiom. One was said to have "struck pay dirt" when his pick axe revealed a vein of ore.
|
8
|
+
I hit pay dirt when I discovered this pattern. It provides me the freedom to build quickly with the confidence of knowing that testing will be a breeze.
|
9
|
+
|
10
|
+
### What is the use case?
|
11
|
+
|
12
|
+
Its use case is gem making. It's for getting rid of callbacks and for shipping business logic off to the more suitable (and more portable) location.
|
13
|
+
It's for packaging use cases up in a modular fashion, where each unit expects to be provided certain dependencies and can be called to provide an expected result.
|
14
|
+
It makes sure you're using dependency injection so you can painlessly mock all your dependencies.
|
15
|
+
|
16
|
+
The basic idea:
|
17
|
+
|
18
|
+
1. Initialize an object by supplying ALL dependencies as a single options hash.
|
19
|
+
2. The object should have ONE public method, `#call`, which will return an expected result object.
|
20
|
+
|
21
|
+
What pay_dirt does to help:
|
22
|
+
|
23
|
+
1. It will set instance variables from the hash of dependencies, using top level key-value pairs.
|
24
|
+
2. It will not initialize (it WILL error) without all required dependencies.
|
25
|
+
3. It allows you to set default values for any dependencies (just merge the `options` argument into your defaults hash before calling `#load_options`)
|
26
|
+
|
27
|
+
PayDirt also provides a `PayDirt::Result` object for your service objects to return (it will respond to `#successful?` and `#data`, see some examples). This is entirely optional, as this object can return whatever you like.
|
28
|
+
|
29
|
+
### Getting on to it
|
30
|
+
|
7
31
|
There are two ways to employ the pattern:
|
8
32
|
|
9
33
|
1. use a class that inherits from [PayDirt::Base](https://github.com/rthbound/pay_dirt/blob/master/test/unit/pay_dirt/base_test.rb#L6-L24)
|
@@ -44,16 +68,18 @@ create a service object
|
|
44
68
|
example
|
45
69
|
-------
|
46
70
|
```
|
47
|
-
$ thor pay_dirt:service_object:new digit_check -d fingers toes -D fingers:10 toes:10
|
48
|
-
|
71
|
+
$ thor pay_dirt:service_object:new quick/digit_check -d fingers toes nose -D fingers:10 toes:10
|
72
|
+
create lib/quick/digit_check.rb
|
73
|
+
create test/unit/quick/digit_check_test.rb
|
74
|
+
append test/minitest_helper.rb
|
49
75
|
```
|
50
76
|
|
51
|
-
Running the above generator will create the following
|
77
|
+
Running the above generator will create the following object
|
52
78
|
|
53
79
|
```ruby
|
54
80
|
require 'pay_dirt'
|
55
81
|
|
56
|
-
module
|
82
|
+
module Quick
|
57
83
|
class DigitCheck < PayDirt::Base
|
58
84
|
def initialize(options = {})
|
59
85
|
options = {
|
@@ -61,23 +87,58 @@ module ServiceObjects
|
|
61
87
|
toes: 10,
|
62
88
|
}.merge(options)
|
63
89
|
|
64
|
-
load_options(:fingers, :toes, options)
|
90
|
+
load_options(:fingers, :toes, :nose, options)
|
65
91
|
end
|
66
92
|
|
67
|
-
def
|
68
|
-
result(true)
|
93
|
+
def call
|
94
|
+
return result(true)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
and the following unit test
|
101
|
+
```ruby
|
102
|
+
require 'minitest_helper'
|
103
|
+
|
104
|
+
describe Quick::DigitCheck do
|
105
|
+
before do
|
106
|
+
@subject = Quick::DigitCheck
|
107
|
+
@params = {
|
108
|
+
fingers: MiniTest::Mock.new,
|
109
|
+
toes: MiniTest::Mock.new,
|
110
|
+
nose: MiniTest::Mock.new,
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "as a class" do
|
115
|
+
it "initializes properly" do
|
116
|
+
@subject.new(@params).must_respond_to :call
|
117
|
+
end
|
118
|
+
|
119
|
+
it "errors when initialized without required dependencies" do
|
120
|
+
-> { @subject.new(@params.reject { |k| k.to_s == 'nose' }) }.must_raise RuntimeError
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "as an instance" do
|
125
|
+
it "executes successfully" do
|
126
|
+
result = @subject.new(@params).call
|
127
|
+
result.successful?.must_equal true
|
128
|
+
result.must_be_kind_of PayDirt::Result
|
69
129
|
end
|
70
130
|
end
|
71
131
|
end
|
72
132
|
```
|
73
133
|
|
74
134
|
### Usage:
|
135
|
+
The class generated can be used in the following manner:
|
75
136
|
```ruby
|
76
|
-
require "
|
77
|
-
|
137
|
+
require "quick/digit_check" #=> true
|
138
|
+
Quick::DigitCheck.new(nose: true).call
|
78
139
|
#=> #<PayDirt::Result:0xa0be85c @data=nil, @success=true>
|
79
140
|
```
|
80
|
-
As you can see, we can now call `
|
141
|
+
As you can see, we can now call `Quick::DigitCheck.new(nose: true).call`
|
81
142
|
and expect a successful return object. Where you take it from there is up to you.
|
82
143
|
|
83
144
|
more examples
|
@@ -86,3 +147,8 @@ more examples
|
|
86
147
|
2. [protected_record](https://github.com/rthbound/protected_record)
|
87
148
|
3. [konamio](https://github.com/rthbound/konamio)
|
88
149
|
4. [eenie_meenie](https://github.com/rthbound/eenie_meenie)
|
150
|
+
5. [foaas](https://github.com/rthbound/foaas)
|
151
|
+
6. [konami-fo](https://github.com/rthbound/konami-fo)
|
152
|
+
7. [rungs](https://github.com/rthbound/rungs)
|
153
|
+
|
154
|
+
#### PayDirt is a Ruby gem based on the "use case" pattern set forth in [opencurriculum-flashcards](https://github.com/isotope11/opencurriculum-flashcards)
|
data/lib/pay_dirt/version.rb
CHANGED
data/pay_dirt.thor
CHANGED
@@ -2,11 +2,14 @@ module PayDirt
|
|
2
2
|
class ServiceObject < Thor
|
3
3
|
include Thor::Actions
|
4
4
|
|
5
|
-
desc "new FILE", "create a
|
5
|
+
desc "new FILE", "create a fully tested object (optionally, requires dependencies)"
|
6
6
|
method_option :dependencies,
|
7
7
|
type: :array,
|
8
8
|
aliases: "-d",
|
9
|
-
desc:
|
9
|
+
desc: "specify required dependencies"
|
10
|
+
method_option :test_framework,
|
11
|
+
type: :string,
|
12
|
+
desc: "choose a testing framework"
|
10
13
|
method_option :defaults,
|
11
14
|
type: :hash,
|
12
15
|
aliases: "-D",
|
@@ -26,73 +29,180 @@ module PayDirt
|
|
26
29
|
class_names = file.split("/").map { |str| str.split("_").map{ |s| (s[0].upcase + s[1..-1]) }.join("") }
|
27
30
|
@dependencies = options[:dependencies] || []
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
create_file "lib/service_objects/#{file}.rb" do
|
33
|
-
open_class(class_names)
|
34
|
-
write_initialize_method
|
35
|
-
write_execute_method
|
36
|
-
|
37
|
-
close_class(class_names)
|
38
|
-
|
39
|
-
@rets
|
40
|
-
end
|
32
|
+
create_object(file, class_names)
|
33
|
+
create_tests(file, class_names)
|
41
34
|
end
|
42
35
|
|
43
36
|
private
|
44
|
-
desc "close_class CLASS_NAMES", "hide", hide: true
|
45
37
|
def close_class(class_names)
|
46
|
-
|
38
|
+
append(@class_depth, "end\n") # Closes innermost class definition
|
47
39
|
|
48
|
-
|
40
|
+
@class_depth.times { |i| append(@class_depth - (i + 1), "end\n") }
|
49
41
|
end
|
50
42
|
|
51
|
-
desc "open_class CLASS_NAMES", "hide", hide: true
|
52
43
|
def open_class(class_names)
|
53
44
|
@class_name = class_names.last
|
54
|
-
@class_depth = class_names.length
|
55
|
-
@inner_depth = class_names.length
|
45
|
+
@class_depth = class_names.length - 1
|
46
|
+
@inner_depth = class_names.length
|
56
47
|
|
57
|
-
|
58
|
-
class_names[0..-2].each_with_index { |mod,i|
|
48
|
+
append(0, "require 'pay_dirt'\n\n")
|
49
|
+
class_names[0..-2].each_with_index { |mod,i| append(i, "module #{mod}\n") }
|
59
50
|
|
60
51
|
if options[:include]
|
61
|
-
|
62
|
-
|
52
|
+
append(@class_depth, "class #{@class_name}\n")
|
53
|
+
append(@inner_depth, "include PayDirt::UseCase\n")
|
63
54
|
elsif options[:inherit]
|
64
|
-
|
55
|
+
append(@class_depth, "class #{@class_name} < PayDirt::Base\n")
|
65
56
|
end
|
66
57
|
end
|
67
58
|
|
68
59
|
def write_execute_method
|
69
|
-
# The
|
70
|
-
|
71
|
-
|
72
|
-
|
60
|
+
# The call method
|
61
|
+
append(@inner_depth, "def call\n")
|
62
|
+
append(@inner_depth.next, "return result(true)\n")
|
63
|
+
append(@inner_depth, "end\n")
|
73
64
|
end
|
74
65
|
|
75
66
|
def write_initialize_method
|
76
|
-
|
67
|
+
append(@inner_depth, "def initialize(options = {})\n")
|
77
68
|
|
78
69
|
set_defaults if options[:defaults]
|
79
70
|
call_load_options
|
80
71
|
|
81
|
-
|
72
|
+
append(@inner_depth, "end\n\n")
|
82
73
|
end
|
83
74
|
|
84
75
|
def call_load_options
|
85
|
-
|
86
|
-
@
|
87
|
-
@
|
76
|
+
append(@inner_depth.next, "# sets instance variables from key value pairs,\n")
|
77
|
+
append(@inner_depth.next, "# will fail if any keys given before options aren't in options\n")
|
78
|
+
append(@inner_depth.next, "load_options(")
|
79
|
+
@dependencies.each { |dep| append(0, ":#{dep}, ") }
|
80
|
+
append(0, "options)\n")
|
88
81
|
end
|
89
82
|
|
90
83
|
def set_defaults
|
91
|
-
|
84
|
+
append(@inner_depth.next, "options = {\n")
|
85
|
+
|
86
|
+
options[:defaults].each { |k,v| append(@inner_depth + 2, "#{k}: #{v}" + ",\n") }
|
87
|
+
|
88
|
+
append(@inner_depth.next, "}.merge(options)\n\n")
|
89
|
+
end
|
90
|
+
|
91
|
+
# TESTS!
|
92
|
+
def open_test_class(class_names, file)
|
93
|
+
case options[:test_framework]
|
94
|
+
when "minitest", "mini_test"
|
95
|
+
append(0, "require 'minitest_helper'\n\n")
|
96
|
+
append_to_file "test/minitest_helper.rb" do
|
97
|
+
"require \"#{file}\"\n"
|
98
|
+
end
|
99
|
+
else
|
100
|
+
append(0, "require 'test_helper'\n\n")
|
101
|
+
append_to_file "test/test_helper.rb" do
|
102
|
+
"require \"#{file}\"\n"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
append(0, "describe #{ class_string(class_names) } do\n")
|
106
|
+
end
|
107
|
+
|
108
|
+
def mock_test_dependencies
|
109
|
+
append(2, "@params = {\n")
|
110
|
+
|
111
|
+
@dependencies.each do |dep|
|
112
|
+
append(3, "#{dep}: MiniTest::Mock.new,\n")
|
113
|
+
end
|
114
|
+
|
115
|
+
append(2, "}\n")
|
116
|
+
end
|
117
|
+
|
118
|
+
def add_before_hook(class_names)
|
119
|
+
append(1, "before do\n")
|
120
|
+
append(2, "@subject = #{ class_string(class_names) }\n")
|
121
|
+
mock_test_dependencies
|
122
|
+
append(1, "end\n")
|
123
|
+
end
|
124
|
+
|
125
|
+
def assert_this(assertion, asserts)
|
126
|
+
append(2, "it \"#{assertion}\" do\n")
|
127
|
+
|
128
|
+
asserts.each do |s|
|
129
|
+
append(3, "#{s}\n")
|
130
|
+
end
|
131
|
+
|
132
|
+
append(2, "end\n")
|
133
|
+
end
|
92
134
|
|
93
|
-
|
135
|
+
def assert_error_without_dependencies
|
136
|
+
assert_this("errors when initialized without required dependencies", @dependencies.reject { |d|
|
137
|
+
options[:defaults] && options[:defaults].keys.include?(d)
|
138
|
+
}.map { |required_dep|
|
139
|
+
"-> { @subject.new(@params.reject { |k| k.to_s == '#{ required_dep }' }) }.must_raise RuntimeError"
|
140
|
+
})
|
141
|
+
end
|
142
|
+
|
143
|
+
def assert_wont_error_with_all_dependencies
|
144
|
+
assert_this("initializes properly", ["@subject.new(@params).must_respond_to :call"])
|
145
|
+
end
|
146
|
+
|
147
|
+
def assert_returns_a_successful_result
|
148
|
+
assert_this("executes successfully", [
|
149
|
+
"result = @subject.new(@params).call",
|
150
|
+
"result.successful?.must_equal true",
|
151
|
+
"result.must_be_kind_of PayDirt::Result"
|
152
|
+
])
|
153
|
+
end
|
154
|
+
|
155
|
+
def context_class
|
156
|
+
append(1, "describe \"as a class\" do\n")
|
157
|
+
assert_wont_error_with_all_dependencies
|
158
|
+
append(0, "\n")
|
159
|
+
assert_error_without_dependencies
|
160
|
+
append(1, "end\n")
|
161
|
+
end
|
162
|
+
|
163
|
+
def context_instance
|
164
|
+
append(1, "describe \"as an instance\" do\n")
|
165
|
+
assert_returns_a_successful_result
|
166
|
+
append(1, "end\n")
|
167
|
+
end
|
168
|
+
|
169
|
+
def close_test_class
|
170
|
+
append(0, "end")
|
171
|
+
end
|
172
|
+
|
173
|
+
def create_object(file, class_names)
|
174
|
+
@rets = nil
|
175
|
+
create_file "lib/#{file}.rb" do
|
176
|
+
open_class(class_names)
|
177
|
+
write_initialize_method
|
178
|
+
write_execute_method
|
179
|
+
|
180
|
+
close_class(class_names)
|
181
|
+
|
182
|
+
@rets
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def create_tests(file, class_names)
|
187
|
+
@rets = nil
|
188
|
+
create_file "test/unit/#{file}_test.rb" do
|
189
|
+
open_test_class(class_names, file)
|
190
|
+
add_before_hook(class_names)
|
191
|
+
append(0, "\n")
|
192
|
+
context_class
|
193
|
+
append(0, "\n")
|
194
|
+
context_instance
|
195
|
+
close_test_class
|
196
|
+
@rets
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def append(depth, string)
|
201
|
+
(@rets ||= "") << (" " * depth) + string
|
202
|
+
end
|
94
203
|
|
95
|
-
|
204
|
+
def class_string(names)
|
205
|
+
names.map(&:to_s).join("::")
|
96
206
|
end
|
97
207
|
end
|
98
208
|
end
|
@@ -13,7 +13,7 @@ describe PayDirt::Base do
|
|
13
13
|
load_options(:the_question, :the_secret, options)
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def call
|
17
17
|
@the_secret == 42 and return result(true, @the_secret )
|
18
18
|
return result(false)
|
19
19
|
end
|
@@ -33,26 +33,26 @@ describe PayDirt::Base do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it "won't error if defaults were supplied for an omitted option" do
|
36
|
-
@use_case.new(the_secret: :not_telling).must_respond_to :
|
36
|
+
@use_case.new(the_secret: :not_telling).must_respond_to :call
|
37
37
|
end
|
38
38
|
|
39
|
-
it "can
|
39
|
+
it "can be called successfully" do
|
40
40
|
dependencies = {
|
41
41
|
the_secret: 42
|
42
42
|
}
|
43
43
|
|
44
|
-
result = @use_case.new(dependencies).
|
44
|
+
result = @use_case.new(dependencies).call
|
45
45
|
|
46
46
|
result.successful?.must_equal true
|
47
47
|
result.must_be_kind_of PayDirt::Result
|
48
48
|
end
|
49
49
|
|
50
|
-
it "can
|
50
|
+
it "can be called unsuccessfully" do
|
51
51
|
dependencies = {
|
52
52
|
the_secret: :i_dunno
|
53
53
|
}
|
54
54
|
|
55
|
-
result = @use_case.new(dependencies).
|
55
|
+
result = @use_case.new(dependencies).call
|
56
56
|
|
57
57
|
result.successful?.must_equal false
|
58
58
|
end
|
@@ -19,7 +19,7 @@ describe PayDirt::Result do
|
|
19
19
|
load_options(:success, :data, options)
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
22
|
+
def call
|
23
23
|
result(@success, @data)
|
24
24
|
end
|
25
25
|
end
|
@@ -28,15 +28,15 @@ describe PayDirt::Result do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "can succeed" do
|
31
|
-
@pay_dirt.new(success: true, data: "yum").
|
31
|
+
@pay_dirt.new(success: true, data: "yum").call.successful?.must_equal true
|
32
32
|
end
|
33
33
|
|
34
34
|
it "can be unsuccessful" do
|
35
|
-
@pay_dirt.new(success: false, data: "gross").
|
35
|
+
@pay_dirt.new(success: false, data: "gross").call.successful?.must_equal false
|
36
36
|
end
|
37
37
|
|
38
38
|
it "provides access to data" do
|
39
|
-
@pay_dirt.new(success: true, data: "yum").
|
39
|
+
@pay_dirt.new(success: true, data: "yum").call.data.must_equal "yum"
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -16,7 +16,7 @@ describe PayDirt::UseCase do
|
|
16
16
|
load_options(:the_secret_to_life_the_universe_and_everything, options)
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def call
|
20
20
|
if @the_secret_to_life_the_universe_and_everything == 42
|
21
21
|
return PayDirt::Result.new(data: return_value, success: true)
|
22
22
|
else
|
@@ -46,30 +46,30 @@ describe PayDirt::UseCase do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it "must not error when options with defaults are omitted" do
|
49
|
-
@use_case.new({}).must_respond_to :
|
49
|
+
@use_case.new({}).must_respond_to :call
|
50
50
|
end
|
51
51
|
|
52
52
|
it "loads options that are not required" do
|
53
|
-
result = @use_case.new({ some_random_option: true }).
|
53
|
+
result = @use_case.new({ some_random_option: true }).call
|
54
54
|
assert result.data[:some_random_option]
|
55
55
|
end
|
56
56
|
|
57
|
-
it "can
|
57
|
+
it "can be called successfully" do
|
58
58
|
dependencies = {
|
59
59
|
}
|
60
60
|
|
61
|
-
result = @use_case.new(dependencies).
|
61
|
+
result = @use_case.new(dependencies).call
|
62
62
|
|
63
63
|
result.successful?.must_equal true
|
64
64
|
result.must_be_kind_of PayDirt::Result
|
65
65
|
end
|
66
66
|
|
67
|
-
it "can
|
67
|
+
it "can be called unsuccessfully" do
|
68
68
|
dependencies = {
|
69
69
|
the_secret_to_life_the_universe_and_everything: :i_dunno
|
70
70
|
}
|
71
71
|
|
72
|
-
result = @use_case.new(dependencies).
|
72
|
+
result = @use_case.new(dependencies).call
|
73
73
|
|
74
74
|
result.successful?.must_equal false
|
75
75
|
end
|
@@ -86,7 +86,7 @@ describe PayDirt::UseCase do
|
|
86
86
|
load_options(:required_option_with_default_value, :required_option, options)
|
87
87
|
end
|
88
88
|
|
89
|
-
def
|
89
|
+
def call
|
90
90
|
if !@required_option_with_default_value
|
91
91
|
return PayDirt::Result.new(data: return_value, success: true)
|
92
92
|
else
|
@@ -105,15 +105,15 @@ describe PayDirt::UseCase do
|
|
105
105
|
end
|
106
106
|
|
107
107
|
# Cheating by not injecting all dependencies
|
108
|
-
result = SomeThing.new(required_option: true).
|
108
|
+
result = SomeThing.new(required_option: true).call # Returns a PayDirt::Result
|
109
109
|
assert !result.successful? #=> false
|
110
110
|
result.data[:optional_option].must_be_nil #=> nil
|
111
111
|
# Playing nice and injecting all required dependencies
|
112
|
-
result = SomeThing.new(required_option: true, required_option_with_default_value: false).
|
112
|
+
result = SomeThing.new(required_option: true, required_option_with_default_value: false).call
|
113
113
|
assert result.successful? #=> true
|
114
114
|
result.data[:optional_option].must_be_nil #=> nil
|
115
115
|
# Making use of an optional option
|
116
|
-
result = SomeThing.new(required_option: true, optional_option: true).
|
116
|
+
result = SomeThing.new(required_option: true, optional_option: true).call
|
117
117
|
assert !result.successful? #=> false
|
118
118
|
assert result.data[:optional_option] #=> true
|
119
119
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pay_dirt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tad Hosford
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|