diff --git a/spec/basic_null_object_spec.rb b/spec/basic_null_object_spec.rb deleted file mode 100644 index 8674831..0000000 --- a/spec/basic_null_object_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'spec_helper' - -describe 'basic null object' do - let(:null_class) { Naught.build } - subject(:null) { null_class.new } - - it 'responds to arbitrary messages and returns nil' do - expect(null.info).to be_nil - expect(null.foobaz).to be_nil - expect(null.to_s).to be_nil - end - - it 'accepts any arguments for any messages' do - null.foobaz(1, 2, 3) - end - - it 'reports that it responds to any message' do - expect(null).to respond_to(:info) - expect(null).to respond_to(:foobaz) - expect(null).to respond_to(:to_s) - end - - it 'can be inspected' do - expect(null.inspect).to eq('') - end - - it 'knows its own class' do - expect(null.class).to eq(null_class) - end - - it 'aliases .new to .get' do - expect(null_class.get.class).to be(null_class) - end - -end diff --git a/spec/implicit_conversions_spec.rb b/spec/implicit_conversions_spec.rb deleted file mode 100644 index 88d4fb2..0000000 --- a/spec/implicit_conversions_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'spec_helper' - -describe 'implicitly convertable null object' do - subject(:null) { null_class.new } - let(:null_class) do - Naught.build do |b| - b.define_implicit_conversions - end - end - it 'implicitly splats the same way an empty array does' do - a, b = null - expect(a).to be_nil - expect(b).to be_nil - end - it 'is implicitly convertable to String' do - expect(instance_eval(null)).to be_nil - end - it 'implicitly converts to an empty array' do - expect(null.to_ary).to eq([]) - end - it 'implicitly converts to an empty string' do - expect(null.to_str).to eq('') - end - -end diff --git a/spec/base_object_spec.rb b/spec/naught/configurations/base_class_spec.rb similarity index 50% rename from spec/base_object_spec.rb rename to spec/naught/configurations/base_class_spec.rb index 66e87aa..ba659f6 100644 --- a/spec/base_object_spec.rb +++ b/spec/naught/configurations/base_class_spec.rb @@ -1,10 +1,8 @@ require 'spec_helper' describe 'null object with a custom base class' do - - subject(:null) { custom_base_null_class.new } - - let(:custom_base_null_class) do + subject(:null) { null_class.new } + let(:null_class) do Naught.build do |b| b.base_class = Object end @@ -25,23 +23,4 @@ end expect(default_base_class).to eq(Naught::BasicObject) end - - describe 'singleton null object' do - subject(:null_instance) { custom_base_singleton_null_class.instance } - - let(:custom_base_singleton_null_class) do - Naught.build do |b| - b.singleton - b.base_class = Object - end - end - - it 'can be cloned' do - expect(null_instance.clone).to be(null_instance) - end - - it 'can be duplicated' do - expect(null_instance.dup).to be(null_instance) - end - end end diff --git a/spec/blackhole_spec.rb b/spec/naught/configurations/black_hole_spec.rb similarity index 66% rename from spec/blackhole_spec.rb rename to spec/naught/configurations/black_hole_spec.rb index 79d84f2..f667e44 100644 --- a/spec/blackhole_spec.rb +++ b/spec/naught/configurations/black_hole_spec.rb @@ -13,4 +13,10 @@ expect(null.foobaz).to be(null) expect(null << 'bar').to be(null) end + + it 'supports chaining of methodcalls' do + expect(null.foo).to be(null) + expect(null.foo.bar.baz).to be(null) + expect(null << "hello" << "world").to be(null) + end end diff --git a/spec/naught/configurations/custom_methods_spec.rb b/spec/naught/configurations/custom_methods_spec.rb new file mode 100644 index 0000000..f213acd --- /dev/null +++ b/spec/naught/configurations/custom_methods_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'null object with custom methods' do + subject(:null) { null_class.new } + let(:null_class) do + Naught.build do |b| + def to_path + '/dev/null' + end + end + end + + it 'responds to defined methods ' do + expect(null.to_path).to eq('/dev/null') + end +end \ No newline at end of file diff --git a/spec/explicit_conversions_spec.rb b/spec/naught/configurations/explicit_conversions_spec.rb similarity index 56% rename from spec/explicit_conversions_spec.rb rename to spec/naught/configurations/explicit_conversions_spec.rb index 4a6d387..6536f49 100644 --- a/spec/explicit_conversions_spec.rb +++ b/spec/naught/configurations/explicit_conversions_spec.rb @@ -1,23 +1,42 @@ require 'spec_helper.rb' describe 'explicitly convertable null object' do + subject(:null) { null_class.new } let(:null_class) do Naught.build do |b| b.define_explicit_conversions end end - subject(:null) { null_class.new } - it 'defines common explicit conversions to return zero values' do + it 'returns empty string for to_s' do expect(null.to_s).to eq('') + end + + it 'returns empty array for to_a' do expect(null.to_a).to eq([]) + end + + it 'returns 0 for to_i' do expect(null.to_i).to eq(0) + end + + it 'returns 0.0 for to_f' do expect(null.to_f).to eq(0.0) - if RUBY_VERSION >= '2.0' - expect(null.to_h).to eq({}) - elsif RUBY_VERSION >= '1.9' + end + + if RUBY_VERSION >= '1.9' + it 'returns Complex(0) for to_c' do expect(null.to_c).to eq(Complex(0)) + end + + it 'returns Rational(0) for to_r' do expect(null.to_r).to eq(Rational(0)) end end + + if RUBY_VERSION >= '2.0' + it 'returns empty hash for to_h' do + expect(null.to_h).to eq({}) + end + end end diff --git a/spec/naught/configurations/impersonate_spec.rb b/spec/naught/configurations/impersonate_spec.rb new file mode 100644 index 0000000..7f377c8 --- /dev/null +++ b/spec/naught/configurations/impersonate_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe 'null object impersonating another type' do + class Point + def x + 23 + end + + def y + 42 + end + end + + subject(:null) { impersonation_class.new } + let(:impersonation_class) do + Naught.build do |b| + b.impersonate Point + end + end + + it 'matches the impersonated type' do + expect(null).to be_a Point + end + + it 'responds to methods from the impersonated type' do + expect(null.x).to be_nil + expect(null.y).to be_nil + end + + it 'does not respond to unknown methods' do + expect { null.foo }.to raise_error(NoMethodError) + end +end diff --git a/spec/naught/configurations/implicit_conversions_spec.rb b/spec/naught/configurations/implicit_conversions_spec.rb new file mode 100644 index 0000000..4624e40 --- /dev/null +++ b/spec/naught/configurations/implicit_conversions_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe 'implicitly convertable null object' do + subject(:null) { null_class.new } + let(:null_class) do + Naught.build do |b| + b.define_implicit_conversions + end + end + + context 'to_ary' do + it 'returns empty array' do + expect(null.to_ary).to eq([]) + end + + it 'makes splats possible' do + a, b = null + expect(a).to be_nil + expect(b).to be_nil + end + end + + context 'to_str' do + it 'returns empty string for to_str' do + expect(null.to_str).to eq('') + end + + it 'makes instance_eval possible' do + expect(instance_eval(null)).to be_nil + end + end +end \ No newline at end of file diff --git a/spec/mimic_spec.rb b/spec/naught/configurations/mimic_spec.rb similarity index 70% rename from spec/mimic_spec.rb rename to spec/naught/configurations/mimic_spec.rb index 4a17fbf..762ecf3 100644 --- a/spec/mimic_spec.rb +++ b/spec/naught/configurations/mimic_spec.rb @@ -36,6 +36,7 @@ def notify_of_overdue_books(titles) b.mimic LibraryPatron end end + it 'responds to all methods defined on the target class' do expect(null.member?).to be_nil expect(null.name).to be_nil @@ -52,6 +53,7 @@ def notify_of_overdue_books(titles) expect(null).to respond_to(:notify_of_overdue_books) expect(null).not_to respond_to(:foobar) end + it 'has an informative inspect string' do expect(null.inspect).to eq('') end @@ -79,39 +81,3 @@ def notify_of_overdue_books(titles) end end end - -describe 'using mimic with black_hole' do - subject(:null) { mimic_class.new } - let(:mimic_class) do - Naught.build do |b| - b.mimic Logger - b.black_hole - end - end - - def self.it_behaves_like_a_black_hole_mimic - it 'returns self from mimicked methods' do - expect(null.info).to equal(null) - expect(null.error).to equal(null) - expect(null << 'test').to equal(null) - end - - it 'does not respond to methods not defined on the target class' do - expect { null.foobar }.to raise_error(NoMethodError) - end - end - - it_behaves_like_a_black_hole_mimic - - describe '(reverse order)' do - let(:mimic_class) do - Naught.build do |b| - b.black_hole - b.mimic Logger - end - end - - it_behaves_like_a_black_hole_mimic - end - -end diff --git a/spec/pebble_spec.rb b/spec/naught/configurations/pebble_spec.rb similarity index 100% rename from spec/pebble_spec.rb rename to spec/naught/configurations/pebble_spec.rb diff --git a/spec/naught/configurations/precedence_spec.rb b/spec/naught/configurations/precedence_spec.rb new file mode 100644 index 0000000..ff9618d --- /dev/null +++ b/spec/naught/configurations/precedence_spec.rb @@ -0,0 +1,122 @@ +require 'spec_helper' + +describe 'configuration precedence of a null object' do + subject(:null) { null_class.new } + + context 'black_hole, predicates_return' do + shared_examples 'behavior' do + it 'responds to predicate-style methods with false' do + expect(null.too_much_coffee?).to eq(false) + end + + it 'responds to other methods with self' do + expect(null.foobar).to be(null) + end + end + + context 'black_hole first' do + let(:null_class) do + Naught.build do |config| + config.black_hole + config.predicates_return false + end + end + + include_examples 'behavior' + end + + context 'predicates_return first' do + let(:null_class) do + Naught.build do |config| + config.predicates_return false + config.black_hole + end + end + + include_examples 'behavior' + end + end + + context 'black_hole, mimic' do + shared_examples 'behavior' do + it 'returns self from mimicked methods' do + expect(null.info).to equal(null) + expect(null.error).to equal(null) + expect(null << 'test').to equal(null) + end + + it 'does not respond to methods not defined on the target class' do + expect { null.foobar }.to raise_error(NoMethodError) + end + end + + describe 'black_hole first' do + let(:null_class) do + Naught.build do |b| + b.black_hole + b.mimic Logger + end + end + + include_examples 'behavior' + end + + describe 'mimic first' do + let(:null_class) do + Naught.build do |b| + b.mimic Logger + b.black_hole + end + end + + include_examples 'behavior' + end + end + + context 'mimic, predicates_return' do + class Coffee + def black? + true + end + + def origin + 'Ethiopia' + end + end + + let(:null_class) do + Naught.build do |config| + config.mimic Coffee + config.predicates_return false + end + end + + it 'responds to predicate-style methods with false' do + expect(null.black?).to eq(false) + end + + it 'responds to other methods with nil' do + expect(null.origin).to be(nil) + end + + it 'does not respond to undefined methods' do + expect(null).not_to respond_to(:leaf_variety) + expect { null.leaf_variety }.to raise_error(NoMethodError) + end + end + + describe 'customs methods, define_explicit_conversions' do + let(:null_class) do + Naught.build do |b| + b.define_explicit_conversions + def to_s + 'NOTHING TO SEE HERE' + end + end + end + + it 'allows generated methods to be overridden' do + expect(null.to_s).to eq('NOTHING TO SEE HERE') + end + end +end diff --git a/spec/naught/configurations/predicate_spec.rb b/spec/naught/configurations/predicate_spec.rb new file mode 100644 index 0000000..7986053 --- /dev/null +++ b/spec/naught/configurations/predicate_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' + +describe 'a null object with predicates_return(false)' do + subject(:null) { null_class.new } + let(:null_class) do + Naught.build do |config| + config.predicates_return false + end + end + + it 'responds to predicate-style methods with false' do + expect(null.too_much_coffee?).to eq(false) + end + + it 'responds to other methods with nil' do + expect(null.foobar).to eq(nil) + end +end diff --git a/spec/singleton_null_object_spec.rb b/spec/naught/configurations/singleton_spec.rb similarity index 86% rename from spec/singleton_null_object_spec.rb rename to spec/naught/configurations/singleton_spec.rb index 0cc9a3f..a6bd45d 100644 --- a/spec/singleton_null_object_spec.rb +++ b/spec/naught/configurations/singleton_spec.rb @@ -26,10 +26,8 @@ null = null_class.instance expect(null.dup).to be(null) end + it 'aliases .instance to .get' do expect(null_class.get).to be null_class.instance end - it 'permits arbitrary arguments to be passed to .get' do - null_class.get(42, :foo => 'bar') - end end diff --git a/spec/naught/configurations/traceable_spec.rb b/spec/naught/configurations/traceable_spec.rb new file mode 100644 index 0000000..b3ac233 --- /dev/null +++ b/spec/naught/configurations/traceable_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe 'traceable null object' do + subject(:trace_null) do + null_object_and_line.first + end + let(:null_object_and_line) do + obj, line = trace_null_class.new, __LINE__ + [obj, line] + end + let(:instantiation_line) { null_object_and_line.last } + let(:trace_null_class) do + Naught.build do |b| + b.traceable + end + end + + it 'remembers the file it was instantiated from' do + expect(trace_null.__file__).to eq(__FILE__) + end + + it 'remembers the line it was instantiated from' do + expect(trace_null.__line__).to eq(instantiation_line) + end + + def make_null + trace_null_class.get(:caller => caller(1)) + end + + it 'can accept custom backtrace info' do + obj, line = make_null, __LINE__ + expect(obj.__line__).to eq(line) + end +end \ No newline at end of file diff --git a/spec/naught/null_object_builder/command_spec.rb b/spec/naught/null_class_builder/command_spec.rb similarity index 100% rename from spec/naught/null_object_builder/command_spec.rb rename to spec/naught/null_class_builder/command_spec.rb diff --git a/spec/naught/null_object_builder_spec.rb b/spec/naught/null_class_builder_spec.rb similarity index 100% rename from spec/naught/null_object_builder_spec.rb rename to spec/naught/null_class_builder_spec.rb diff --git a/spec/naught_spec.rb b/spec/naught_spec.rb index caafd04..c54da17 100644 --- a/spec/naught_spec.rb +++ b/spec/naught_spec.rb @@ -1,101 +1,35 @@ require 'spec_helper' -describe 'null object impersonating another type' do - class Point - def x - 23 - end +describe 'base null object' do + subject(:null) { null_class.new } + let(:null_class) { Naught.build } - def y - 42 - end + it 'responds to arbitrary messages and returns nil' do + expect(null.info).to be_nil + expect(null.foobaz).to be_nil + expect(null.to_s).to be_nil end - subject(:null) { impersonation_class.new } - let(:impersonation_class) do - Naught.build do |b| - b.impersonate Point - end + it 'accepts any arguments for any messages' do + null.foobaz(1, 2, 3) end - it 'matches the impersonated type' do - expect(null).to be_a Point + it 'reports that it responds to any message' do + expect(null).to respond_to(:info) + expect(null).to respond_to(:foobaz) + expect(null).to respond_to(:to_s) end - it 'responds to methods from the impersonated type' do - expect(null.x).to be_nil - expect(null.y).to be_nil + it 'can be inspected' do + expect(null.inspect).to eq('') end - it 'does not respond to unknown methods' do - expect { null.foo }.to raise_error(NoMethodError) - end -end - -describe 'traceable null object' do - subject(:trace_null) do - null_object_and_line.first - end - let(:null_object_and_line) do - obj, line = trace_null_class.new, __LINE__ - [obj, line] - end - let(:instantiation_line) { null_object_and_line.last } - let(:trace_null_class) do - Naught.build do |b| - b.traceable - end + it 'knows its own class' do + expect(null.class).to eq(null_class) end - it 'remembers the file it was instantiated from' do - expect(trace_null.__file__).to eq(__FILE__) + it 'aliases .new to .get' do + expect(null_class.get.class).to be(null_class) end - it 'remembers the line it was instantiated from' do - expect(trace_null.__line__).to eq(instantiation_line) - end - - def make_null - trace_null_class.get(:caller => caller(1)) - end - - it 'can accept custom backtrace info' do - obj, line = make_null, __LINE__ - expect(obj.__line__).to eq(line) - end -end - -describe 'customized null object' do - subject(:custom_null) { custom_null_class.new } - let(:custom_null_class) do - Naught.build do |b| - b.define_explicit_conversions - def to_path - '/dev/null' - end - - def to_s - 'NOTHING TO SEE HERE' - end - end - end - - it 'responds to custom-defined methods' do - expect(custom_null.to_path).to eq('/dev/null') - end - - it 'allows generated methods to be overridden' do - expect(custom_null.to_s).to eq('NOTHING TO SEE HERE') - end -end -TestNull = Naught.build - -describe 'a named null object class' do - it 'has named ancestor modules', :pending => rubinius? do - expect(TestNull.ancestors[0..2].collect(&:name)).to eq([ - 'TestNull', - 'TestNull::Customizations', - 'TestNull::GeneratedMethods' - ]) - end end diff --git a/spec/predicate_spec.rb b/spec/predicate_spec.rb deleted file mode 100644 index 132b36b..0000000 --- a/spec/predicate_spec.rb +++ /dev/null @@ -1,84 +0,0 @@ -require 'spec_helper' - -describe 'a null object with predicates_return(false)' do - subject(:null) { null_class.new } - let(:null_class) do - Naught.build do |config| - config.predicates_return false - end - end - - it 'responds to predicate-style methods with false' do - expect(null.too_much_coffee?).to eq(false) - end - - it 'responds to other methods with nil' do - expect(null.foobar).to eq(nil) - end - - describe '(black hole)' do - let(:null_class) do - Naught.build do |config| - config.black_hole - config.predicates_return false - end - end - - it 'responds to predicate-style methods with false' do - expect(null.too_much_coffee?).to eq(false) - end - - it 'responds to other methods with self' do - expect(null.foobar).to be(null) - end - end - - describe '(black hole, reverse order config)' do - let(:null_class) do - Naught.build do |config| - config.predicates_return false - config.black_hole - end - end - - it 'responds to predicate-style methods with false' do - expect(null.too_much_coffee?).to eq(false) - end - - it 'responds to other methods with self' do - expect(null.foobar).to be(null) - end - end - - class Coffee - def black? - true - end - - def origin - 'Ethiopia' - end - end - - describe '(mimic)' do - let(:null_class) do - Naught.build do |config| - config.mimic Coffee - config.predicates_return false - end - end - - it 'responds to predicate-style methods with false' do - expect(null.black?).to eq(false) - end - - it 'responds to other methods with nil' do - expect(null.origin).to be(nil) - end - - it 'does not respond to undefined methods' do - expect(null).not_to respond_to(:leaf_variety) - expect { null.leaf_variety }.to raise_error(NoMethodError) - end - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e58b711..8500bdd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,7 +6,9 @@ Coveralls.wear! else require 'simplecov' - SimpleCov.start + SimpleCov.start do + add_filter "/spec/" + end end require 'naught'