Skip to content

Commit

Permalink
Merge 25990b3 into 0869d4a
Browse files Browse the repository at this point in the history
  • Loading branch information
samnang committed Jul 27, 2013
2 parents 0869d4a + 25990b3 commit 40c1713
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 66 deletions.
71 changes: 5 additions & 66 deletions lib/naught/null_class_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class NullClassBuilder
module Commands
end

attr_accessor :base_class
attr_accessor :base_class, :inspect_proc, :interface_defined

def initialize
@interface_defined = false
Expand Down Expand Up @@ -99,39 +99,6 @@ def respond_to?(*)
@interface_defined = true
end

def mimic(class_to_mimic, options={})
include_super = options.fetch(:include_super) { true }
@base_class = root_class_of(class_to_mimic)
@inspect_proc = -> { "<null:#{class_to_mimic}>" }
defer do |subject|
methods = class_to_mimic.instance_methods(include_super) -
Object.instance_methods
methods.each do |method_name|
stub_method(subject, method_name)
end
end
@interface_defined = true
end

def impersonate(class_to_impersonate, options={})
mimic(class_to_impersonate, options)
@base_class = class_to_impersonate
end

def traceable
defer do |subject|
subject.module_eval do
attr_reader :__file__, :__line__

def initialize(options={})
backtrace = options.fetch(:caller) { Kernel.caller(4) }
@__file__, line, _ = backtrace[0].split(':')
@__line__ = line.to_i
end
end
end
end

def defer(options={}, &deferred_operation)
list = options[:class] ? class_operations : operations
if options[:prepend]
Expand All @@ -141,32 +108,17 @@ def defer(options={}, &deferred_operation)
end
end

def singleton
defer(class: true) do |subject|
require 'singleton'
subject.module_eval do
include Singleton
def self.get(*)
instance
end

%w(dup clone).each do |method_name|
define_method method_name do
self
end
end

end
end
def stub_method(subject, name)
send(@stub_strategy, subject, name)
end

private

def define_basic_methods
define_basic_instance_methods
define_basic_class_methods
end

private

def apply_operations(operations, module_or_class)
operations.each do |operation|
operation.call(module_or_class)
Expand Down Expand Up @@ -203,10 +155,6 @@ def operations
@operations ||= []
end

def stub_method(subject, name)
send(@stub_strategy, subject, name)
end

def stub_method_returning_nil(subject, name)
subject.module_eval do
define_method(name) {|*| nil }
Expand All @@ -222,14 +170,5 @@ def stub_method_returning_self(subject, name)
def command_name_for_method(method_name)
method_name.to_s.gsub(/(?:^|_)([a-z])/) { $1.upcase }
end

def root_class_of(klass)
if klass.ancestors.include?(Object)
Object
else
BasicObject
end
end

end
end
4 changes: 4 additions & 0 deletions lib/naught/null_class_builder/commands.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
require 'naught/null_class_builder/commands/define_explicit_conversions'
require 'naught/null_class_builder/commands/define_implicit_conversions'
require 'naught/null_class_builder/commands/predicates_return'
require 'naught/null_class_builder/commands/singleton'
require 'naught/null_class_builder/commands/traceable'
require 'naught/null_class_builder/commands/mimic'
require 'naught/null_class_builder/commands/impersonate'
13 changes: 13 additions & 0 deletions lib/naught/null_class_builder/commands/impersonate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Naught
class NullClassBuilder
module Commands
class Impersonate < Naught::NullClassBuilder::Commands::Mimic
def initialize(builder, class_to_impersonate, options={})
super

builder.base_class = class_to_impersonate
end
end
end
end
end
41 changes: 41 additions & 0 deletions lib/naught/null_class_builder/commands/mimic.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'naught/null_class_builder/command'

module Naught
class NullClassBuilder
module Commands
class Mimic < Naught::NullClassBuilder::Command
def initialize(builder, class_to_mimic, options={})
super(builder)

@class_to_mimic = class_to_mimic
@include_super = options.fetch(:include_super) { true }

builder.base_class = root_class_of(class_to_mimic)
builder.inspect_proc = -> { "<null:#{class_to_mimic}>" }
builder.interface_defined = true
end

def call
defer do |subject|
methods = @class_to_mimic.instance_methods(@include_super) -
Object.instance_methods
methods.each do |method_name|
@builder.stub_method(subject, method_name)
end
end
end

private

def root_class_of(klass)
if klass.ancestors.include?(Object)
Object
else
BasicObject
end
end
end
end
end
end

28 changes: 28 additions & 0 deletions lib/naught/null_class_builder/commands/singleton.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'naught/null_class_builder/command'

module Naught
class NullClassBuilder
module Commands
class Singleton < Naught::NullClassBuilder::Command
def call
defer(class: true) do |subject|
require 'singleton'
subject.module_eval do
include ::Singleton

def self.get(*)
instance
end

%w(dup clone).each do |method_name|
define_method method_name do
self
end
end
end
end
end
end
end
end
end
24 changes: 24 additions & 0 deletions lib/naught/null_class_builder/commands/traceable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require 'naught/null_class_builder/command'

module Naught
class NullClassBuilder
module Commands
class Traceable < Naught::NullClassBuilder::Command
def call
defer do |subject|
subject.module_eval do
attr_reader :__file__, :__line__

def initialize(options={})
backtrace = options.fetch(:caller) { Kernel.caller(4) }
@__file__, line, _ = backtrace[0].split(':')
@__line__ = line.to_i
end
end
end
end
end
end
end
end

3 changes: 3 additions & 0 deletions spec/naught_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def y; 42; end
expect{null.foo}.to raise_error(NoMethodError)
end
end

describe 'traceable null object' do
subject(:trace_null) {
null_object_and_line.first
Expand All @@ -48,6 +49,7 @@ def y; 42; 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
Expand All @@ -57,6 +59,7 @@ def make_null
expect(obj.__line__).to eq(line)
end
end

describe 'customized null object' do
subject(:custom_null) { custom_null_class.new }
let(:custom_null_class) {
Expand Down

0 comments on commit 40c1713

Please sign in to comment.