naught 0.0.2 → 0.0.3
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 +4 -0
- data/.travis.yml +2 -0
- data/Changelog.md +6 -0
- data/Gemfile +1 -0
- data/Guardfile +10 -0
- data/README.markdown +413 -0
- data/Rakefile +5 -0
- data/lib/naught.rb +1 -4
- data/lib/naught/null_class_builder.rb +37 -137
- data/lib/naught/null_class_builder/command.rb +20 -0
- data/lib/naught/null_class_builder/commands.rb +8 -0
- data/lib/naught/null_class_builder/commands/define_explicit_conversions.rb +13 -24
- data/lib/naught/null_class_builder/commands/define_implicit_conversions.rb +14 -0
- data/lib/naught/null_class_builder/commands/impersonate.rb +9 -0
- data/lib/naught/null_class_builder/commands/mimic.rb +40 -0
- data/lib/naught/null_class_builder/commands/pebble.rb +36 -0
- data/lib/naught/null_class_builder/commands/predicates_return.rb +47 -0
- data/lib/naught/null_class_builder/commands/singleton.rb +24 -0
- data/lib/naught/null_class_builder/commands/traceable.rb +19 -0
- data/lib/naught/null_class_builder/conversions_module.rb +57 -0
- data/lib/naught/version.rb +1 -1
- data/naught.gemspec +2 -1
- data/spec/base_object_spec.rb +47 -0
- data/spec/basic_null_object_spec.rb +35 -0
- data/spec/blackhole_spec.rb +16 -0
- data/spec/conversions_spec.rb +20 -0
- data/spec/functions/actual_spec.rb +22 -0
- data/spec/functions/just_spec.rb +22 -0
- data/spec/functions/maybe_spec.rb +35 -0
- data/spec/functions/null_spec.rb +34 -0
- data/spec/implicit_conversions_spec.rb +25 -0
- data/spec/mimic_spec.rb +122 -0
- data/spec/naught/null_object_builder/command_spec.rb +10 -0
- data/spec/naught/null_object_builder_spec.rb +31 -0
- data/spec/naught_spec.rb +77 -411
- data/spec/pebble_spec.rb +75 -0
- data/spec/predicate_spec.rb +80 -0
- data/spec/singleton_null_object_spec.rb +35 -0
- data/spec/spec_helper.rb +13 -1
- data/spec/support/convertable_null.rb +4 -0
- metadata +76 -32
- data/.rspec +0 -1
- data/README.org +0 -340
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'naught/null_class_builder/command'
|
2
|
+
|
3
|
+
module Naught::NullClassBuilder::Commands
|
4
|
+
class PredicatesReturn < Naught::NullClassBuilder::Command
|
5
|
+
def initialize(builder, return_value)
|
6
|
+
super(builder)
|
7
|
+
@predicate_return_value = return_value
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
defer do |subject|
|
12
|
+
define_method_missing(subject)
|
13
|
+
define_predicate_methods(subject)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def define_method_missing(subject)
|
20
|
+
subject.module_exec(@predicate_return_value) do |return_value|
|
21
|
+
if subject.method_defined?(:method_missing)
|
22
|
+
original_method_missing = instance_method(:method_missing)
|
23
|
+
define_method(:method_missing) do
|
24
|
+
|method_name, *args, &block|
|
25
|
+
if method_name.to_s.end_with?('?')
|
26
|
+
return_value
|
27
|
+
else
|
28
|
+
original_method_missing.bind(self).call(method_name, *args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def define_predicate_methods(subject)
|
36
|
+
subject.module_exec(@predicate_return_value) do |return_value|
|
37
|
+
instance_methods.each do |method_name|
|
38
|
+
if method_name.to_s.end_with?('?')
|
39
|
+
define_method(method_name) do |*|
|
40
|
+
return_value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'naught/null_class_builder/command'
|
2
|
+
|
3
|
+
module Naught::NullClassBuilder::Commands
|
4
|
+
class Singleton < Naught::NullClassBuilder::Command
|
5
|
+
def call
|
6
|
+
defer(class: true) do |subject|
|
7
|
+
require 'singleton'
|
8
|
+
subject.module_eval do
|
9
|
+
include ::Singleton
|
10
|
+
|
11
|
+
def self.get(*)
|
12
|
+
instance
|
13
|
+
end
|
14
|
+
|
15
|
+
%w(dup clone).each do |method_name|
|
16
|
+
define_method method_name do
|
17
|
+
self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'naught/null_class_builder/command'
|
2
|
+
|
3
|
+
module Naught::NullClassBuilder::Commands
|
4
|
+
class Traceable < Naught::NullClassBuilder::Command
|
5
|
+
def call
|
6
|
+
defer do |subject|
|
7
|
+
subject.module_eval do
|
8
|
+
attr_reader :__file__, :__line__
|
9
|
+
|
10
|
+
def initialize(options={})
|
11
|
+
backtrace = options.fetch(:caller) { Kernel.caller(4) }
|
12
|
+
@__file__, line, _ = backtrace[0].split(':')
|
13
|
+
@__line__ = line.to_i
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Naught
|
2
|
+
class ConversionsModule < Module
|
3
|
+
attr_reader :null_class
|
4
|
+
attr_reader :null_equivs
|
5
|
+
|
6
|
+
def initialize(null_class, null_equivs)
|
7
|
+
@null_class = null_class
|
8
|
+
@null_equivs = null_equivs
|
9
|
+
mod = self
|
10
|
+
super() do
|
11
|
+
%w[Null Maybe Just Actual].each do |method_name|
|
12
|
+
define_method(method_name, &mod.method(method_name))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def Null(object=:nothing_passed)
|
18
|
+
case object
|
19
|
+
when NullObjectTag then object
|
20
|
+
when :nothing_passed, *null_equivs
|
21
|
+
null_class.get(caller: caller(1))
|
22
|
+
else raise ArgumentError, "#{object.inspect} is not null!"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def Maybe(object=nil, &block)
|
27
|
+
object = block ? block.call : object
|
28
|
+
case object
|
29
|
+
when NullObjectTag then object
|
30
|
+
when *null_equivs
|
31
|
+
null_class.get(caller: caller(1))
|
32
|
+
else
|
33
|
+
object
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def Just(object=nil, &block)
|
38
|
+
object = block ? block.call : object
|
39
|
+
case object
|
40
|
+
when NullObjectTag, *null_equivs
|
41
|
+
raise ArgumentError, "Null value: #{object.inspect}"
|
42
|
+
else
|
43
|
+
object
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def Actual(object=nil, &block)
|
48
|
+
object = block ? block.call : object
|
49
|
+
case object
|
50
|
+
when NullObjectTag then nil
|
51
|
+
else
|
52
|
+
object
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
data/lib/naught/version.rb
CHANGED
data/naught.gemspec
CHANGED
@@ -20,7 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
24
24
|
spec.add_development_dependency "guard"
|
25
25
|
spec.add_development_dependency "guard-rspec"
|
26
|
+
spec.add_development_dependency "guard-bundler"
|
26
27
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'null object with a custom base class' do
|
4
|
+
|
5
|
+
subject(:null) { custom_base_null_class.new }
|
6
|
+
|
7
|
+
let(:custom_base_null_class) do
|
8
|
+
Naught.build do |b|
|
9
|
+
b.base_class = Object
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'respond to base class methods' do
|
14
|
+
expect(null.methods).to be_a_kind_of(Array)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'respond to unknown methods' do
|
18
|
+
expect(null.foo).to be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'exposes the default base class choice, for the curious' do
|
22
|
+
default_base_class = :not_set
|
23
|
+
Naught.build do |b|
|
24
|
+
default_base_class = b.base_class
|
25
|
+
end
|
26
|
+
expect(default_base_class).to eq(BasicObject)
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'singleton null object' do
|
30
|
+
subject(:null_instance) { custom_base_singleton_null_class.instance }
|
31
|
+
|
32
|
+
let(:custom_base_singleton_null_class) do
|
33
|
+
Naught.build do |b|
|
34
|
+
b.singleton
|
35
|
+
b.base_class = Object
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'can be cloned' do
|
40
|
+
expect(null_instance.clone).to be(null_instance)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'can be duplicated' do
|
44
|
+
expect(null_instance.dup).to be(null_instance)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'basic null object' do
|
4
|
+
let(:null_class) { Naught.build }
|
5
|
+
subject(:null) { null_class.new }
|
6
|
+
|
7
|
+
it 'responds to arbitrary messages and returns nil' do
|
8
|
+
expect(null.info).to be_nil
|
9
|
+
expect(null.foobaz).to be_nil
|
10
|
+
expect(null.to_s).to be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'accepts any arguments for any messages' do
|
14
|
+
null.foobaz(1,2,3)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'reports that it responds to any message' do
|
18
|
+
expect(null).to respond_to(:info)
|
19
|
+
expect(null).to respond_to(:foobaz)
|
20
|
+
expect(null).to respond_to(:to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'can be inspected' do
|
24
|
+
expect(null.inspect).to eq("<null>")
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'knows its own class' do
|
28
|
+
expect(null.class).to eq(null_class)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'aliases .new to .get' do
|
32
|
+
expect(null_class.get.class).to be(null_class)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'black hole null object' do
|
4
|
+
subject(:null) { null_class.new }
|
5
|
+
let(:null_class) {
|
6
|
+
Naught.build do |b|
|
7
|
+
b.black_hole
|
8
|
+
end
|
9
|
+
}
|
10
|
+
|
11
|
+
it 'returns self from arbitray method calls' do
|
12
|
+
expect(null.info).to be(null)
|
13
|
+
expect(null.foobaz).to be(null)
|
14
|
+
expect(null << "bar").to be(null)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe 'explicitly convertable null object' do
|
4
|
+
let(:null_class) {
|
5
|
+
Naught.build do |b|
|
6
|
+
b.define_explicit_conversions
|
7
|
+
end
|
8
|
+
}
|
9
|
+
subject(:null) { null_class.new }
|
10
|
+
|
11
|
+
it "defines common explicit conversions to return zero values" do
|
12
|
+
expect(null.to_s).to eq("")
|
13
|
+
expect(null.to_a).to eq([])
|
14
|
+
expect(null.to_i).to eq(0)
|
15
|
+
expect(null.to_f).to eq(0.0)
|
16
|
+
expect(null.to_c).to eq(Complex(0))
|
17
|
+
expect(null.to_r).to eq(Rational(0))
|
18
|
+
expect(null.to_h).to eq({})
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Actual()' do
|
4
|
+
include ConvertableNull::Conversions
|
5
|
+
|
6
|
+
specify 'given a null object, returns nil' do
|
7
|
+
null = ConvertableNull.get
|
8
|
+
expect(Actual(null)).to be_nil
|
9
|
+
end
|
10
|
+
|
11
|
+
specify 'given anything else, returns the input unchanged' do
|
12
|
+
expect(Actual(false)).to be(false)
|
13
|
+
str = "hello"
|
14
|
+
expect(Actual(str)).to be(str)
|
15
|
+
expect(Actual(nil)).to be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'also works with blocks' do
|
19
|
+
expect(Actual{ConvertableNull.new}).to be_nil
|
20
|
+
expect(Actual{"foo"}).to eq("foo")
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Just()' do
|
4
|
+
include ConvertableNull::Conversions
|
5
|
+
|
6
|
+
specify 'passes non-nullish values through' do
|
7
|
+
expect(Just(false)).to be(false)
|
8
|
+
str = "hello"
|
9
|
+
expect(Just(str)).to be(str)
|
10
|
+
end
|
11
|
+
|
12
|
+
specify 'rejects nullish values' do
|
13
|
+
expect{Just(nil)}.to raise_error(ArgumentError)
|
14
|
+
expect{Just("")}.to raise_error(ArgumentError)
|
15
|
+
expect{Just(ConvertableNull.get)}.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'also works with blocks' do
|
19
|
+
expect{Just{nil}.class}.to raise_error(ArgumentError)
|
20
|
+
expect(Just{"foo"}).to eq("foo")
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Maybe()' do
|
4
|
+
include ConvertableNull::Conversions
|
5
|
+
|
6
|
+
specify 'given nil, returns a null object' do
|
7
|
+
expect(Maybe(nil).class).to be(ConvertableNull)
|
8
|
+
end
|
9
|
+
|
10
|
+
specify 'given a null object, returns the same null object' do
|
11
|
+
null = ConvertableNull.get
|
12
|
+
expect(Maybe(null)).to be(null)
|
13
|
+
end
|
14
|
+
|
15
|
+
specify 'given anything in null_equivalents, return a null object' do
|
16
|
+
expect(Maybe("").class).to be(ConvertableNull)
|
17
|
+
end
|
18
|
+
|
19
|
+
specify 'given anything else, returns the input unchanged' do
|
20
|
+
expect(Maybe(false)).to be(false)
|
21
|
+
str = "hello"
|
22
|
+
expect(Maybe(str)).to be(str)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'generates null objects with useful trace info' do
|
26
|
+
null = Maybe(); line = __LINE__
|
27
|
+
expect(null.__line__).to eq(line)
|
28
|
+
expect(null.__file__).to eq(__FILE__)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'also works with blocks' do
|
32
|
+
expect(Maybe{nil}.class).to eq(ConvertableNull)
|
33
|
+
expect(Maybe{"foo"}).to eq("foo")
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Null()' do
|
4
|
+
include ConvertableNull::Conversions
|
5
|
+
|
6
|
+
specify 'given no input, returns a null object' do
|
7
|
+
expect(Null().class).to be(ConvertableNull)
|
8
|
+
end
|
9
|
+
|
10
|
+
specify 'given nil, returns a null object' do
|
11
|
+
expect(Null(nil).class).to be(ConvertableNull)
|
12
|
+
end
|
13
|
+
|
14
|
+
specify 'given a null object, returns the same null object' do
|
15
|
+
null = ConvertableNull.get
|
16
|
+
expect(Null(null)).to be(null)
|
17
|
+
end
|
18
|
+
|
19
|
+
specify 'given anything in null_equivalents, return a null object' do
|
20
|
+
expect(Null("").class).to be(ConvertableNull)
|
21
|
+
end
|
22
|
+
|
23
|
+
specify 'given anything else, raises an ArgumentError' do
|
24
|
+
expect{Null(false)}.to raise_error(ArgumentError)
|
25
|
+
expect{Null("hello")}.to raise_error(ArgumentError)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'generates null objects with useful trace info' do
|
29
|
+
null = Null(); line = __LINE__
|
30
|
+
expect(null.__line__).to eq(line)
|
31
|
+
expect(null.__file__).to eq(__FILE__)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'implicitly convertable null object' do
|
4
|
+
subject(:null) { null_class.new }
|
5
|
+
let(:null_class) {
|
6
|
+
Naught.build do |b|
|
7
|
+
b.define_implicit_conversions
|
8
|
+
end
|
9
|
+
}
|
10
|
+
it 'implicitly splats the same way an empty array does' do
|
11
|
+
a, b = null
|
12
|
+
expect(a).to be_nil
|
13
|
+
expect(b).to be_nil
|
14
|
+
end
|
15
|
+
it 'is implicitly convertable to String' do
|
16
|
+
expect(eval(null)).to be_nil
|
17
|
+
end
|
18
|
+
it 'implicitly converts to an empty array' do
|
19
|
+
expect(null.to_ary).to eq([])
|
20
|
+
end
|
21
|
+
it 'implicitly converts to an empty string' do
|
22
|
+
expect(null.to_str).to eq("")
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/spec/mimic_spec.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
describe 'null object mimicking a class' do
|
5
|
+
class User
|
6
|
+
def login; "bob"; end
|
7
|
+
end
|
8
|
+
|
9
|
+
module Authorizable
|
10
|
+
def authorized_for?(object); true; end
|
11
|
+
end
|
12
|
+
|
13
|
+
class LibraryPatron < User
|
14
|
+
include Authorizable
|
15
|
+
|
16
|
+
def member?; true; end
|
17
|
+
def name; "Bob"; end
|
18
|
+
def notify_of_overdue_books(titles); puts 'Notifying...'; end
|
19
|
+
end
|
20
|
+
|
21
|
+
subject(:null) { mimic_class.new }
|
22
|
+
let(:mimic_class) {
|
23
|
+
Naught.build do |b|
|
24
|
+
b.mimic LibraryPatron
|
25
|
+
end
|
26
|
+
}
|
27
|
+
it 'responds to all methods defined on the target class' do
|
28
|
+
expect(null.member?).to be_nil
|
29
|
+
expect(null.name).to be_nil
|
30
|
+
expect(null.notify_of_overdue_books(['The Grapes of Wrath'])).to be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'does not respond to methods not defined on the target class' do
|
34
|
+
expect{null.foobar}.to raise_error(NoMethodError)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'reports which messages it does and does not respond to' do
|
38
|
+
expect(null).to respond_to(:member?)
|
39
|
+
expect(null).to respond_to(:name)
|
40
|
+
expect(null).to respond_to(:notify_of_overdue_books)
|
41
|
+
expect(null).not_to respond_to(:foobar)
|
42
|
+
end
|
43
|
+
it 'has an informative inspect string' do
|
44
|
+
expect(null.inspect).to eq("<null:LibraryPatron>")
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'excludes Object methods from being mimicked' do
|
48
|
+
expect(null.object_id).not_to be_nil
|
49
|
+
expect(null.hash).not_to be_nil
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'includes inherited methods' do
|
53
|
+
expect(null.authorized_for?('something')).to be_nil
|
54
|
+
expect(null.login).to be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'with include_super: false' do
|
58
|
+
let(:mimic_class) {
|
59
|
+
Naught.build do |b|
|
60
|
+
b.mimic LibraryPatron, include_super: false
|
61
|
+
end
|
62
|
+
}
|
63
|
+
|
64
|
+
it 'excludes inherited methods' do
|
65
|
+
expect(null).to_not respond_to(:authorized_for?)
|
66
|
+
expect(null).to_not respond_to(:login)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'using mimic with black_hole' do
|
72
|
+
subject(:null) { mimic_class.new }
|
73
|
+
let(:mimic_class) {
|
74
|
+
Naught.build do |b|
|
75
|
+
b.mimic Logger
|
76
|
+
b.black_hole
|
77
|
+
end
|
78
|
+
}
|
79
|
+
|
80
|
+
def self.it_behaves_like_a_black_hole_mimic
|
81
|
+
it 'returns self from mimicked methods' do
|
82
|
+
expect(null.info).to equal(null)
|
83
|
+
expect(null.error).to equal(null)
|
84
|
+
expect(null << "test").to equal(null)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'does not respond to methods not defined on the target class' do
|
88
|
+
expect{null.foobar}.to raise_error(NoMethodError)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it_behaves_like_a_black_hole_mimic
|
93
|
+
|
94
|
+
describe '(reverse order)' do
|
95
|
+
let(:mimic_class) {
|
96
|
+
Naught.build do |b|
|
97
|
+
b.black_hole
|
98
|
+
b.mimic Logger
|
99
|
+
end
|
100
|
+
}
|
101
|
+
|
102
|
+
it_behaves_like_a_black_hole_mimic
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
describe 'mimicking a non-Object-derived class' do
|
108
|
+
class MinimalClass < BasicObject
|
109
|
+
end
|
110
|
+
|
111
|
+
subject(:null) { mimic_class.new }
|
112
|
+
let(:mimic_class) {
|
113
|
+
Naught.build do |b|
|
114
|
+
b.mimic MinimalClass
|
115
|
+
end
|
116
|
+
}
|
117
|
+
|
118
|
+
it 'generates a BasicObject-derived null class' do
|
119
|
+
expect(BasicObject).to be === null
|
120
|
+
expect(Object).not_to be === null
|
121
|
+
end
|
122
|
+
end
|