[Checkins] SVN: martian/trunk/src/martian/ Add some tests for
directives.
Martijn Faassen
faassen at infrae.com
Wed Jun 20 08:25:08 EDT 2007
Log message for revision 76835:
Add some tests for directives.
Changed:
A martian/trunk/src/martian/directive.txt
A martian/trunk/src/martian/tests/directive/
A martian/trunk/src/martian/tests/directive/__init__.py
A martian/trunk/src/martian/tests/directive/classcontextbroken.py
A martian/trunk/src/martian/tests/directive/classormodulecontext.py
A martian/trunk/src/martian/tests/directive/modulecontext.py
A martian/trunk/src/martian/tests/directive/onlyoncemodulecontext.py
U martian/trunk/src/martian/tests/test_all.py
-=-
Added: martian/trunk/src/martian/directive.txt
===================================================================
--- martian/trunk/src/martian/directive.txt (rev 0)
+++ martian/trunk/src/martian/directive.txt 2007-06-20 12:25:08 UTC (rev 76835)
@@ -0,0 +1,200 @@
+Directives
+==========
+
+A martian directive is a special function call that causes information
+to be set on module or class level. This information is set as a
+Python module is imported, so should do the minimum amount of work (as
+import side-effects are bad). The idea is that this information can
+then be picked up by a martian-based framework during grok time.
+
+Martian has an infrastructure to make it easy to define new
+directives.
+
+Directive contexts
+------------------
+
+If a directive is given ``ModuleDirectiveContext`` it can only work in
+real modules::
+
+ >>> from martian.directive import SingleTextDirective, ModuleDirectiveContext
+ >>> foo = SingleTextDirective('grok.foo', ModuleDirectiveContext())
+
+We cannot show a working example of the ``foo`` directive in this
+doctest as it is not a real module. It would look like this::
+
+ foo('hello world')
+
+We have placed this code in a real module and will import it::
+
+ >>> from martian.tests.directive import modulecontext
+
+We expect modulecontext to contain a special attribute ``__grok_foo__``
+with the string ``'hello world'``::
+
+ >>> modulecontext.__grok_foo__
+ 'hello world'
+
+This directive cannot be used in a class as it's not allowed by its context::
+
+ >>> class Test(object):
+ ... foo('hello world')
+ Traceback (most recent call last):
+ ...
+ GrokImportError: grok.foo can only be used on module level.
+
+Now let's define a directive that can only work in classes::
+
+ >>> from martian.directive import ClassDirectiveContext
+ >>> bar = SingleTextDirective('grok.bar', ClassDirectiveContext())
+
+It won't work in a module::
+
+ >>> from martian.tests.directive import classcontextbroken
+ Traceback (most recent call last):
+ ...
+ GrokImportError: grok.bar can only be used on class level.
+
+It will work in a class context::
+
+ >>> class Test(object):
+ ... bar('hello world')
+ >>> Test.__grok_bar__
+ 'hello world'
+
+Now let's define a directive that can be used both on module-level as
+well as on class-level::
+
+ >>> from martian.directive import ClassOrModuleDirectiveContext
+ >>> qux = SingleTextDirective('grok.qux', ClassOrModuleDirectiveContext())
+
+It can be used in a class::
+
+ >>> class Test(object):
+ ... qux('hello world')
+ >>> Test.__grok_qux__
+ 'hello world'
+
+It can also be used in a module::
+
+ >>> from martian.tests.directive import classormodulecontext
+ >>> classormodulecontext.__grok_qux__
+ 'hello world'
+
+Calling a directive once or multiple times
+------------------------------------------
+
+Directives can either be called once in a particular context, or
+multiple times. Let's define a type of directive that can only be
+called once::
+
+ >>> from martian.directive import OnceDirective, SingleValue, BaseTextDirective
+ >>> class MyDirective(BaseTextDirective, SingleValue, OnceDirective):
+ ... pass
+ >>> hoi = MyDirective('hoi', ClassDirectiveContext())
+
+When we try to use it twice, we get an error::
+
+ >>> class Test(object):
+ ... hoi('once')
+ ... hoi('twice')
+ Traceback (most recent call last):
+ ...
+ GrokImportError: hoi can only be called once per class.
+
+This also works for module-level directives::
+
+ >>> from martian.tests.directive import onlyoncemodulecontext
+ Traceback (most recent call last):
+ ...
+ GrokImportError: hoi can only be called once per module.
+
+Now let's define a directive that can be called multiple times::
+
+ >>> from martian.directive import MultipleTimesDirective
+ >>> class MyDirective(BaseTextDirective, SingleValue, MultipleTimesDirective):
+ ... pass
+ >>> dag = MyDirective('dag', ClassDirectiveContext())
+
+It will allow you to use it multiple times::
+
+ >>> class Test(object):
+ ... dag('once')
+ ... dag('twice')
+
+The underlying annotation will have stored the multiple values::
+
+ >>> Test.__dag__
+ ['once', 'twice']
+
+Directive values
+----------------
+
+A ``BaseTextDirective`` directive accepts unicode or plain ascii values::
+
+ >>> class Test(object):
+ ... hoi('hello')
+ >>> class Test(object):
+ ... hoi(u'è')
+
+It won't accept values in another encoding::
+
+ >>> class Test(object):
+ ... hoi(u'è'.encode('latin-1'))
+ Traceback (most recent call last):
+ ...
+ GrokImportError: You can only pass unicode or ASCII to hoi.
+ >>> class Test(object):
+ ... hoi(u'è'.encode('UTF-8'))
+ Traceback (most recent call last):
+ ...
+ GrokImportError: You can only pass unicode or ASCII to hoi.
+
+A ``InterfaceOrClassDirective`` only accepts class or interface objects::
+
+ >>> from martian.directive import InterfaceOrClassDirective
+ >>> class MyDirective(InterfaceOrClassDirective, SingleValue, OnceDirective):
+ ... pass
+ >>> hello = MyDirective('hello', ClassDirectiveContext())
+ >>> class SomeClass(object):
+ ... pass
+ >>> class Test(object):
+ ... hello(SomeClass)
+ >>> class SomeOldStyleClass:
+ ... pass
+ >>> class Test(object):
+ ... hello(SomeOldStyleClass)
+ >>> from zope.interface import Interface
+ >>> class ISomeInterface(Interface):
+ ... pass
+ >>> class Test(object):
+ ... hello(ISomeInterface)
+
+But not anything else::
+
+ >>> class Test(object):
+ ... hello(None)
+ Traceback (most recent call last):
+ ...
+ GrokImportError: You can only pass classes or interfaces to hello.
+ >>> class Test(object):
+ ... hello('foo')
+ Traceback (most recent call last):
+ ...
+ GrokImportError: You can only pass classes or interfaces to hello.
+
+An ``InterfaceDirective`` accepts only interfaces::
+
+ >>> from martian.directive import InterfaceDirective
+ >>> class MyDirective(InterfaceDirective, SingleValue, OnceDirective):
+ ... pass
+ >>> hello2 = MyDirective('hello2', ClassDirectiveContext())
+ >>> class Test(object):
+ ... hello2(ISomeInterface)
+
+But not classes::
+
+ >>> class Test(object):
+ ... hello2(SomeClass)
+ Traceback (most recent call last):
+ ...
+ GrokImportError: You can only pass interfaces to hello2.
Added: martian/trunk/src/martian/tests/directive/__init__.py
===================================================================
--- martian/trunk/src/martian/tests/directive/__init__.py (rev 0)
+++ martian/trunk/src/martian/tests/directive/__init__.py 2007-06-20 12:25:08 UTC (rev 76835)
@@ -0,0 +1 @@
+# this is a package
Added: martian/trunk/src/martian/tests/directive/classcontextbroken.py
===================================================================
--- martian/trunk/src/martian/tests/directive/classcontextbroken.py (rev 0)
+++ martian/trunk/src/martian/tests/directive/classcontextbroken.py 2007-06-20 12:25:08 UTC (rev 76835)
@@ -0,0 +1,5 @@
+from martian.directive import SingleTextDirective, ClassDirectiveContext
+
+bar = SingleTextDirective('grok.bar', ClassDirectiveContext())
+
+bar('hello world') # this won't work as not class context
Added: martian/trunk/src/martian/tests/directive/classormodulecontext.py
===================================================================
--- martian/trunk/src/martian/tests/directive/classormodulecontext.py (rev 0)
+++ martian/trunk/src/martian/tests/directive/classormodulecontext.py 2007-06-20 12:25:08 UTC (rev 76835)
@@ -0,0 +1,5 @@
+from martian.directive import SingleTextDirective, ClassOrModuleDirectiveContext
+
+qux = SingleTextDirective('grok.qux', ClassOrModuleDirectiveContext())
+
+qux('hello world')
Added: martian/trunk/src/martian/tests/directive/modulecontext.py
===================================================================
--- martian/trunk/src/martian/tests/directive/modulecontext.py (rev 0)
+++ martian/trunk/src/martian/tests/directive/modulecontext.py 2007-06-20 12:25:08 UTC (rev 76835)
@@ -0,0 +1,5 @@
+from martian.directive import SingleTextDirective, ModuleDirectiveContext
+
+foo = SingleTextDirective('grok.foo', ModuleDirectiveContext())
+
+foo('hello world')
Added: martian/trunk/src/martian/tests/directive/onlyoncemodulecontext.py
===================================================================
--- martian/trunk/src/martian/tests/directive/onlyoncemodulecontext.py (rev 0)
+++ martian/trunk/src/martian/tests/directive/onlyoncemodulecontext.py 2007-06-20 12:25:08 UTC (rev 76835)
@@ -0,0 +1,10 @@
+from martian.directive import OnceDirective, SingleValue, BaseTextDirective
+from martian.directive import ModuleDirectiveContext
+
+class MyDirective(BaseTextDirective, SingleValue, OnceDirective):
+ pass
+
+hoi = MyDirective('hoi', ModuleDirectiveContext())
+
+hoi('once')
+hoi('twice')
Modified: martian/trunk/src/martian/tests/test_all.py
===================================================================
--- martian/trunk/src/martian/tests/test_all.py 2007-06-20 12:10:55 UTC (rev 76834)
+++ martian/trunk/src/martian/tests/test_all.py 2007-06-20 12:25:08 UTC (rev 76835)
@@ -66,5 +66,7 @@
optionflags=optionflags),
doctest.DocFileSuite('../scan.txt',
optionflags=optionflags),
+ doctest.DocFileSuite('../directive.txt',
+ optionflags=optionflags),
])
return suite
More information about the Checkins
mailing list