-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
460 additions
and
405 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
env: | ||
- TRAVIS=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
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("<null>") | ||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
require 'spec_helper' | ||
|
||
describe 'black hole null object' do | ||
subject(:null) { null_class.new } | ||
let(:null_class) { | ||
Naught.build do |b| | ||
b.black_hole | ||
end | ||
} | ||
|
||
it 'returns self from arbitray method calls' do | ||
expect(null.info).to be(null) | ||
expect(null.foobaz).to be(null) | ||
expect(null << "bar").to be(null) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
require 'spec_helper.rb' | ||
|
||
describe 'explicitly convertable null object' do | ||
let(:null_class) { | ||
Naught.build do |b| | ||
b.define_explicit_conversions | ||
end | ||
} | ||
subject(:null) { null_class.new } | ||
|
||
it "defines common explicit conversions to return zero values" do | ||
expect(null.to_s).to eq("") | ||
expect(null.to_a).to eq([]) | ||
expect(null.to_i).to eq(0) | ||
expect(null.to_f).to eq(0.0) | ||
expect(null.to_c).to eq(Complex(0)) | ||
expect(null.to_r).to eq(Rational(0)) | ||
expect(null.to_h).to eq({}) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
require 'spec_helper' | ||
|
||
describe 'Actual()' do | ||
include ConvertableNull::Conversions | ||
|
||
specify 'given a null object, returns nil' do | ||
null = ConvertableNull.get | ||
expect(Actual(null)).to be_nil | ||
end | ||
|
||
specify 'given anything else, returns the input unchanged' do | ||
expect(Actual(false)).to be(false) | ||
str = "hello" | ||
expect(Actual(str)).to be(str) | ||
expect(Actual(nil)).to be_nil | ||
end | ||
|
||
it 'also works with blocks' do | ||
expect(Actual{ConvertableNull.new}).to be_nil | ||
expect(Actual{"foo"}).to eq("foo") | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
require 'spec_helper' | ||
|
||
describe 'Just()' do | ||
include ConvertableNull::Conversions | ||
|
||
specify 'passes non-nullish values through' do | ||
expect(Just(false)).to be(false) | ||
str = "hello" | ||
expect(Just(str)).to be(str) | ||
end | ||
|
||
specify 'rejects nullish values' do | ||
expect{Just(nil)}.to raise_error(ArgumentError) | ||
expect{Just("")}.to raise_error(ArgumentError) | ||
expect{Just(ConvertableNull.get)}.to raise_error(ArgumentError) | ||
end | ||
|
||
it 'also works with blocks' do | ||
expect{Just{nil}.class}.to raise_error(ArgumentError) | ||
expect(Just{"foo"}).to eq("foo") | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
require 'spec_helper' | ||
|
||
describe 'Maybe()' do | ||
include ConvertableNull::Conversions | ||
|
||
specify 'given nil, returns a null object' do | ||
expect(Maybe(nil).class).to be(ConvertableNull) | ||
end | ||
|
||
specify 'given a null object, returns the same null object' do | ||
null = ConvertableNull.get | ||
expect(Maybe(null)).to be(null) | ||
end | ||
|
||
specify 'given anything in null_equivalents, return a null object' do | ||
expect(Maybe("").class).to be(ConvertableNull) | ||
end | ||
|
||
specify 'given anything else, returns the input unchanged' do | ||
expect(Maybe(false)).to be(false) | ||
str = "hello" | ||
expect(Maybe(str)).to be(str) | ||
end | ||
|
||
it 'generates null objects with useful trace info' do | ||
null = Maybe(); line = __LINE__ | ||
expect(null.__line__).to eq(line) | ||
expect(null.__file__).to eq(__FILE__) | ||
end | ||
|
||
it 'also works with blocks' do | ||
expect(Maybe{nil}.class).to eq(ConvertableNull) | ||
expect(Maybe{"foo"}).to eq("foo") | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
require 'spec_helper' | ||
|
||
describe 'Null()' do | ||
include ConvertableNull::Conversions | ||
|
||
specify 'given no input, returns a null object' do | ||
expect(Null().class).to be(ConvertableNull) | ||
end | ||
|
||
specify 'given nil, returns a null object' do | ||
expect(Null(nil).class).to be(ConvertableNull) | ||
end | ||
|
||
specify 'given a null object, returns the same null object' do | ||
null = ConvertableNull.get | ||
expect(Null(null)).to be(null) | ||
end | ||
|
||
specify 'given anything in null_equivalents, return a null object' do | ||
expect(Null("").class).to be(ConvertableNull) | ||
end | ||
|
||
specify 'given anything else, raises an ArgumentError' do | ||
expect{Null(false)}.to raise_error(ArgumentError) | ||
expect{Null("hello")}.to raise_error(ArgumentError) | ||
end | ||
|
||
it 'generates null objects with useful trace info' do | ||
null = Null(); line = __LINE__ | ||
expect(null.__line__).to eq(line) | ||
expect(null.__file__).to eq(__FILE__) | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
require 'spec_helper' | ||
|
||
describe 'Actual()' do | ||
include ConvertableNull::Conversions | ||
|
||
specify 'given a null object, returns nil' do | ||
null = ConvertableNull.get | ||
expect(Actual(null)).to be_nil | ||
end | ||
|
||
specify 'given anything else, returns the input unchanged' do | ||
expect(Actual(false)).to be(false) | ||
str = "hello" | ||
expect(Actual(str)).to be(str) | ||
expect(Actual(nil)).to be_nil | ||
end | ||
|
||
it 'also works with blocks' do | ||
expect(Actual{ConvertableNull.new}).to be_nil | ||
expect(Actual{"foo"}).to eq("foo") | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
require 'spec_helper' | ||
|
||
describe 'implicitly convertable null object' do | ||
subject(:null) { null_class.new } | ||
let(:null_class) { | ||
Naught.build do |b| | ||
b.define_implicit_conversions | ||
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(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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
require 'spec_helper' | ||
require 'logger' | ||
|
||
describe 'null object mimicking a class' do | ||
class User | ||
def login | ||
"bob" | ||
end | ||
end | ||
|
||
module Authorizable | ||
def authorized_for?(object) | ||
true | ||
end | ||
end | ||
|
||
class LibraryPatron < User | ||
include Authorizable | ||
|
||
def member?; true; end | ||
def name; "Bob"; end | ||
def notify_of_overdue_books(titles) | ||
puts "Notifying Bob his books are overdue..." | ||
end | ||
end | ||
|
||
subject(:null) { mimic_class.new } | ||
let(:mimic_class) { | ||
Naught.build do |b| | ||
b.mimic LibraryPatron | ||
end | ||
} | ||
it 'responds to all methods defined on the target class' do | ||
expect(null.member?).to be_nil | ||
expect(null.name).to be_nil | ||
expect(null.notify_of_overdue_books(['The Grapes of Wrath'])).to be_nil | ||
end | ||
|
||
it 'does not respond to methods not defined on the target class' do | ||
expect{null.foobar}.to raise_error(NoMethodError) | ||
end | ||
|
||
it 'reports which messages it does and does not respond to' do | ||
expect(null).to respond_to(:member?) | ||
expect(null).to respond_to(:name) | ||
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("<null:LibraryPatron>") | ||
end | ||
|
||
it 'excludes Object methods from being mimicked' do | ||
expect(null.object_id).not_to be_nil | ||
expect(null.hash).not_to be_nil | ||
end | ||
|
||
it 'includes inherited methods' do | ||
expect(null.authorized_for?('something')).to be_nil | ||
expect(null.login).to be_nil | ||
end | ||
|
||
describe 'with include_super: false' do | ||
let(:mimic_class) { | ||
Naught.build do |b| | ||
b.mimic LibraryPatron, include_super: false | ||
end | ||
} | ||
|
||
it 'excludes inherited methods' do | ||
expect(null).to_not respond_to(:authorized_for?) | ||
expect(null).to_not respond_to(:login) | ||
end | ||
end | ||
end | ||
|
||
describe 'using mimic with black_hole' do | ||
subject(:null) { mimic_class.new } | ||
let(:mimic_class) { | ||
Naught.build do |b| | ||
b.mimic Logger | ||
b.black_hole | ||
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) { | ||
Naught.build do |b| | ||
b.black_hole | ||
b.mimic Logger | ||
end | ||
} | ||
|
||
it_behaves_like_a_black_hole_mimic | ||
end | ||
end |
Oops, something went wrong.