Skip to content

Instantly share code, notes, and snippets.

@sporsh
Forked from jimweirich/read_only_proxy.rb
Created February 8, 2012 08:44
Show Gist options
  • Save sporsh/1766933 to your computer and use it in GitHub Desktop.
Save sporsh/1766933 to your computer and use it in GitHub Desktop.
Vital Ruby Lab 5
class ReadOnlyProxy(object):
def __init__(self, target):
self._target = target
def __getattribute__(self, name):
target = object.__getattribute__(self, '_target')
return getattr(target, name)
class ReadOnlyProxy
def initialize(target)
@_target = target
end
def method_missing(sym, *args, &block)
if ! sym.to_s.end_with?('=')
@_target.send(sym, *args, &block)
end
end
def respond_to?(sym)
self.instance_variable_defined? "@#{sym.to_s}" || super
end
end
from read_only_proxy import ReadOnlyProxy
class ShadowProxy(ReadOnlyProxy):
def __getattribute__(self, name):
try:
return object.__getattribute__(self, name)
except AttributeError:
return ReadOnlyProxy.__getattribute__(self, name)
require "read_only_proxy"
class ShadowProxy < ReadOnlyProxy
def method_missing(sym, *args, &block)
if sym.to_s.end_with?('=')
self.instance_variable_set "@#{sym.to_s[0...-1]}", *args
else
value = self.instance_variable_get "@#{sym.to_s}"
value || super
end
end
end
import unittest
from read_only_proxy import ReadOnlyProxy
from shadow_proxy import ShadowProxy
class ActualObject(object):
def __init__(self, name="INITIAL NAME"):
self.name = name
class ReadOnlyProxyTestCase(unittest.TestCase):
def setUp(self):
unittest.TestCase.setUp(self)
self.actual = ActualObject()
self.actual.name = "ACTUAL NAME"
self.proxy = ReadOnlyProxy(self.actual)
def test_attributes_pass_thru(self):
self.assertEqual("ACTUAL NAME", self.proxy.name)
def test_attributes_are_not_set(self):
self.proxy.name = "PROXY NAME"
self.assertEqual("ACTUAL NAME", self.actual.name)
self.assertEqual("ACTUAL NAME", self.proxy.name)
def test_unset_attribute_raise_exception(self):
self.assertRaises(AttributeError, lambda: self.proxy.unset_attr)
def test_new_attribute_raise_exception(self):
self.proxy.new = "NEW"
self.assertRaises(AttributeError, lambda: self.proxy.new_attr)
class ShadowProxyTestCase(unittest.TestCase):
def setUp(self):
unittest.TestCase.setUp(self)
self.actual = ActualObject()
self.actual.name = "ACTUAL NAME"
self.proxy = ShadowProxy(self.actual)
def test_attributes_pass_thru(self):
self.assertEqual("ACTUAL NAME", self.proxy.name)
def test_attributes_are_shadowed(self):
self.proxy.name = "PROXY NAME"
self.assertEqual("PROXY NAME", self.proxy.name)
def test_attributes_are_not_set_on_actual_object(self):
self.proxy.name = "PROXY NAME"
self.assertEqual("ACTUAL NAME", self.actual.name)
def test_unset_attribute_raise_exception(self):
self.assertRaises(AttributeError, lambda: self.proxy.unset_attr)
def test_new_attribute_set_proxy_attribute(self):
self.proxy.new_attr = "NEW"
self.assertEqual("NEW", self.proxy.new_attr)
def test_new_attribute_does_not_go_thru(self):
self.proxy.new_attr = "NEW"
self.assertRaises(AttributeError, lambda: self.actual.new_attr)
def test_del_attribute_does_not_go_thru_but_reset(self):
self.proxy.name = "PROXY NAME"
del self.proxy.name
self.assertEqual("ACTUAL NAME", self.proxy.name)
if __name__ == '__main__':
unittest.main()
require "test/unit"
require "read_only_proxy"
require "shadow_proxy"
class ActualObject
attr_accessor :name
end
class ReadOnlyProxyTest < Test::Unit::TestCase
def setup
@actual = ActualObject.new
@actual.name = "ACTUAL NAME"
@proxy = ReadOnlyProxy.new(@actual)
end
def test_attributes_pass_thru
assert_equal "ACTUAL NAME", @proxy.name
end
def test_attributes_are_not_set_on_actual
@proxy.name = "PROXY NAME"
assert_equal "ACTUAL NAME", @actual.name
end
def test_attributes_are_not_set_on_proxy
@proxy.name = "PROXY NAME"
assert_equal "ACTUAL NAME", @proxy.name
end
# def test_unset_attr_raises
# assert_raise NoMethodError { @proxy.missing_attr }
# end
end
class ShadowProxyTest < Test::Unit::TestCase
def setup
@actual = ActualObject.new
@actual.name = "ACTUAL NAME"
@proxy = ShadowProxy.new(@actual)
end
def test_attributes_pass_thru
assert_equal "ACTUAL NAME", @proxy.name
end
def test_attributes_are_not_set_on_actual
@proxy.name = "PROXY NAME"
assert_equal "ACTUAL NAME", @actual.name
end
def test_attributes_are_set_on_proxy
@proxy.name = "PROXY NAME"
assert_equal "PROXY NAME", @proxy.name
end
# def test_unset_attr_raises
# assert_raise NoMethodError { @proxy.missing_attr }
# end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment