~hardware-certification/zope3/certify-staging-2.5

« back to all changes in this revision

Viewing changes to src/zope/configuration/tests/.svn/text-base/test_simple.py.svn-base

  • Committer: Marc Tardif
  • Date: 2008-04-26 19:03:34 UTC
  • Revision ID: cr3@lime-20080426190334-u16xo4llz56vliqf
Initial import.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
##############################################################################
 
2
#
 
3
# Copyright (c) 2003 Zope Corporation and Contributors.
 
4
# All Rights Reserved.
 
5
#
 
6
# This software is subject to the provisions of the Zope Public License,
 
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
 
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
 
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 
11
# FOR A PARTICULAR PURPOSE.
 
12
#
 
13
##############################################################################
 
14
r"""How to write a simple directive
 
15
 
 
16
This module documents how to write a simple directive.
 
17
 
 
18
A simple directive is a directive that doesn't contain other
 
19
directives. It can be implemented via a fairly simple function.
 
20
To implement a simple directive, you need to do 3 things:
 
21
 
 
22
- You need to create a schema to describe the directive parameters,
 
23
 
 
24
- You need to write a directive handler, and
 
25
 
 
26
- You need to register the directive.
 
27
 
 
28
In this module, we'll implement a contrived example that records
 
29
information about files in a file registry. The file registry is just
 
30
the list, ``file_registry``. Our registry will contain tuples
 
31
with:
 
32
 
 
33
  - file path
 
34
 
 
35
  - file title
 
36
 
 
37
  - description
 
38
 
 
39
  - Information about where the file was defined
 
40
 
 
41
Our schema is defined in IRegisterFile (see below). Our schema lists
 
42
the path and title.  We'll get the description and other information
 
43
for free, as we'll see later.  The title is not required, and may be
 
44
ommmitted.
 
45
 
 
46
The job of a configuration handler is to compute one or more
 
47
configuration actions.  Configuration actions are defered function
 
48
calls. The handler doesn't perform the actions. It just computes
 
49
actions, which may be performed later if they are not overridden by
 
50
other directives.
 
51
 
 
52
Out handler is given in the function, ``registerFile``. It takes a context,
 
53
a path and a title. All directive handlers take the directive context
 
54
as the first argument.  A directive context, at a minimim, implements,
 
55
``zope.configuration.IConfigurationContext``.  (Specialized contexts
 
56
can implement more specific interfaces. We'll say more about that when
 
57
we talk about grouping directives.)  The title argument
 
58
must have a default value, because we indicated that the title was not
 
59
required in the schema. (Alternatively, we could have made the title
 
60
required, but provided a default value in the schema.
 
61
 
 
62
In the first line of function `registerFile`, we get the context information
 
63
object. This object contains information about the configuration
 
64
directive, such as the file and location within the file of the
 
65
directive.
 
66
 
 
67
The context information object also has a text attribute that contains
 
68
the textual data contained by the configuration directive. (This is
 
69
the concatenation of all of the xml text nodes directly contained by
 
70
the directive.)  We use this for our description in the second line
 
71
of the handler.
 
72
 
 
73
The last thing the handler does is to compute an action by calling the
 
74
action method of the context.  It passes the action method 3 keyword
 
75
arguments:
 
76
 
 
77
- discriminator
 
78
 
 
79
  The discriminator is used to identify the action to be performed so
 
80
  that duplicate actions can be detected.  Two actions are duplicated,
 
81
  and this conflict, if they have the same discriminator values and
 
82
  the values are not ``None``.  Conflicting actions can be resolved if
 
83
  one of the conflicting actions is from a configuration file that
 
84
  directly or indirectly includes the files containing the other
 
85
  conflicting actions.
 
86
 
 
87
  In function ``registerFile``, we a tuple with the string
 
88
  ``'RegisterFile'`` and the path to be registered.
 
89
 
 
90
- callable
 
91
 
 
92
  The callable is the object to be called to perform the action.
 
93
 
 
94
- args
 
95
 
 
96
  The args argument contains positinal arguments to be passed to the
 
97
  callable. In function ``registerFile``, we pass a tuple containing a
 
98
  ``FileInfo`` object.
 
99
 
 
100
  (Note that there's nothing special about the FileInfo class. It has
 
101
   nothing to do with creating simple directives. It's just used in
 
102
   this example to organize the application data.)
 
103
 
 
104
 
 
105
The final step in implementing the simple directive is to register
 
106
it. We do that with the zcml ``meta:directive`` directive.  This is
 
107
given in the file simple.zcml.  Here we specify the name, namespace,
 
108
schema, and handler for the directive.  We also provide a
 
109
documentation for the directive as text between the start and end
 
110
tags.
 
111
 
 
112
The file simple.zcml also includes some directives that use the new
 
113
directive to register some files.
 
114
 
 
115
Now let's try it all out:
 
116
 
 
117
>>> from zope.configuration import tests
 
118
>>> context = xmlconfig.file("simple.zcml", tests)
 
119
 
 
120
Now we should see some file information in the  registry:
 
121
 
 
122
>>> from zope.configuration.tests.test_xmlconfig import clean_text_w_paths
 
123
>>> from zope.configuration.tests.test_xmlconfig import clean_path
 
124
>>> for i in file_registry:
 
125
...   print "path:", clean_path(i.path)
 
126
...   print "title:", i.title
 
127
...   print "description:", '\n'.join(
 
128
...               [l.rstrip()
 
129
...                for l in i.description.strip().split('\n')
 
130
...                if l.rstrip()])
 
131
...   print "info:"
 
132
...   print clean_text_w_paths(i.info)
 
133
path: tests/test_simple.py
 
134
title: How to create a simple directive
 
135
description: Describes how to implement a simple directive
 
136
info:
 
137
File "tests/simple.zcml", line 19.2-24.2
 
138
    <files:register
 
139
        path="test_simple.py"
 
140
        title="How to create a simple directive"
 
141
        >
 
142
      Describes how to implement a simple directive
 
143
    </files:register>
 
144
path: tests/simple.zcml
 
145
title: 
 
146
description: Shows the ZCML directives needed to register a simple directive.
 
147
    Also show some usage examples,
 
148
info:
 
149
File "tests/simple.zcml", line 26.2-30.2
 
150
    <files:register path="simple.zcml">
 
151
      Shows the ZCML directives needed to register a simple directive.
 
152
      Also show some usage examples,
 
153
    </files:register>
 
154
path: tests/__init__.py
 
155
title: Make this a package
 
156
description: 
 
157
info:
 
158
File "tests/simple.zcml", line 32.2-32.67
 
159
    <files:register path="__init__.py" title="Make this a package" />
 
160
 
 
161
 
 
162
We'll clean up after ourselves:
 
163
 
 
164
>>> del file_registry[:]
 
165
 
 
166
$Id$
 
167
"""
 
168
 
 
169
file_registry = []
 
170
 
 
171
                   
 
172
import unittest
 
173
from zope.testing.doctestunit import DocTestSuite
 
174
from zope import interface
 
175
from zope import schema
 
176
from zope.configuration import fields, xmlconfig
 
177
 
 
178
class IRegisterFile(interface.Interface):
 
179
 
 
180
    path = fields.Path(
 
181
        title=u"File path",
 
182
        description=u"This is the path name of the file to be registered."
 
183
        )
 
184
 
 
185
    title = schema.Text(
 
186
        title=u"Short summary of the file",
 
187
        description=u"This will be used in file listings",
 
188
        required = False
 
189
        )
 
190
 
 
191
class FileInfo(object):
 
192
 
 
193
    def __init__(self, path, title, description, info):
 
194
        (self.path, self.title, self.description, self.info
 
195
         ) = path, title, description, info
 
196
 
 
197
def registerFile(context, path, title=u""):
 
198
    info = context.info
 
199
    description = info.text.strip()
 
200
    context.action(discriminator=('RegisterFile', path),
 
201
                   callable=file_registry.append,
 
202
                   args=(FileInfo(path, title, description, info),)
 
203
                   )
 
204
 
 
205
def test_suite():
 
206
    return unittest.TestSuite((
 
207
        DocTestSuite(),
 
208
        ))
 
209
 
 
210
if __name__ == '__main__': unittest.main()