diff options
author | Jesse Luehrs <doy@tozt.net> | 2014-10-31 22:57:46 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2014-10-31 22:57:46 -0400 |
commit | 483c36526b1b70a6c0d20433ce0ad2699e52e9b5 (patch) | |
tree | 3cb717e6dc21c1ea18ff4b702c3dde8c74550120 /t/simple_overrides_test.py | |
parent | b5c669c2a9928ed1184ab7d23ae0c2c4de451ef3 (diff) | |
download | python-mop-483c36526b1b70a6c0d20433ce0ad2699e52e9b5.tar.gz python-mop-483c36526b1b70a6c0d20433ce0ad2699e52e9b5.zip |
test a few simple overrides
Diffstat (limited to 't/simple_overrides_test.py')
-rw-r--r-- | t/simple_overrides_test.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/t/simple_overrides_test.py b/t/simple_overrides_test.py new file mode 100644 index 0000000..c38056a --- /dev/null +++ b/t/simple_overrides_test.py @@ -0,0 +1,93 @@ +import unittest + +import mop + +# in a real implementation, we'd add more functionality to the mop itself to +# allow for calling superclass methods, but that would be complicated enough to +# obscure the implementation and make it not as easy to follow (we would have +# to manage call stacks ourselves), and so we just do this instead for now +def call_method_at_class(c, method_name, invocant, *args, **kwargs): + return c.get_all_methods()[method_name].slots["body"]( + invocant, *args, **kwargs + ) + +class SimpleOverridesTest(unittest.TestCase): + def test_accessor_generation(self): + AccessorsMetaclass = mop.Class.new( + name="AccessorsMetaclass", + superclass=mop.Class, + ) + def add_attribute(self, attr): + name = attr.get_name() + call_method_at_class(mop.Class, "add_attribute", self, attr) + self.add_method(self.method_class().new( + name=name, + body=lambda self: self.metaclass.get_all_attributes()[name].get_value(self), + )) + AccessorsMetaclass.add_method(AccessorsMetaclass.metaclass.method_class().new( + name="add_attribute", + body=add_attribute, + )) + AccessorsMetaclass.finalize() + + Point = AccessorsMetaclass.new( + name="Point", + superclass=AccessorsMetaclass.base_object_class(), + ) + Point.add_attribute(Point.attribute_class().new(name="x", default=0)) + Point.add_attribute(Point.attribute_class().new(name="y", default=0)) + Point.finalize() + + point = Point.new(x=1, y=2) + assert point.x() == 1 + assert point.y() == 2 + + def test_trace_method_calls(self): + methods_called = [] + + TraceMethod = mop.Class.new( + name="TraceMethod", + superclass=mop.Method, + ) + + def execute(self, invocant, args, kwargs): + methods_called.append(self.get_name()) + return call_method_at_class(mop.Method, "execute", self, invocant, args, kwargs) + TraceMethod.add_method(TraceMethod.metaclass.method_class().new( + name="execute", + body=execute, + )) + TraceMethod.finalize() + + TraceClass = mop.Class.new( + name="TraceClass", + superclass=mop.Class, + ) + TraceClass.add_method(TraceClass.metaclass.method_class().new( + name="method_class", + body=lambda self: TraceMethod, + )) + TraceClass.finalize() + + Point = TraceClass.new( + name="Point", + superclass=TraceClass.base_object_class(), + ) + Point.add_attribute(Point.attribute_class().new(name="x", default=0)) + Point.add_attribute(Point.attribute_class().new(name="y", default=0)) + Point.add_method(Point.method_class().new( + name="x", + body=lambda self: self.metaclass.get_all_attributes()["x"].get_value(self) + )) + Point.add_method(Point.method_class().new( + name="y", + body=lambda self: self.metaclass.get_all_attributes()["y"].get_value(self) + )) + Point.finalize() + + point = Point.new(x=1, y=2) + assert methods_called == [] + assert point.x() == 1 + assert methods_called == ['x'] + assert point.y() == 2 + assert methods_called == ['x', 'y'] |