source: products/quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/tests.py @ 430

Last change on this file since 430 was 430, checked in by crchemist, 18 years ago

Added folders for furure compatibility with plone-2.1.3 and plone-2.5

File size: 28.6 KB
Line 
1import unittest
2import pprint
3import os
4
5from zope.testing import doctest, cleanup
6from zope.component import provideUtility, provideAdapter, adapts
7from zope.interface import classProvides, implements
8
9from collective.transmogrifier.interfaces import ISectionBlueprint, ISection
10from collective.transmogrifier.tests import tearDown
11from collective.transmogrifier.sections.tests import sectionsSetUp
12from collective.transmogrifier.sections.tests import SampleSource
13
14from Products.Five import zcml
15
16import quintagroup.transmogrifier
17from quintagroup.transmogrifier.xslt import stylesheet_registry
18
19class DataPrinter(object):
20    classProvides(ISectionBlueprint)
21    implements(ISection)
22
23    def __init__(self, transmogrifier, name, options, previous):
24        self.previous = previous
25        self.printkey = [i.strip() for i in options['print'].splitlines() if i.strip()]
26        if 'prettyprint' in options:
27            self.pprint = pprint.PrettyPrinter().pprint
28
29    def __iter__(self):
30        for item in self.previous:
31            if self.printkey:
32                data = item
33                for i in self.printkey:
34                    if i in data:
35                        data = data[i]
36                    else:
37                        data = None
38                        break
39                if data is not None:
40                    if hasattr(self, 'pprint'):
41                        self.pprint(data)
42                    else:
43                        print data
44            yield item
45
46ctSectionsSetup = sectionsSetUp
47def sectionsSetUp(test):
48    ctSectionsSetup(test)
49    import Products.Five
50    import Products.GenericSetup
51    import zope.annotation
52    zcml.load_config('meta.zcml', Products.Five)
53    zcml.load_config('meta.zcml', Products.GenericSetup)
54    zcml.load_config('configure.zcml', zope.annotation)
55    zcml.load_config('configure.zcml', quintagroup.transmogrifier)
56
57    from Products.CMFCore import utils
58    def getToolByName(context, tool_id):
59        return context
60    utils.getToolByName = getToolByName
61
62    import Acquisition
63    def aq_base(obj):
64        return obj
65    Acquisition.aq_base = aq_base
66
67    provideUtility(DataPrinter,
68        name=u'quintagroup.transmogrifier.tests.dataprinter')
69
70def siteWalkerSetUp(test):
71    sectionsSetUp(test)
72
73    from Products.CMFCore.interfaces import IFolderish
74    from Products.Archetypes.interfaces import IBaseFolder
75
76    class MockContent(object):
77        path = ()
78
79        def getPhysicalPath(self):
80            return self.path
81
82        def getPortalTypeName(self):
83            return self.__class__.__name__
84
85    class Document(MockContent):
86        pass
87
88    class Folder(MockContent, dict):
89        implements(IBaseFolder)
90
91        contentItems = dict.items
92        contentValues = dict.values
93
94    class MockPortal(MockContent, dict):
95        implements(IFolderish)
96
97        contentItems = dict.items
98        contentValues = dict.values
99
100    portal = MockPortal()
101
102    test.globs['plone'] = portal
103    test.globs['transmogrifier'].context = test.globs['plone']
104
105    portal.path = ('', 'plone')
106    portal['document1'] = Document()
107    portal['document1'].path = ('', 'plone', 'document1')
108    portal['folder1'] = Folder()
109    portal['folder1'].path = ('', 'plone', 'folder1')
110    portal['folder1']['document2'] = Document()
111    portal['folder1']['document2'].path = ('', 'plone', 'folder1', 'document2')
112    portal['folder1']['folder2'] = Folder()
113    portal['folder1']['folder2'].path = ('', 'plone', 'folder1', 'folder2')
114    portal['document3'] = Document()
115    portal['document3'].path = ('', 'plone', 'document3')
116
117def manifestSetUp(test):
118    sectionsSetUp(test)
119
120    root = dict(
121        _path='',
122        _entries=(
123            ('news', 'Folder'),
124            ('events', 'Folder'),
125            ('front-page', 'Document'),
126            ('only-in-manifest', 'Document')
127        )
128    )
129
130    news = dict(
131        _path='news',
132        _entries=(
133            ('aggregator', 'Topic'),
134            ('once-more', 'File')
135        )
136    )
137
138    aggregator = dict(
139        _path='news/aggregator',
140    )
141
142    events = dict(
143        _path='events'
144    )
145
146    front_page = dict(
147        _path='front-page',
148    )
149
150    members = dict(
151        _path='Members'
152    )
153
154    class ManifestSource(SampleSource):
155        classProvides(ISectionBlueprint)
156        implements(ISection)
157
158        def __init__(self, *args, **kw):
159            super(ManifestSource, self).__init__(*args, **kw)
160            self.sample = (root, dict(), news, aggregator, events, front_page, members)
161
162    provideUtility(ManifestSource,
163        name=u'quintagroup.transmogrifier.tests.manifestsource')
164
165def marshallSetUp(test):
166    sectionsSetUp(test)
167
168    from Products.Archetypes.interfaces import IBaseObject
169
170    class MockBase(object):
171        def checkCreationFlag(self):
172            return True
173
174        def unmarkCreationFlag(self):
175            pass
176
177        def at_post_create_script(self):
178            pass
179
180        def at_post_edit_script(self):
181            pass
182
183        indexed = ()
184        def indexObject(self):
185            self.indexed += (self._last_path,)
186
187    class MockCriterion(MockBase):
188        implements(IBaseObject)
189        _last_path = None
190        indexed = ()
191        def indexObject(self):
192            self.indexed += (self._last_path,)
193
194    class MockPortal(MockBase):
195        implements(IBaseObject)
196
197        criterion = MockCriterion()
198
199        _last_path = None
200        def unrestrictedTraverse(self, path, default):
201            if path[0] == '/':
202                return default # path is absolute
203            if isinstance(path, unicode):
204                return default
205            if path == 'not/existing/bar':
206                return default
207            if path == 'topic/criterion':
208                self._last_path = path
209                self.criterion._last_path = path
210                return self.criterion
211            if path.endswith('/notatcontent'):
212                return object()
213            self._last_path = path
214            return self
215
216        def getId(self):
217            return "plone"
218
219        indexed = ()
220        def indexObject(self):
221            self.indexed += (self._last_path,)
222
223        marshalled = ()
224        def marshall(self, instance, **kwargs):
225            self.marshalled += ((self._last_path, kwargs.get('atns_exclude')),)
226            # Marshall often fails to export topic criteria
227            if isinstance(instance, MockCriterion):
228                return None, None, None
229            else:
230                return None, None, "marshalled"
231
232        demarshalled = ()
233        def demarshall(self, instance, data):
234            # we don't need to test Marshall product, only check if we call it's components
235            self.demarshalled += (self._last_path,)
236
237    portal = MockPortal()
238    test.globs['plone'] = portal
239    test.globs['transmogrifier'].context = test.globs['plone']
240
241    from Products.Marshall import registry
242    def getComponent(name):
243        return portal
244    registry.getComponent = getComponent
245
246    class MarshallSource(SampleSource):
247        classProvides(ISectionBlueprint)
248        implements(ISection)
249
250        def __init__(self, *args, **kw):
251            super(MarshallSource, self).__init__(*args, **kw)
252            self.sample = (
253                dict(),
254                dict(_path='spam/eggs/foo', _excluded_fields=('file', 'image')),
255                dict(_path='topic/criterion'),
256                dict(_path='not/existing/bar'),
257                dict(_path='spam/eggs/notatcontent', 
258                     _files=dict(marshall=dict(data='xml', name='.marshall.xml'))),
259            )
260    provideUtility(MarshallSource,
261        name=u'quintagroup.transmogrifier.tests.marshallsource')
262
263def propertyManagerSetUp(test):
264    sectionsSetUp(test)
265
266    from OFS.interfaces import IPropertyManager
267
268    class MockPortal(object):
269        implements(IPropertyManager)
270
271        _properties = (
272            {'id':'title', 'type': 'string', 'mode': 'w'},
273            {'id':'description', 'type': 'string', 'mode': 'w'},
274            {'id':'encoding', 'type': 'string', 'mode': 'w'},
275            {'id':'author', 'type': 'string', 'mode': 'w'}
276        )
277
278        _last_path = None
279        def unrestrictedTraverse(self, path, default):
280            if path[0] == '/':
281                return default # path is absolute
282            if isinstance(path, unicode):
283                return default
284            if path == 'not/existing/bar':
285                return default
286            if path.endswith('/notatcontent'):
287                return object()
288            self._last_path = path
289            return self
290
291        def _propertyMap(self):
292            return self._properties
293
294        def getProperty(self, id, d=None):
295            return 'value'
296
297        def propdict(self):
298            d={}
299            for p in self._properties:
300                d[p['id']]=p
301            return d
302
303        updated = ()
304        def _updateProperty(self, id, value):
305            self.updated += ((self._last_path, id, value.strip()))
306
307    portal = MockPortal()
308    test.globs['plone'] = portal
309    test.globs['transmogrifier'].context = test.globs['plone']
310
311    class PropertyManagerSource(SampleSource):
312        classProvides(ISectionBlueprint)
313        implements(ISection)
314
315        def __init__(self, *args, **kw):
316            super(PropertyManagerSource, self).__init__(*args, **kw)
317            self.sample = (
318                dict(),
319                dict(_path='not/existing/bar'),
320                dict(_path='spam/eggs/notatcontent'),
321                dict(_path='spam/eggs/foo', _excluded_properties=('encoding',)),
322            )
323
324    provideUtility(PropertyManagerSource,
325        name=u'quintagroup.transmogrifier.tests.propertymanagersource')
326
327def commentsSetUp(test):
328    sectionsSetUp(test)
329
330    class MockDiscussionItem(object):
331        creator = 'creator'
332        modified = 'date'
333
334        def __init__(self, reply, text=""):
335            self.in_reply_to = reply
336            self.text = text
337
338        def __of__(self, container):
339            return self
340
341        def getMetadataHeaders(self):
342            return []
343
344        def setMetadata(self, headers):
345            pass
346
347        def Creator(self):
348            return self.creator
349
350        def addCreator(self, creator):
351            self.creator = creator
352
353        def ModificationDate(self):
354            return self.modified
355
356        def setModificationDate(self, date):
357            self.modified = date
358
359        def setFormat(self, format):
360            pass
361
362        def _edit(self, text=None):
363            self.text = text
364
365        def indexObject(self):
366            pass
367
368        def __repr__(self):
369            return "<DicussionItem %s %s %s %s>" % (
370                self.Creator(),
371                self.ModificationDate(),
372                self.in_reply_to,
373                self.text
374                )
375
376    from Products.CMFDefault import DiscussionItem
377    DiscussionItem.DiscussionItem = MockDiscussionItem
378
379    class MockPortal(object):
380        _discussion = {
381            '1': MockDiscussionItem(None, 'comment to content'),
382            '2': MockDiscussionItem('1', 'reply to first comment'),
383            '3': MockDiscussionItem(None, 'other comment to content')
384        }
385        _container = {}
386
387        @property
388        def talkback(self):
389            return self
390
391        def objectItems(self):
392            l = self._discussion.items()
393            l.sort(key=lambda x: int(x[0]))
394            return l
395
396        def unrestrictedTraverse(self, path, default):
397            if path[0] == '/':
398                return default # path is absolute
399            if isinstance(path, unicode):
400                return default
401            if path == 'not/existing/bar':
402                return default
403            if path.endswith('/notdiscussable'):
404                return object()
405            return self
406
407        def getDiscussionFor(self, obj):
408            return self
409
410    portal = MockPortal()
411    test.globs['plone'] = portal
412    test.globs['transmogrifier'].context = test.globs['plone']
413
414    class CommentsSource(SampleSource):
415        classProvides(ISectionBlueprint)
416        implements(ISection)
417
418        def __init__(self, *args, **kw):
419            super(CommentsSource, self).__init__(*args, **kw)
420            self.sample = (
421                dict(),
422                dict(_path='not/existing/bar'),
423                dict(_path='spam/eggs/notdiscussable'),
424                dict(_path='spam/eggs/foo'),
425            )
426
427    provideUtility(CommentsSource,
428        name=u'quintagroup.transmogrifier.tests.commentssource')
429
430
431def dataCorrectorSetUp(test):
432    sectionsSetUp(test)
433
434    class MockPortal(object):
435        def unrestrictedTraverse(self, path, default):
436            if path[0] == '/':
437                return default # path is absolute
438            if isinstance(path, unicode):
439                return default
440            if path == 'not/existing/bar':
441                return default
442            if path.endswith('/notadaptable'):
443                return object()
444            return self
445
446    portal = MockPortal()
447    test.globs['plone'] = portal
448    test.globs['transmogrifier'].context = test.globs['plone']
449
450    from quintagroup.transmogrifier.interfaces import IExportDataCorrector, \
451        IImportDataCorrector
452
453    class MockExportAdapter(object):
454        implements(IExportDataCorrector)
455        adapts(MockPortal)
456        def __init__(self, context):
457            self.context = context
458
459        def __call__(self, data):
460            return "modified export data"
461
462    provideAdapter(MockExportAdapter, name="marshall")
463
464    class MockImportAdapter(object):
465        implements(IImportDataCorrector)
466        adapts(MockPortal)
467        def __init__(self, context):
468            self.context = context
469
470        def __call__(self, data):
471            return "modified import data"
472
473    provideAdapter(MockImportAdapter, name="manifest")
474
475    class DataCorrectorSource(SampleSource):
476        classProvides(ISectionBlueprint)
477        implements(ISection)
478
479        def __init__(self, *args, **kw):
480            super(DataCorrectorSource, self).__init__(*args, **kw)
481            self.sample = (
482                dict(),
483                dict(_files=dict(marshall="item hasn't path")),
484                dict(_path='spam/eggs/foo'),
485                dict(_path='not/existing/bar'),
486                dict(_path='spam/eggs/notadaptable', _files=dict(marshall="object isn't adaptable")),
487                dict(_path='spam/eggs/foo',
488                     _files=dict(marshall='marshall data', unchanged='this must be unchanged')),
489                dict(_path='spam/eggs/foo',
490                     _files=dict(manifest='manifest data', unchanged='this must be unchanged')),
491            )
492
493    provideUtility(DataCorrectorSource,
494        name=u'quintagroup.transmogrifier.tests.datacorrectorsource')
495
496def writerSetUp(test):
497    sectionsSetUp(test)
498
499    class MockExportContext(object):
500        def __init__( self, *args, **kwargs):
501            self.args = args
502            for k, v in kwargs.items():
503                setattr(self, k, v)
504            self._wrote = []
505
506        def __getitem__(self, name):
507            return getattr(self, name, None)
508
509        def __contains__(self, name):
510            return hasattr(self, name)
511
512        def writeDataFile(self, filename, text, content_type, subdir=None):
513            filename = '%s/%s' % (subdir, filename)
514            self._wrote.append((filename, text, content_type))
515
516        def __repr__(self):
517            s = " ".join(["%s=%s" % (k,v) for k,v in self.__dict__.items()])
518            return "<%s %s>" % (self.__class__.__name__, s)
519
520
521    from Products.GenericSetup import context
522
523    context.DirectoryExportContext = type('Directory', (MockExportContext,), {})
524    context.TarballExportContext = type('Tarball', (MockExportContext,), {})
525    context.SnapshotExportContext = type('Snapshot', (MockExportContext,), {})
526
527    class WriterSource(SampleSource):
528        classProvides(ISectionBlueprint)
529        implements(ISection)
530
531        def __init__(self, *args, **kw):
532            super(WriterSource, self).__init__(*args, **kw)
533            self.sample = (
534                dict(_path='spam/eggs/foo'),
535                dict(_files=dict(mock=dict(name='.first.xml', data='some data'))),
536                dict(_path='spam/eggs/foo',
537                     _files=dict(mock=dict(name='.first.xml', data='some data'),
538                                 other=dict(name='.second.xml', data='other data'))),
539                dict(_path='other/path',
540                     _files=dict(mock=dict(name='.third.xml', data='some data')))
541            )
542
543    provideUtility(WriterSource,
544        name=u'quintagroup.transmogrifier.tests.writersource')
545
546    class SingleItemSource(SampleSource):
547        classProvides(ISectionBlueprint)
548        implements(ISection)
549
550        def __init__(self, *args, **kw):
551            super(SingleItemSource, self).__init__(*args, **kw)
552            self.sample = (
553                dict(_path='', _files={}),
554            )
555
556    provideUtility(SingleItemSource,
557        name=u"quintagroup.transmogrifier.tests.singleitemsource")
558
559def readerSetUp(test):
560    sectionsSetUp(test)
561
562    class MockImportContext(object):
563
564        _dirs = [
565            'structure',
566            'structure/news', 'structure/news/recent',
567            'structure/pages', 'structure/pages/front-page',
568        ]
569        _files = [
570            'structure/.properties.xml',
571            'structure/other.file',
572            'structure/news/.objects.xml',
573            'structure/pages/.objects.xml',
574            'structure/pages/front-page/.marshall.xml',
575            'structure/pages/front-page/.comments.xml',
576        ]
577
578        def __init__( self, *args, **kwargs):
579            self.args = args
580            for k, v in kwargs.items():
581                setattr(self, k, v)
582
583        def __repr__(self):
584            s = " ".join(["%s=%s" % (k,v) for k,v in self.__dict__.items()])
585            return "<%s %s>" % (self.__class__.__name__, s)
586
587        def readDataFile(self, filename, subdir=None):
588            return 'some data'
589
590        def isDirectory(self, path):
591            return path == '' or path in self._dirs
592
593        def listDirectory(self, path):
594            all_names = self._dirs + self._files
595            if path:
596                pfx_len = len(path)+1
597            else:
598                pfx_len = 0
599            names = []
600            for name in all_names:
601                if name == path:
602                    continue
603                if not name.startswith(path):
604                    continue
605                name = name[pfx_len:]
606                if '/' in name:
607                    continue
608                names.append(name)
609            return names
610
611    from Products.GenericSetup import context
612
613    context.DirectoryImportContext = type('Directory', (MockImportContext,),
614        {'listDirectory': lambda self, path: []})
615    context.TarballImportContext = type('Tarball', (MockImportContext,), {})
616    context.SnapshotImportContext = type('Snapshot', (MockImportContext,),
617        {'listDirectory': lambda self, path: []})
618
619def substitutionSetUp(test):
620    sectionsSetUp(test)
621
622    class SubstitutionSource(SampleSource):
623        classProvides(ISectionBlueprint)
624        implements(ISection)
625
626        def __init__(self, *args, **kw):
627            super(SubstitutionSource, self).__init__(*args, **kw)
628            self.sample = (
629                {},
630                {'_type': 'Blog'},
631                {'_type': 'PloneFormMailer'},
632                {'_type': 'Document'},
633            )
634
635    provideUtility(SubstitutionSource,
636        name=u'quintagroup.transmogrifier.tests.substitutionsource')
637
638class MetaDirectivesTests(unittest.TestCase):
639    def setUp(self):
640        zcml.load_config('meta.zcml', quintagroup.transmogrifier)
641
642    def tearDown(self):
643        stylesheet_registry.clear()
644        cleanup.cleanUp()
645
646    def testEmptyZCML(self):
647        zcml.load_string('''\
648<configure xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier">
649</configure>''')
650        self.assertEqual(stylesheet_registry.listStylesheetNames(), ())
651
652    def testConfigZCML(self):
653        zcml.load_string('''\
654<configure
655    xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier">
656<transmogrifier:stylesheet
657    source="marshall"
658    from="Blog"
659    to="Weblog"
660    file="blog.xsl"
661    />
662</configure>''')
663        self.assertEqual(stylesheet_registry.listStylesheetNames(),
664                         (u'marshall:Blog:Weblog',))
665        path = os.path.split(quintagroup.transmogrifier.__file__)[0]
666        self.assertEqual(
667            stylesheet_registry.getStylesheet('marshall', 'Blog', 'Weblog'),
668            dict(from_=u'Blog',
669                 to=u'Weblog',
670                 file=os.path.join(path, 'blog.xsl'))
671        )
672
673    def testMultipleZCML(self):
674        zcml.load_string('''\
675<configure
676    xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier">
677<transmogrifier:stylesheet
678    source="marshall"
679    from="Blog"
680    to="Weblog"
681    file="blog.xsl"
682    />
683<transmogrifier:stylesheet
684    source="propertymanager"
685    from="BlogEntry"
686    to="WeblogEntry"
687    file="blogentry.xsl"
688    />
689</configure>''')
690        self.assertEqual(stylesheet_registry.listStylesheetNames(),
691                         (u'marshall:Blog:Weblog', u'propertymanager:BlogEntry:WeblogEntry'))
692
693def xsltSetUp(test):
694    sectionsSetUp(test)
695
696    class XSLTSource(SampleSource):
697        classProvides(ISectionBlueprint)
698        implements(ISection)
699
700        def __init__(self, *args, **kw):
701            super(XSLTSource, self).__init__(*args, **kw)
702            self.sample = (
703                {},
704                {'_type': 'Weblog'},
705                {'_old_type': 'Blog'},
706                {'_old_type': 'Blog',
707                 '_type': 'Weblog',
708                 '_files': {'manifest': {'data': 'xml', 'name': 'manifest.xml'}}},
709                {'_old_type': 'Blog',
710                 '_type': 'Weblog',
711                 '_files': {'marshall': {'data': 'xml', 'name': 'marshall.xml'}}},
712            )
713
714    provideUtility(XSLTSource,
715        name=u'quintagroup.transmogrifier.tests.xsltsource')
716
717    from quintagroup.transmogrifier.xslt import XSLTSection, stylesheet_registry
718
719    XSLTSection.applyTransformations = lambda self, xml, xslt: 'transformed xml'
720    test.globs['stylesheet_registry'] = stylesheet_registry
721
722def binarySetUp(test):
723    sectionsSetUp(test)
724
725    from Products.Archetypes.interfaces import IBaseObject
726
727    class MockPortal(object):
728        implements(IBaseObject)
729
730        _last_path = None
731        def unrestrictedTraverse(self, path, default):
732            if path[0] == '/':
733                return default # path is absolute
734            if isinstance(path, unicode):
735                return default
736            if path == 'not/existing/bar':
737                return default
738            if path.endswith('/notatcontent'):
739                return object()
740            self._last_path = path
741            return self
742
743        fields = ['id', 'title', 'file', 'image']
744
745        def Schema(self):
746            return dict.fromkeys(self.fields)
747
748        def isBinary(self, field):
749            return field in ('file',) #, 'image')
750
751        def getField(self, field):
752            return self
753
754        def getBaseUnit(self, obj):
755            return self
756
757        def getFilename(self):
758            return "archive.tar.gz"
759
760        def getContentType(self):
761            return 'application/x-tar'
762
763        def getRaw(self):
764            return "binary data"
765
766        def getMutator(self, obj):
767            return self
768
769        updated = ()
770        def __call__(self, data, filename=None, mimetype=None):
771            self.updated += (filename, mimetype, data)
772
773    portal = MockPortal()
774    test.globs['plone'] = portal
775    test.globs['transmogrifier'].context = test.globs['plone']
776
777    class BinarySource(SampleSource):
778        classProvides(ISectionBlueprint)
779        implements(ISection)
780
781        def __init__(self, *args, **kw):
782            super(BinarySource, self).__init__(*args, **kw)
783            self.sample = (
784                dict(),
785                dict(_path='not/existing/bar'),
786                dict(_path='spam/eggs/notatcontent'),
787                dict(_path='spam/eggs/foo'),
788            )
789
790    provideUtility(BinarySource,
791        name=u'quintagroup.transmogrifier.tests.binarysource')
792
793from DateTime import DateTime
794
795def catalogSourceSetUp(test):
796    sectionsSetUp(test)
797
798    class MockContent(dict):
799        def __init__(self, **kw):
800            self.update(kw)
801            self['id'] = self.getId
802
803        def getPath(self):
804            return self['path']
805
806        @property
807        def getId(self):
808            path = self.getPath()
809            return path.rsplit('/', 1)[-1]
810
811        @property
812        def portal_type(self):
813            return self['portal_type']
814
815        @property
816        def is_folderish(self):
817            return self['portal_type'] == 'Folder' and True or False
818
819    class MockPortal(dict):
820
821        content = ()
822        def __call__(self, **kw):
823            res = []
824            for obj in self.content:
825                matched = True
826                for index, query in kw.items():
827                    if index not in obj:
828                        matched = False
829                        break
830                    if matched and index == 'modified':
831                        if isinstance(query, dict):
832                            value = query['query']
833                            range_ = query['range']
834                            if range_ == 'min' and DateTime(obj[index]) >= DateTime(value):
835                                matched = True
836                            elif range_ == 'max' and DateTime(obj[index]) <= DateTime(value):
837                                matched = True
838                            else:
839                                matched = False
840                        else:
841                            if DateTime(obj[index]) == DateTime(query):
842                                matched = True
843                            else:
844                                matched = False
845                    elif matched and index == 'path':
846                        if obj[index].startswith(query):
847                            matched = True
848                        else:
849                            matched = False
850                    elif matched:
851                        if obj[index] == query:
852                            matched = True
853                        else:
854                            matched = False
855                if matched:
856                    res.append(obj)
857
858            return res
859
860    portal = MockPortal()
861    doc1 = MockContent(path='/plone/document1', portal_type='Document',
862        modified='2008-11-01T12:00:00Z')
863    folder1 = MockContent(path='/plone/folder1', portal_type='Folder',
864        modified='2008-11-01T12:00:00Z')
865    doc2 = MockContent(path='/plone/folder1/document2', portal_type='Document',
866        modified='2008-11-02T12:00:00Z')
867    doc3 = MockContent(path='/plone/folder1/document3', portal_type='Document',
868        modified='2008-11-02T12:00:00Z')
869    folder2 = MockContent(path='/plone/folder2', portal_type='Folder',
870        modified='2008-11-02T12:00:00Z')
871    doc4 = MockContent(path='/plone/folder2/document4', portal_type='Document',
872        modified='2008-11-01T12:00:00Z')
873    comment = MockContent(path='/plone/folder2/document4/talkback/1234567890', portal_type='Discussion Item',
874        modified='2008-11-02T12:00:00Z')
875    # items are sorted on their modification date
876    portal.content = (doc1, folder1, folder2, doc2, doc3, doc4, comment)
877
878    test.globs['plone'] = portal
879    test.globs['transmogrifier'].context = test.globs['plone']
880
881def test_suite():
882    import sys
883    suite = unittest.findTestCases(sys.modules[__name__])
884    suite.addTests((
885        doctest.DocFileSuite(
886            'sitewalker.txt',
887            setUp=siteWalkerSetUp, tearDown=tearDown),
888        doctest.DocFileSuite(
889            'manifest.txt',
890            setUp=manifestSetUp, tearDown=tearDown),
891        doctest.DocFileSuite(
892            'marshall.txt',
893            setUp=marshallSetUp, tearDown=tearDown),
894        doctest.DocFileSuite(
895            'propertymanager.txt',
896            setUp=propertyManagerSetUp, tearDown=tearDown),
897        doctest.DocFileSuite(
898            'comments.txt',
899            setUp=commentsSetUp, tearDown=tearDown),
900        doctest.DocFileSuite(
901            'datacorrector.txt',
902            setUp=dataCorrectorSetUp, tearDown=tearDown),
903        doctest.DocFileSuite(
904            'writer.txt',
905            setUp=writerSetUp, tearDown=tearDown),
906        doctest.DocFileSuite(
907            'reader.txt',
908            setUp=readerSetUp, tearDown=tearDown),
909        doctest.DocFileSuite(
910            'substitution.txt',
911            setUp=substitutionSetUp, tearDown=tearDown),
912        doctest.DocFileSuite(
913            'xslt.txt',
914            setUp=xsltSetUp, tearDown=tearDown),
915        doctest.DocFileSuite(
916            'binary.txt',
917            setUp=binarySetUp, tearDown=tearDown),
918        doctest.DocFileSuite(
919            'catalogsource.txt',
920            setUp=catalogSourceSetUp, tearDown=tearDown),
921    ))
922    return suite
Note: See TracBrowser for help on using the repository browser.