naught 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.
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/Gemfile +8 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.org +340 -0
- data/Rakefile +1 -0
- data/bin/autospec +16 -0
- data/bin/coderay +16 -0
- data/bin/guard +16 -0
- data/bin/htmldiff +16 -0
- data/bin/ldiff +16 -0
- data/bin/pry +16 -0
- data/bin/rake +16 -0
- data/bin/rspec +16 -0
- data/bin/thor +16 -0
- data/lib/naught.rb +16 -0
- data/lib/naught/null_class_builder.rb +274 -0
- data/lib/naught/null_class_builder/commands/define_explicit_conversions.rb +30 -0
- data/lib/naught/version.rb +3 -0
- data/naught.gemspec +26 -0
- data/spec/naught_spec.rb +429 -0
- data/spec/spec_helper.rb +1 -0
- metadata +161 -0
data/spec/naught_spec.rb
ADDED
@@ -0,0 +1,429 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'naught'
|
3
|
+
|
4
|
+
module Naught
|
5
|
+
describe 'basic null object' do
|
6
|
+
subject(:null) { null_class.new }
|
7
|
+
let(:null_class) {
|
8
|
+
Naught.build
|
9
|
+
}
|
10
|
+
it 'responds to arbitrary messages and returns nil' do
|
11
|
+
expect(null.info).to be_nil
|
12
|
+
expect(null.foobaz).to be_nil
|
13
|
+
expect(null.to_s).to be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'accepts any arguments for any messages' do
|
17
|
+
null.foobaz(1,2,3)
|
18
|
+
end
|
19
|
+
it 'reports that it responds to any message' do
|
20
|
+
expect(null).to respond_to(:info)
|
21
|
+
expect(null).to respond_to(:foobaz)
|
22
|
+
expect(null).to respond_to(:to_s)
|
23
|
+
end
|
24
|
+
it 'can be inspected' do
|
25
|
+
expect(null.inspect).to eq("<null>")
|
26
|
+
end
|
27
|
+
it 'knows its own class' do
|
28
|
+
expect(null.class).to eq(null_class)
|
29
|
+
end
|
30
|
+
it 'aliases .new to .get' do
|
31
|
+
expect(null_class.get.class).to be(null_class)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
describe 'explicitly convertable null object' do
|
35
|
+
subject(:null) { null_class.new }
|
36
|
+
let(:null_class) {
|
37
|
+
Naught.build do |b|
|
38
|
+
b.define_explicit_conversions
|
39
|
+
end
|
40
|
+
}
|
41
|
+
|
42
|
+
it "defines common explicit conversions to return zero values" do
|
43
|
+
expect(null.to_s).to eq("")
|
44
|
+
expect(null.to_a).to eq([])
|
45
|
+
expect(null.to_i).to eq(0)
|
46
|
+
expect(null.to_f).to eq(0.0)
|
47
|
+
expect(null.to_c).to eq(Complex(0))
|
48
|
+
expect(null.to_r).to eq(Rational(0))
|
49
|
+
expect(null.to_h).to eq({})
|
50
|
+
end
|
51
|
+
end
|
52
|
+
describe 'implicitly convertable null object' do
|
53
|
+
subject(:null) { null_class.new }
|
54
|
+
let(:null_class) {
|
55
|
+
Naught.build do |b|
|
56
|
+
b.define_implicit_conversions
|
57
|
+
end
|
58
|
+
}
|
59
|
+
it 'implicitly splats the same way an empty array does' do
|
60
|
+
a, b = null
|
61
|
+
expect(a).to be_nil
|
62
|
+
expect(b).to be_nil
|
63
|
+
end
|
64
|
+
it 'is implicitly convertable to String' do
|
65
|
+
expect(eval(null)).to be_nil
|
66
|
+
end
|
67
|
+
it 'implicitly converts to an empty array' do
|
68
|
+
expect(null.to_ary).to eq([])
|
69
|
+
end
|
70
|
+
it 'implicitly converts to an empty string' do
|
71
|
+
expect(null.to_str).to eq("")
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
describe 'singleton null object' do
|
76
|
+
subject(:null_class) {
|
77
|
+
Naught.build do |b|
|
78
|
+
b.singleton
|
79
|
+
end
|
80
|
+
}
|
81
|
+
|
82
|
+
it 'does not respond to .new' do
|
83
|
+
expect{ null_class.new }.to raise_error
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'has only one instance' do
|
87
|
+
null1 = null_class.instance
|
88
|
+
null2 = null_class.instance
|
89
|
+
expect(null1).to be(null2)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'can be cloned' do
|
93
|
+
null = null_class.instance
|
94
|
+
expect(null.clone).to be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'can be duplicated' do
|
98
|
+
null = null_class.instance
|
99
|
+
expect(null.dup).to be_nil
|
100
|
+
end
|
101
|
+
it 'aliases .instance to .get' do
|
102
|
+
expect(null_class.get).to be null_class.instance
|
103
|
+
end
|
104
|
+
it 'permits arbitrary arguments to be passed to .get' do
|
105
|
+
null_class.get(42, foo: "bar")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
describe 'black hole null object' do
|
109
|
+
subject(:null) { null_class.new }
|
110
|
+
let(:null_class) {
|
111
|
+
Naught.build do |b|
|
112
|
+
b.black_hole
|
113
|
+
end
|
114
|
+
}
|
115
|
+
|
116
|
+
it 'returns self from arbitray method calls' do
|
117
|
+
expect(null.info).to be(null)
|
118
|
+
expect(null.foobaz).to be(null)
|
119
|
+
expect(null << "bar").to be(null)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
describe 'null object mimicking a class' do
|
123
|
+
class User
|
124
|
+
def login
|
125
|
+
"bob"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
module Authorizable
|
130
|
+
def authorized_for?(object)
|
131
|
+
true
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
class LibraryPatron < User
|
136
|
+
include Authorizable
|
137
|
+
|
138
|
+
def member?; true; end
|
139
|
+
def name; "Bob"; end
|
140
|
+
def notify_of_overdue_books(titles)
|
141
|
+
puts "Notifying Bob his books are overdue..."
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
subject(:null) { mimic_class.new }
|
146
|
+
let(:mimic_class) {
|
147
|
+
Naught.build do |b|
|
148
|
+
b.mimic LibraryPatron
|
149
|
+
end
|
150
|
+
}
|
151
|
+
it 'responds to all methods defined on the target class' do
|
152
|
+
expect(null.member?).to be_nil
|
153
|
+
expect(null.name).to be_nil
|
154
|
+
expect(null.notify_of_overdue_books(['The Grapes of Wrath'])).to be_nil
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'does not respond to methods not defined on the target class' do
|
158
|
+
expect{null.foobar}.to raise_error(NoMethodError)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'reports which messages it does and does not respond to' do
|
162
|
+
expect(null).to respond_to(:member?)
|
163
|
+
expect(null).to respond_to(:name)
|
164
|
+
expect(null).to respond_to(:notify_of_overdue_books)
|
165
|
+
expect(null).not_to respond_to(:foobar)
|
166
|
+
end
|
167
|
+
it 'has an informative inspect string' do
|
168
|
+
expect(null.inspect).to eq("<null:Naught::LibraryPatron>")
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'excludes Object methods from being mimicked' do
|
172
|
+
expect(null.object_id).not_to be_nil
|
173
|
+
expect(null.hash).not_to be_nil
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'includes inherited methods' do
|
177
|
+
expect(null.authorized_for?('something')).to be_nil
|
178
|
+
expect(null.login).to be_nil
|
179
|
+
end
|
180
|
+
|
181
|
+
describe 'with include_super: false' do
|
182
|
+
let(:mimic_class) {
|
183
|
+
Naught.build do |b|
|
184
|
+
b.mimic LibraryPatron, include_super: false
|
185
|
+
end
|
186
|
+
}
|
187
|
+
|
188
|
+
it 'excludes inherited methods' do
|
189
|
+
expect(null).to_not respond_to(:authorized_for?)
|
190
|
+
expect(null).to_not respond_to(:login)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
describe 'using mimic with black_hole' do
|
195
|
+
require 'logger'
|
196
|
+
subject(:null) { mimic_class.new }
|
197
|
+
let(:mimic_class) {
|
198
|
+
Naught.build do |b|
|
199
|
+
b.mimic Logger
|
200
|
+
b.black_hole
|
201
|
+
end
|
202
|
+
}
|
203
|
+
|
204
|
+
def self.it_behaves_like_a_black_hole_mimic
|
205
|
+
it 'returns self from mimicked methods' do
|
206
|
+
expect(null.info).to equal(null)
|
207
|
+
expect(null.error).to equal(null)
|
208
|
+
expect(null << "test").to equal(null)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'does not respond to methods not defined on the target class' do
|
212
|
+
expect{null.foobar}.to raise_error(NoMethodError)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
it_behaves_like_a_black_hole_mimic
|
217
|
+
|
218
|
+
describe '(reverse order)' do
|
219
|
+
let(:mimic_class) {
|
220
|
+
Naught.build do |b|
|
221
|
+
b.black_hole
|
222
|
+
b.mimic Logger
|
223
|
+
end
|
224
|
+
}
|
225
|
+
|
226
|
+
it_behaves_like_a_black_hole_mimic
|
227
|
+
end
|
228
|
+
end
|
229
|
+
describe 'null object impersonating another type' do
|
230
|
+
class Point
|
231
|
+
def x; 23; end
|
232
|
+
def y; 42; end
|
233
|
+
end
|
234
|
+
|
235
|
+
subject(:null) { impersonation_class.new }
|
236
|
+
let(:impersonation_class) {
|
237
|
+
Naught.build do |b|
|
238
|
+
b.impersonate Point
|
239
|
+
end
|
240
|
+
}
|
241
|
+
|
242
|
+
it 'matches the impersonated type' do
|
243
|
+
expect(Point).to be === null
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'responds to methods from the impersonated type' do
|
247
|
+
expect(null.x).to be_nil
|
248
|
+
expect(null.y).to be_nil
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'does not respond to unknown methods' do
|
252
|
+
expect{null.foo}.to raise_error(NoMethodError)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
describe 'traceable null object' do
|
256
|
+
subject(:trace_null) {
|
257
|
+
null_object_and_line.first
|
258
|
+
}
|
259
|
+
let(:null_object_and_line) {
|
260
|
+
obj = trace_null_class.new; line = __LINE__;
|
261
|
+
[obj, line]
|
262
|
+
}
|
263
|
+
let(:instantiation_line) { null_object_and_line.last }
|
264
|
+
let(:trace_null_class) {
|
265
|
+
Naught.build do |b|
|
266
|
+
b.traceable
|
267
|
+
end
|
268
|
+
}
|
269
|
+
|
270
|
+
it 'remembers the file it was instantiated from' do
|
271
|
+
expect(trace_null.__file__).to eq(__FILE__)
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'remembers the line it was instantiated from' do
|
275
|
+
expect(trace_null.__line__).to eq(instantiation_line)
|
276
|
+
end
|
277
|
+
def make_null
|
278
|
+
trace_null_class.get(caller: caller(1))
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'can accept custom backtrace info' do
|
282
|
+
obj = make_null; line = __LINE__
|
283
|
+
expect(obj.__line__).to eq(line)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
describe 'customized null object' do
|
287
|
+
subject(:custom_null) { custom_null_class.new }
|
288
|
+
let(:custom_null_class) {
|
289
|
+
Naught.build do |b|
|
290
|
+
b.define_explicit_conversions
|
291
|
+
def to_path
|
292
|
+
"/dev/null"
|
293
|
+
end
|
294
|
+
def to_s
|
295
|
+
"NOTHING TO SEE HERE"
|
296
|
+
end
|
297
|
+
end
|
298
|
+
}
|
299
|
+
|
300
|
+
it 'responds to custom-defined methods' do
|
301
|
+
expect(custom_null.to_path).to eq("/dev/null")
|
302
|
+
end
|
303
|
+
|
304
|
+
it 'allows generated methods to be overridden' do
|
305
|
+
expect(custom_null.to_s).to eq("NOTHING TO SEE HERE")
|
306
|
+
end
|
307
|
+
end
|
308
|
+
TestNull = Naught.build
|
309
|
+
|
310
|
+
describe 'a named null object class' do
|
311
|
+
it 'has named ancestor modules' do
|
312
|
+
expect(TestNull.ancestors[0..2].map(&:name)).to eq([
|
313
|
+
'Naught::TestNull',
|
314
|
+
'Naught::TestNull::Customizations',
|
315
|
+
'Naught::TestNull::GeneratedMethods'
|
316
|
+
])
|
317
|
+
end
|
318
|
+
end
|
319
|
+
ConvertableNull = Naught.build do |b|
|
320
|
+
b.null_equivalents << ""
|
321
|
+
b.traceable
|
322
|
+
end
|
323
|
+
|
324
|
+
describe 'Null()' do
|
325
|
+
include ConvertableNull::Conversions
|
326
|
+
|
327
|
+
specify 'given no input, returns a null object' do
|
328
|
+
expect(Null().class).to be(ConvertableNull)
|
329
|
+
end
|
330
|
+
|
331
|
+
specify 'given nil, returns a null object' do
|
332
|
+
expect(Null(nil).class).to be(ConvertableNull)
|
333
|
+
end
|
334
|
+
|
335
|
+
specify 'given a null object, returns the same null object' do
|
336
|
+
null = ConvertableNull.get
|
337
|
+
expect(Null(null)).to be(null)
|
338
|
+
end
|
339
|
+
|
340
|
+
specify 'given anything in null_equivalents, return a null object' do
|
341
|
+
expect(Null("").class).to be(ConvertableNull)
|
342
|
+
end
|
343
|
+
|
344
|
+
specify 'given anything else, raises an ArgumentError' do
|
345
|
+
expect{Null(false)}.to raise_error(ArgumentError)
|
346
|
+
expect{Null("hello")}.to raise_error(ArgumentError)
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'generates null objects with useful trace info' do
|
350
|
+
null = Null(); line = __LINE__
|
351
|
+
expect(null.__line__).to eq(line)
|
352
|
+
expect(null.__file__).to eq(__FILE__)
|
353
|
+
end
|
354
|
+
|
355
|
+
end
|
356
|
+
describe 'Maybe()' do
|
357
|
+
include ConvertableNull::Conversions
|
358
|
+
|
359
|
+
specify 'given nil, returns a null object' do
|
360
|
+
expect(Maybe(nil).class).to be(ConvertableNull)
|
361
|
+
end
|
362
|
+
|
363
|
+
specify 'given a null object, returns the same null object' do
|
364
|
+
null = ConvertableNull.get
|
365
|
+
expect(Maybe(null)).to be(null)
|
366
|
+
end
|
367
|
+
|
368
|
+
specify 'given anything in null_equivalents, return a null object' do
|
369
|
+
expect(Maybe("").class).to be(ConvertableNull)
|
370
|
+
end
|
371
|
+
|
372
|
+
specify 'given anything else, returns the input unchanged' do
|
373
|
+
expect(Maybe(false)).to be(false)
|
374
|
+
str = "hello"
|
375
|
+
expect(Maybe(str)).to be(str)
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'generates null objects with useful trace info' do
|
379
|
+
null = Maybe(); line = __LINE__
|
380
|
+
expect(null.__line__).to eq(line)
|
381
|
+
expect(null.__file__).to eq(__FILE__)
|
382
|
+
end
|
383
|
+
|
384
|
+
it 'also works with blocks' do
|
385
|
+
expect(Maybe{nil}.class).to eq(ConvertableNull)
|
386
|
+
expect(Maybe{"foo"}).to eq("foo")
|
387
|
+
end
|
388
|
+
end
|
389
|
+
describe 'Just()' do
|
390
|
+
include ConvertableNull::Conversions
|
391
|
+
|
392
|
+
specify 'passes non-nullish values through' do
|
393
|
+
expect(Just(false)).to be(false)
|
394
|
+
str = "hello"
|
395
|
+
expect(Just(str)).to be(str)
|
396
|
+
end
|
397
|
+
|
398
|
+
specify 'rejects nullish values' do
|
399
|
+
expect{Just(nil)}.to raise_error(ArgumentError)
|
400
|
+
expect{Just("")}.to raise_error(ArgumentError)
|
401
|
+
expect{Just(ConvertableNull.get)}.to raise_error(ArgumentError)
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'also works with blocks' do
|
405
|
+
expect{Just{nil}.class}.to raise_error(ArgumentError)
|
406
|
+
expect(Just{"foo"}).to eq("foo")
|
407
|
+
end
|
408
|
+
end
|
409
|
+
describe 'Actual()' do
|
410
|
+
include ConvertableNull::Conversions
|
411
|
+
|
412
|
+
specify 'given a null object, returns nil' do
|
413
|
+
null = ConvertableNull.get
|
414
|
+
expect(Actual(null)).to be_nil
|
415
|
+
end
|
416
|
+
|
417
|
+
specify 'given anything else, returns the input unchanged' do
|
418
|
+
expect(Actual(false)).to be(false)
|
419
|
+
str = "hello"
|
420
|
+
expect(Actual(str)).to be(str)
|
421
|
+
expect(Actual(nil)).to be_nil
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'also works with blocks' do
|
425
|
+
expect(Actual{ConvertableNull.new}).to be_nil
|
426
|
+
expect(Actual{"foo"}).to eq("foo")
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: naught
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Avdi Grimm
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: guard
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: guard-rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Naught is a toolkit for building Null Objects
|
95
|
+
email:
|
96
|
+
- avdi@avdi.org
|
97
|
+
executables:
|
98
|
+
- autospec
|
99
|
+
- coderay
|
100
|
+
- guard
|
101
|
+
- htmldiff
|
102
|
+
- ldiff
|
103
|
+
- pry
|
104
|
+
- rake
|
105
|
+
- rspec
|
106
|
+
- thor
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- .gitignore
|
111
|
+
- .rspec
|
112
|
+
- Gemfile
|
113
|
+
- Guardfile
|
114
|
+
- LICENSE.txt
|
115
|
+
- README.org
|
116
|
+
- Rakefile
|
117
|
+
- bin/autospec
|
118
|
+
- bin/coderay
|
119
|
+
- bin/guard
|
120
|
+
- bin/htmldiff
|
121
|
+
- bin/ldiff
|
122
|
+
- bin/pry
|
123
|
+
- bin/rake
|
124
|
+
- bin/rspec
|
125
|
+
- bin/thor
|
126
|
+
- lib/naught.rb
|
127
|
+
- lib/naught/null_class_builder.rb
|
128
|
+
- lib/naught/null_class_builder/commands/define_explicit_conversions.rb
|
129
|
+
- lib/naught/version.rb
|
130
|
+
- naught.gemspec
|
131
|
+
- spec/naught_spec.rb
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
homepage: https://github.com/avdi/naught
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ! '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 1.8.24
|
155
|
+
signing_key:
|
156
|
+
specification_version: 3
|
157
|
+
summary: Naught is a toolkit for building Null Objects
|
158
|
+
test_files:
|
159
|
+
- spec/naught_spec.rb
|
160
|
+
- spec/spec_helper.rb
|
161
|
+
has_rdoc:
|