null_and_void 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +240 -0
- data/Rakefile +1 -0
- data/lib/null_and_void.rb +7 -0
- data/lib/null_and_void/convertible.rb +54 -0
- data/lib/null_and_void/falsifiable.rb +19 -0
- data/lib/null_and_void/maybe.rb +9 -0
- data/lib/null_and_void/model_support.rb +27 -0
- data/lib/null_and_void/null_object.rb +7 -0
- data/lib/null_and_void/nullified.rb +15 -0
- data/lib/null_and_void/stubbable.rb +7 -0
- data/lib/null_and_void/version.rb +3 -0
- data/spec/convertible_spec.rb +70 -0
- data/spec/falsifiable_spec.rb +26 -0
- data/spec/maybe_spec.rb +20 -0
- data/spec/model_support_spec.rb +31 -0
- data/spec/null_and_void_spec.rb +8 -0
- data/spec/null_object_spec.rb +22 -0
- data/spec/nullified_spec.rb +39 -0
- data/spec/stubbable_spec.rb +14 -0
- metadata +122 -0
data/README.md
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
Null And Void
|
2
|
+
================================
|
3
|
+
|
4
|
+
**Create Null Objects with Ease**
|
5
|
+
|
6
|
+
<img src="http://cdn.memegenerator.net/instances/300x/34275719.jpg" align="right" />
|
7
|
+
|
8
|
+
Using the Null Object pattern in Ruby is rather easy so why create a gem?
|
9
|
+
|
10
|
+
I found myself using the same implementation around the [Null Object
|
11
|
+
pattern](https://en.wikipedia.org/wiki/Null_object_pattern#Ruby) over and over.
|
12
|
+
Rather than duplicating the logic in every one of my projects, I decided to
|
13
|
+
package it up as a gem.
|
14
|
+
|
15
|
+
In the process of doing research to make sure I was implementing this gem the
|
16
|
+
best way possible, I came across [an article by Avdi
|
17
|
+
Grimm](http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness). In the
|
18
|
+
article Avdi brings up a lot of the same ideas I was implementing in my gem.
|
19
|
+
Additionally, he had come up with some [other](#helper-methods)
|
20
|
+
[nicities](#maybies) that I hadn't thought of.
|
21
|
+
|
22
|
+
<br/>
|
23
|
+
<br/>
|
24
|
+
<br/>
|
25
|
+
<br/>
|
26
|
+
<br/>
|
27
|
+
<br/>
|
28
|
+
<br/>
|
29
|
+
|
30
|
+
Installation
|
31
|
+
--------------------------------
|
32
|
+
|
33
|
+
gem install null_and_void
|
34
|
+
|
35
|
+
Usage
|
36
|
+
--------------------------------
|
37
|
+
|
38
|
+
Whenever you want to return a Null Object you can do something like:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
def first_tps_line_item
|
42
|
+
TpsReport.line_items.first || NullAndVoid::NullObject.instance
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Alternatively, you can [define your own Null Objects](#defineyourownnullobjects)
|
47
|
+
such as:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
def first_tps_line_item
|
51
|
+
TpsReport.line_items.first || NullTpsLineItem.instance
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
If you decide to [use the mixin](#includeintoyourobjectsoptional) you can call
|
56
|
+
the `as_null_object` method on the class and use convention to figure out which
|
57
|
+
Null Object you want:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
def first_tps_line_item
|
61
|
+
TpsReport.line_items.first || TpsLineItem.as_null_object
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
In this case it will return a `NullTpsLineItem` if it's defined and otherwise
|
66
|
+
will return a `NullAndVoid::NullObject`.
|
67
|
+
|
68
|
+
Implementation
|
69
|
+
--------------------------------
|
70
|
+
|
71
|
+
### Method Implementation #####################################################
|
72
|
+
|
73
|
+
With the exception of those defined below, any calls to any methods on a Null
|
74
|
+
Object that inherits from `NullAndVoid::NullObject` will result in itself.
|
75
|
+
|
76
|
+
**Example:**
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
null_object = NullAndVoid::NullObject.instance
|
80
|
+
|
81
|
+
null_object == null_object.foobar # => true
|
82
|
+
```
|
83
|
+
|
84
|
+
### Helper Methods ############################################################
|
85
|
+
|
86
|
+
Many common Ruby methods are implemented as 'noops' such as:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
null_object = NullUser.instance
|
90
|
+
|
91
|
+
null_object.to_i # => 0
|
92
|
+
null_object.to_int # => 0
|
93
|
+
null_object.to_f # => 0.0
|
94
|
+
null_object.to_r # => (0/1)
|
95
|
+
null_object.to_a # => []
|
96
|
+
null_object.to_ary # => []
|
97
|
+
null_object.to_hash # => {}
|
98
|
+
null_object.to_html # => ''
|
99
|
+
null_object.to_json # => ''
|
100
|
+
null_object.to_xml # => ''
|
101
|
+
null_object.to_model # => User.new
|
102
|
+
null_object.to_s # => ''
|
103
|
+
```
|
104
|
+
|
105
|
+
### Falsity ###################################################################
|
106
|
+
|
107
|
+
`NullAndVoid::NullObject` attempts to be falsey whenever possible however it's
|
108
|
+
my opinion that this is an anti-pattern and only the basic attempts are made to
|
109
|
+
make this work. For example:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
null_object = NullAndVoid::NullObject.instance
|
113
|
+
|
114
|
+
!null_object # => true
|
115
|
+
null_object.nil? # => true
|
116
|
+
null_object.blank? # => true
|
117
|
+
null_object.present? # => false
|
118
|
+
```
|
119
|
+
|
120
|
+
### Singleton Implementation ##################################################
|
121
|
+
|
122
|
+
`NullAndVoid::NullObject` is a singleton. All calls to an implementation of it
|
123
|
+
will result in the same object. Therefore:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
NullUser.instance == User.new.as_null_object == User.as_null_object # => true
|
127
|
+
```
|
128
|
+
|
129
|
+
### Define Your Own Null Objects ##############################################
|
130
|
+
|
131
|
+
When implementing a Null Object for a specific class that you own, simply
|
132
|
+
include `NullAndVoid::Nullified` like so:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
require 'null_and_void/nullified'
|
136
|
+
|
137
|
+
class NullUser
|
138
|
+
include NullAndVoid::Nullified
|
139
|
+
|
140
|
+
def admin?
|
141
|
+
false
|
142
|
+
end
|
143
|
+
end
|
144
|
+
```
|
145
|
+
|
146
|
+
### Maybies ###################################################################
|
147
|
+
|
148
|
+
Unfortunately when you're programming in the 'Real World ©" you don't
|
149
|
+
always have control over the API you're using. And sometimes, those APIs,
|
150
|
+
rather than doing the sane thing and always returning the same type no matter
|
151
|
+
what, instead return nils.
|
152
|
+
|
153
|
+
In these situations, you could do this:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
class Foo
|
157
|
+
def bar
|
158
|
+
call_some_method_that_could_return_nils || NullAndVoid::NullObject.instance
|
159
|
+
end
|
160
|
+
end
|
161
|
+
```
|
162
|
+
|
163
|
+
Or instead, you can simply mixin `NullAndVoid::Mayby` and it will handle that
|
164
|
+
for you. For example:
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
class Foo
|
168
|
+
include NullAndVoid::Maybe
|
169
|
+
|
170
|
+
def bar
|
171
|
+
maybe(call_some_method_that_could_return_nils)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
```
|
175
|
+
|
176
|
+
If you'd rather not mix it into your class, you can also just call it directly:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
class Foo
|
180
|
+
def bar
|
181
|
+
NullAndVoid.maybe(call_some_method_that_could_return_nils)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
### Include Into Your Objects (Optional) ######################################
|
187
|
+
|
188
|
+
You can add Null Object creation to your class by including
|
189
|
+
`NullAndVoid::ModelSupport`.
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
class User
|
193
|
+
include NullAndVoid::ModelSupport
|
194
|
+
|
195
|
+
def admin?
|
196
|
+
type == 'admin'
|
197
|
+
end
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
201
|
+
This will endow your class with two methods `.as_null_object` and
|
202
|
+
`#as_null_object`. Both of which return either the Null Object for that class
|
203
|
+
(eg `NullUser`) or the generic `NullAndVoid::NullObject`.
|
204
|
+
|
205
|
+
Now, when calling:
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
User.as_null_object
|
209
|
+
```
|
210
|
+
|
211
|
+
or:
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
User.new.as_null_object
|
215
|
+
```
|
216
|
+
|
217
|
+
Will return:
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
NullUser.instance
|
221
|
+
```
|
222
|
+
|
223
|
+
Issues
|
224
|
+
------
|
225
|
+
|
226
|
+
If you have problems, please create a [Github issue](issues).
|
227
|
+
|
228
|
+
Credits
|
229
|
+
-------
|
230
|
+
|
231
|
+
![thekompanee](http://www.thekompanee.com/public_files/kompanee-github-readme-logo.png)
|
232
|
+
|
233
|
+
null_and_void is maintained by [The Kompanee, Ltd.](http://www.thekompanee.com)
|
234
|
+
|
235
|
+
The names and logos for The Kompanee are trademarks of The Kompanee, Ltd.
|
236
|
+
|
237
|
+
License
|
238
|
+
-------
|
239
|
+
|
240
|
+
null_and_void is Copyright © 2013 The Kompanee. It is free software, and may be redistributed under the terms specified in the LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'active_support/inflector/methods'
|
2
|
+
|
3
|
+
module NullAndVoid
|
4
|
+
module Convertible
|
5
|
+
def to_i
|
6
|
+
0
|
7
|
+
end
|
8
|
+
|
9
|
+
alias :to_int :to_i
|
10
|
+
|
11
|
+
def to_f
|
12
|
+
0.0
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_r
|
16
|
+
Rational(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_a
|
20
|
+
Array.new
|
21
|
+
end
|
22
|
+
|
23
|
+
alias :to_ary :to_a
|
24
|
+
|
25
|
+
def to_hash
|
26
|
+
Hash.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_html
|
30
|
+
''
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_json
|
34
|
+
''
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_xml
|
38
|
+
''
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
''
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_model
|
46
|
+
base_path = ActiveSupport::Inflector.demodulize(self.class.name)
|
47
|
+
module_path = ActiveSupport::Inflector.deconstantize(self.class.name)
|
48
|
+
source_model = base_path.gsub(/^Null/, '')
|
49
|
+
source_model_path = "#{module_path}::#{source_model}"
|
50
|
+
|
51
|
+
ActiveSupport::Inflector.constantize(source_model_path).new
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'active_support/inflector/methods'
|
2
|
+
require 'null_and_void/null_object'
|
3
|
+
|
4
|
+
module NullAndVoid
|
5
|
+
module ModelSupport
|
6
|
+
module ClassMethods
|
7
|
+
def as_null_object
|
8
|
+
base_path = ActiveSupport::Inflector.demodulize(self.name)
|
9
|
+
module_path = ActiveSupport::Inflector.deconstantize(self.name)
|
10
|
+
null_object_base = "Null#{base_path}"
|
11
|
+
source_model_path = "#{module_path}::#{null_object_base}"
|
12
|
+
|
13
|
+
ActiveSupport::Inflector.constantize(source_model_path).new
|
14
|
+
rescue NameError
|
15
|
+
NullAndVoid::NullObject.instance
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def as_null_object
|
20
|
+
self.class.as_null_object
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.included(base)
|
24
|
+
base.extend ClassMethods
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'null_and_void/stubbable'
|
3
|
+
require 'null_and_void/convertible'
|
4
|
+
require 'null_and_void/falsifiable'
|
5
|
+
|
6
|
+
module NullAndVoid
|
7
|
+
module Nullified
|
8
|
+
def self.included(base)
|
9
|
+
base.send(:include, Singleton)
|
10
|
+
base.send(:include, Stubbable)
|
11
|
+
base.send(:include, Convertible)
|
12
|
+
base.send(:include, Falsifiable)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/convertible'
|
3
|
+
|
4
|
+
module FooBar
|
5
|
+
class NullObject
|
6
|
+
include NullAndVoid::Convertible
|
7
|
+
end
|
8
|
+
|
9
|
+
class NullBaz
|
10
|
+
include NullAndVoid::Convertible
|
11
|
+
end
|
12
|
+
|
13
|
+
class Object
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe NullAndVoid::Convertible do
|
18
|
+
let(:null_object) { FooBar::NullObject.new }
|
19
|
+
|
20
|
+
it 'is zero when the attempt is made to convert it to an Integer' do
|
21
|
+
null_object.to_i.should be_an Integer
|
22
|
+
null_object.to_i.should be_zero
|
23
|
+
|
24
|
+
null_object.to_int.should be_an Integer
|
25
|
+
null_object.to_int.should be_zero
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'is zero when the attempt is made to convert it to a Float' do
|
29
|
+
null_object.to_f.should be_a Float
|
30
|
+
null_object.to_f.should be_zero
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'is zero when the attempt is made to convert it to a Rational' do
|
34
|
+
null_object.to_r.should be_a Rational
|
35
|
+
null_object.to_r.should be_zero
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'is an empty Array when the attempt is made to convert it to an Array' do
|
39
|
+
null_object.to_a.should eql []
|
40
|
+
null_object.to_ary.should eql []
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'is an empty Hash when the attempt is made to convert it to an Hash' do
|
44
|
+
null_object.to_hash.should eql Hash.new
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'is an empty String when the attempt is made to convert it to HTML' do
|
48
|
+
null_object.to_html.should eql ''
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'is an empty String when the attempt is made to convert it to JSON' do
|
52
|
+
null_object.to_json.should eql ''
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'is an empty String when the attempt is made to convert it to XML' do
|
56
|
+
null_object.to_xml.should eql ''
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'is an empty String when the attempt is made to convert it to a String' do
|
60
|
+
null_object.to_s.should eql ''
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'is the class the Null Object is based on when the attempt is made to convert it to a value object' do
|
64
|
+
null_object.to_model.should be_a FooBar::Object
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'raises an error if the model the Null Object is based on does not exist' do
|
68
|
+
expect { FooBar::NullBaz.new.to_model }.to raise_error NameError
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/falsifiable'
|
3
|
+
|
4
|
+
class NullObject
|
5
|
+
include NullAndVoid::Falsifiable
|
6
|
+
end
|
7
|
+
|
8
|
+
describe NullAndVoid::Falsifiable do
|
9
|
+
let(:null_object) { NullObject.new }
|
10
|
+
|
11
|
+
it 'can be double inverted to be false' do
|
12
|
+
(!!null_object).should be_false
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'is blank' do
|
16
|
+
null_object.should be_blank
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'is nil' do
|
20
|
+
null_object.should be_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'is not present' do
|
24
|
+
null_object.should_not be_present
|
25
|
+
end
|
26
|
+
end
|
data/spec/maybe_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/maybe'
|
3
|
+
|
4
|
+
class MyObject
|
5
|
+
include NullAndVoid::Maybe
|
6
|
+
end
|
7
|
+
|
8
|
+
describe NullAndVoid::Maybe do
|
9
|
+
context 'when it is passed a nil' do
|
10
|
+
it 'is a null object' do
|
11
|
+
MyObject.new.maybe(nil).should be_a NullAndVoid::NullObject
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when it is passed something other than nil' do
|
16
|
+
it 'is the non-nil object' do
|
17
|
+
MyObject.new.maybe(1).should eql 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/model_support'
|
3
|
+
|
4
|
+
module FooBar
|
5
|
+
class MyNullableModel
|
6
|
+
include NullAndVoid::ModelSupport
|
7
|
+
end
|
8
|
+
|
9
|
+
class NullMyNullableModel
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class NonNullableModel
|
14
|
+
include NullAndVoid::ModelSupport
|
15
|
+
end
|
16
|
+
|
17
|
+
describe NullAndVoid::ModelSupport do
|
18
|
+
let(:model) { FooBar::MyNullableModel.new }
|
19
|
+
|
20
|
+
it 'can convert a model into its Null Object if it exists' do
|
21
|
+
model.as_null_object.should be_a FooBar::NullMyNullableModel
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can convert the model's class into its Null Object if it exists" do
|
25
|
+
model.class.as_null_object.should be_a FooBar::NullMyNullableModel
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'can convert a model into a generic Null Object a model-specific Null Object does not exist' do
|
29
|
+
NonNullableModel.as_null_object.should be_a NullAndVoid::NullObject
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/null_object'
|
3
|
+
|
4
|
+
describe NullAndVoid::NullObject do
|
5
|
+
let(:null_object) { NullAndVoid::NullObject.instance }
|
6
|
+
|
7
|
+
it 'is a singleton' do
|
8
|
+
null_object == NullAndVoid::NullObject.instance
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'is stubbable' do
|
12
|
+
null_object.should be_a NullAndVoid::Stubbable
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'is convertible' do
|
16
|
+
null_object.should be_a NullAndVoid::Convertible
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'is falsifiable' do
|
20
|
+
null_object.should be_a NullAndVoid::Falsifiable
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/null_object'
|
3
|
+
require 'null_and_void/nullified'
|
4
|
+
|
5
|
+
class NullWidget
|
6
|
+
include NullAndVoid::Nullified
|
7
|
+
|
8
|
+
def my_null_object_method
|
9
|
+
'i am null'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe NullAndVoid::Nullified do
|
14
|
+
let(:null_object) { NullWidget.instance }
|
15
|
+
|
16
|
+
it 'is a singleton' do
|
17
|
+
null_object == NullWidget.instance
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'is not a NullAndVoid::NullObject singleton' do
|
21
|
+
null_object != NullAndVoid::NullObject.instance
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'handles undefined methods' do
|
25
|
+
null_object.foobar.should eql NullWidget.instance
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'handles conversions' do
|
29
|
+
null_object.to_a.should eql []
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'is falsifiable' do
|
33
|
+
(!!null_object).should be_false
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'can implement its own methods' do
|
37
|
+
null_object.my_null_object_method.should eql 'i am null'
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/stubbable'
|
3
|
+
|
4
|
+
class NullObject
|
5
|
+
include NullAndVoid::Stubbable
|
6
|
+
end
|
7
|
+
|
8
|
+
describe NullAndVoid::Stubbable do
|
9
|
+
let(:null_object) { NullObject.new }
|
10
|
+
|
11
|
+
it 'returns itself for all unknown method calls' do
|
12
|
+
null_object.foobar.should eql null_object
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: null_and_void
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- jfelchner
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.1'
|
21
|
+
none: false
|
22
|
+
prerelease: false
|
23
|
+
type: :runtime
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '3.1'
|
29
|
+
none: false
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ~>
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '2.12'
|
37
|
+
none: false
|
38
|
+
prerelease: false
|
39
|
+
type: :development
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '2.12'
|
45
|
+
none: false
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspectacular
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0.7'
|
53
|
+
none: false
|
54
|
+
prerelease: false
|
55
|
+
type: :development
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.7'
|
61
|
+
none: false
|
62
|
+
description: Makes generating Null Objects easy.
|
63
|
+
email: accounts+git@thekompanee.com
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files:
|
67
|
+
- README.md
|
68
|
+
files:
|
69
|
+
- lib/null_and_void/convertible.rb
|
70
|
+
- lib/null_and_void/falsifiable.rb
|
71
|
+
- lib/null_and_void/maybe.rb
|
72
|
+
- lib/null_and_void/model_support.rb
|
73
|
+
- lib/null_and_void/null_object.rb
|
74
|
+
- lib/null_and_void/nullified.rb
|
75
|
+
- lib/null_and_void/stubbable.rb
|
76
|
+
- lib/null_and_void/version.rb
|
77
|
+
- lib/null_and_void.rb
|
78
|
+
- Rakefile
|
79
|
+
- README.md
|
80
|
+
- spec/convertible_spec.rb
|
81
|
+
- spec/falsifiable_spec.rb
|
82
|
+
- spec/maybe_spec.rb
|
83
|
+
- spec/model_support_spec.rb
|
84
|
+
- spec/null_and_void_spec.rb
|
85
|
+
- spec/null_object_spec.rb
|
86
|
+
- spec/nullified_spec.rb
|
87
|
+
- spec/stubbable_spec.rb
|
88
|
+
homepage: https://github.com/jfelchner/null_and_void
|
89
|
+
licenses: []
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options:
|
92
|
+
- --charset = UTF-8
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
none: false
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
none: false
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project: null_and_void
|
109
|
+
rubygems_version: 1.8.25
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: Easy Null Objects
|
113
|
+
test_files:
|
114
|
+
- spec/convertible_spec.rb
|
115
|
+
- spec/falsifiable_spec.rb
|
116
|
+
- spec/maybe_spec.rb
|
117
|
+
- spec/model_support_spec.rb
|
118
|
+
- spec/null_and_void_spec.rb
|
119
|
+
- spec/null_object_spec.rb
|
120
|
+
- spec/nullified_spec.rb
|
121
|
+
- spec/stubbable_spec.rb
|
122
|
+
has_rdoc:
|