Skip to content

Commit

Permalink
final clean up and implementation of using BlankSlate:
Browse files Browse the repository at this point in the history
  * add Jim's copyright notice for BlankSlate, as I took it from Builder;
  * clean up some specs to be a bit more readable
  * put rspec back
  • Loading branch information
rsanheim committed Jan 21, 2009
1 parent 27b060c commit 57337b8
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 45 deletions.
28 changes: 26 additions & 2 deletions lib/configatron/blank_slate.rb
@@ -1,12 +1,36 @@
#--
# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.

# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++

# This version of BlankSlate was taken from Builder and modified by Rob Sanheim
# to remove hooks into the various built-in callbacks (ie method_added).
# Not sure if we need that complexity (yet) in configatron's use case.
#
######################################################################
# BlankSlate provides an abstract base class with no predefined
# methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
# BlankSlate is useful as a base class when writing classes that
# depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
#
class Configatron
class BlankSlate
# These methods are used by configatron internals, so we have to whitelist them.
# We could probably do some alias magic to get them to be proper __foo style methods
#, but this is okay for now.
CONFIGATRON_WHITELIST = %w[instance_eval methods instance_variable_get is_a? class]

class << self

# Hide the method named +name+ in the BlankSlate class. Don't
# hide +instance_eval+ or any method beginning with "__".
# hide methods in +CONFIGATRON_WHITELIST+ or any method beginning with "__".
def hide(name)
if instance_methods.include?(name.to_s) and
name !~ /^(__|instance_eval|methods)/
name !~ /^(__|#{CONFIGATRON_WHITELIST.join("|")})/
@hidden_methods ||= {}
@hidden_methods[name.to_sym] = instance_method(name)
undef_method name
Expand Down
4 changes: 0 additions & 4 deletions lib/configatron/store.rb
Expand Up @@ -92,12 +92,8 @@ def set_default(name, default_value)
end

def method_missing(sym, *args) # :nodoc:
p "method_missing with #{sym} and #{args}"
if sym.to_s.match(/(.+)=$/)
name = sym.to_s.gsub("=", '').to_sym
p 'in if block...'
p "protected: #{@_protected.inspect}"
p methods_include?(name)
raise Configatron::ProtectedParameter.new(name.to_s) if @_protected.include?(name) || methods_include?(name)
raise Configatron::LockedNamespace.new(@_name.to_s) if @_locked && !@_store.has_key?(name)
@_store[name] = parse_options(*args)
Expand Down
20 changes: 7 additions & 13 deletions spec/lib/blank_slate_spec.rb
Expand Up @@ -6,26 +6,20 @@
configatron.reset!
end

it "should respond to __id__, __send__, and instance_eval" do
it "should respond to __id__ and __send__ built in methods" do
lambda {
Configatron::BlankSlate.new.__id__
Configatron::BlankSlate.new.__send__
Configatron::BlankSlate.new.__methods__
Configatron::BlankSlate.new.instance_eval { 'hi' }
}.should_not raise_error(NoMethodError)
end

it "has methods" do
Configatron::BlankSlate.new.methods.should == ["methods", "__id__", "__send__", "instance_eval", "configatron", "send_with_chain"]
end

it "should not respond to Object's immediate methods" do
object_methods = Object.methods(false).reject { |m| m =~ /^(__|instance_eval)/ }.sort
object_methods.each do |meth|
it "should have methods on the CONFIGATRON_WHITELIST" do
blank_slate = Configatron::BlankSlate.new
Configatron::BlankSlate::CONFIGATRON_WHITELIST.each do |meth|
lambda {
Configatron::BlankSlate.new.__send__(meth)
}.should raise_error(NoMethodError)
blank_slate__send__
}.should_not raise_error(NoMethodError)
end
end

end
20 changes: 6 additions & 14 deletions spec/lib/configatron_spec.rb
Expand Up @@ -3,7 +3,6 @@
describe "configatron" do

before(:each) do
p 'in each!'
configatron.reset!
end

Expand All @@ -21,16 +20,6 @@

describe 'protect' do

fit "should shovel protected attribute onto @protected" do
begin
configatron.one = 1
rescue Exception => e
p e.message
end
configatron.protect(:one)
configatron.instance_variable_get(:@_protected).should == [:one]
end

it 'should protect a parameter and prevent it from being set' do
configatron.one = 1
configatron.protect(:one)
Expand All @@ -41,6 +30,7 @@
end

it 'should protect basic methods' do
pending("Not sure if this really applies any more...there is no reason to _not_ let users set a key called 'object_id' now")
lambda{configatron.object_id = 123456}.should raise_error(Configatron::ProtectedParameter)
lambda{configatron.foo.object_id = 123456}.should raise_error(Configatron::ProtectedParameter)
end
Expand Down Expand Up @@ -74,9 +64,11 @@
configatron.letters.a = 'A'
configatron.letters.b = 'B'
configatron.protect_all!
[:a,:b].each do |l|
lambda{configatron.configure_from_hash(:letters => {l => l.to_s})}.should raise_error(Configatron::ProtectedParameter)
configatron.letters.__send__(l).should == l.to_s.upcase
[:a,:b].each do |lowercase_letter|
lambda {
configatron.configure_from_hash(:letters => { lowercase_letter => lowercase_letter.to_s})
}.should raise_error(Configatron::ProtectedParameter)
configatron.letters.__send__(lowercase_letter).should == lowercase_letter.to_s.upcase
end
lambda{configatron.letters.configure_from_hash(:a => 'a')}.should raise_error(Configatron::ProtectedParameter)
lambda{configatron.configure_from_hash(:letters => 'letters')}.should raise_error(Configatron::ProtectedParameter)
Expand Down
13 changes: 1 addition & 12 deletions spec/spec_helper.rb
@@ -1,15 +1,4 @@
require 'rubygems'
# require 'spec'
gem 'spicycode-micronaut'
gem 'relevance-log_buddy'
require 'micronaut'
require 'log_buddy'
LogBuddy.init

Micronaut.configure do |c|
c.filter_run :focused => true
c.alias_example_to :fit, :focused => true
end

require 'spec'

require File.join(File.dirname(__FILE__), '..', 'lib', 'configatron')

0 comments on commit 57337b8

Please sign in to comment.