[Zope-Checkins] CVS: Zope/lib/python/Products/PluginIndexes/FieldIndex/tests - testFieldIndex.py:1.2
Tres Seaver
tseaver@zope.com
Mon, 22 Oct 2001 21:15:42 -0400
Update of /cvs-repository/Zope/lib/python/Products/PluginIndexes/FieldIndex/tests
In directory cvs.zope.org:/tmp/cvs-serv4608/lib/python/Products/PluginIndexes/FieldIndex/tests
Added Files:
testFieldIndex.py
Log Message:
- Restore tests lost on branch (update doesn't pick them up?)
=== Zope/lib/python/Products/PluginIndexes/FieldIndex/tests/testFieldIndex.py 1.1 => 1.2 ===
+#
+# Zope Public License (ZPL) Version 1.0
+# -------------------------------------
+#
+# Copyright (c) Digital Creations. All rights reserved.
+#
+# This license has been certified as Open Source(tm).
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# 1. Redistributions in source code must retain the above copyright
+# notice, this list of conditions, and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions, and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. Digital Creations requests that attribution be given to Zope
+# in any manner possible. Zope includes a "Powered by Zope"
+# button that is installed by default. While it is not a license
+# violation to remove this button, it is requested that the
+# attribution remain. A significant investment has been put
+# into Zope, and this effort will continue if the Zope community
+# continues to grow. This is one way to assure that growth.
+#
+# 4. All advertising materials and documentation mentioning
+# features derived from or use of this software must display
+# the following acknowledgement:
+#
+# "This product includes software developed by Digital Creations
+# for use in the Z Object Publishing Environment
+# (http://www.zope.org/)."
+#
+# In the event that the product being advertised includes an
+# intact Zope distribution (with copyright and license included)
+# then this clause is waived.
+#
+# 5. Names associated with Zope or Digital Creations must not be used to
+# endorse or promote products derived from this software without
+# prior written permission from Digital Creations.
+#
+# 6. Modified redistributions of any form whatsoever must retain
+# the following acknowledgment:
+#
+# "This product includes software developed by Digital Creations
+# for use in the Z Object Publishing Environment
+# (http://www.zope.org/)."
+#
+# Intact (re-)distributions of any official Zope release do not
+# require an external acknowledgement.
+#
+# 7. Modifications are encouraged but must be packaged separately as
+# patches to official Zope releases. Distributions that do not
+# clearly separate the patches from the original work must be clearly
+# labeled as unofficial distributions. Modifications which do not
+# carry the name Zope may be packaged in any form, as long as they
+# conform to all of the clauses above.
+#
+#
+# Disclaimer
+#
+# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
+# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#
+# This software consists of contributions made by Digital Creations and
+# many individuals on behalf of Digital Creations. Specific
+# attributions are listed in the accompanying credits file.
+#
+##############################################################################
+
+import os, sys, unittest
+
+import ZODB
+from Products.PluginIndexes.FieldIndex.FieldIndex import FieldIndex
+
+class Dummy:
+
+ def __init__( self, foo ):
+ self._foo = foo
+
+ def foo( self ):
+ return self._foo
+
+ def __str__( self ):
+ return '<Dummy: %s>' % self._foo
+
+ __repr__ = __str__
+
+class TestCase( unittest.TestCase ):
+ """
+ Test FieldIndex objects.
+ """
+
+ def setUp( self ):
+ """
+ """
+ self._index = FieldIndex( 'foo' )
+ self._marker = []
+ self._values = [ ( 0, Dummy( 'a' ) )
+ , ( 1, Dummy( 'ab' ) )
+ , ( 2, Dummy( 'abc' ) )
+ , ( 3, Dummy( 'abca' ) )
+ , ( 4, Dummy( 'abcd' ) )
+ , ( 5, Dummy( 'abce' ) )
+ , ( 6, Dummy( 'abce' ) )
+ , ( 7, Dummy( 0 ) ) # Collector #1959
+ , ( 8, Dummy(None) )]
+ self._forward = {}
+ self._backward = {}
+ for k, v in self._values:
+ self._backward[k] = v
+ keys = self._forward.get( v, [] )
+ self._forward[v] = keys
+
+ self._noop_req = { 'bar': 123 }
+ self._request = { 'foo': 'abce' }
+ self._min_req = { 'foo': 'abc'
+ , 'foo_usage': 'range:min'
+ }
+ self._max_req = { 'foo': 'abc'
+ , 'foo_usage': 'range:max'
+ }
+ self._range_req = { 'foo': ( 'abc', 'abcd' )
+ , 'foo_usage': 'range:min:max'
+ }
+ self._zero_req = { 'foo': 0 }
+ self._none_req = { 'foo': None }
+
+
+ def tearDown( self ):
+ """
+ """
+
+ def _populateIndex( self ):
+ for k, v in self._values:
+ self._index.index_object( k, v )
+
+ def _checkApply( self, req, expectedValues ):
+ result, used = self._index._apply_index( req )
+ if hasattr(result, 'keys'):
+ result = result.keys()
+ assert used == ( 'foo', )
+ assert len( result ) == len( expectedValues ), \
+ '%s | %s' % ( map( None, result ), expectedValues )
+ for k, v in expectedValues:
+ assert k in result
+
+ def testEmpty( self ):
+ "Test an empty FieldIndex."
+
+ assert len( self._index ) == 0
+ assert len( self._index.referencedObjects() ) == 0
+
+ assert self._index.getEntryForObject( 1234 ) is None
+ assert ( self._index.getEntryForObject( 1234, self._marker )
+ is self._marker )
+ self._index.unindex_object( 1234 ) # nothrow
+
+ assert self._index.hasUniqueValuesFor( 'foo' )
+ assert not self._index.hasUniqueValuesFor( 'bar' )
+ assert len( self._index.uniqueValues( 'foo' ) ) == 0
+
+ assert self._index._apply_index( self._noop_req ) is None
+ self._checkApply( self._request, [] )
+ self._checkApply( self._min_req, [] )
+ self._checkApply( self._max_req, [] )
+ self._checkApply( self._range_req, [] )
+
+ def testPopulated( self ):
+ """ Test a populated FieldIndex """
+ self._populateIndex()
+ values = self._values
+
+ assert len( self._index ) == len( values )-1 #'abce' is duplicate
+ assert len( self._index.referencedObjects() ) == len( values )
+
+ assert self._index.getEntryForObject( 1234 ) is None
+ assert ( self._index.getEntryForObject( 1234, self._marker )
+ is self._marker )
+ self._index.unindex_object( 1234 ) # nothrow
+
+ for k, v in values:
+ assert self._index.getEntryForObject( k ) == v.foo()
+
+ assert len( self._index.uniqueValues( 'foo' ) ) == len( values )-1
+
+ assert self._index._apply_index( self._noop_req ) is None
+
+ self._checkApply( self._request, values[ -4:-2 ] )
+ self._checkApply( self._min_req, values[ 2:-2 ] )
+ self._checkApply( self._max_req, values[ :3 ] + values[ -2: ] )
+ self._checkApply( self._range_req, values[ 2:5 ] )
+
+ def testZero( self ):
+ """ Make sure 0 gets indexed """
+ self._populateIndex()
+ values = self._values
+ self._checkApply( self._zero_req, values[ -2:-1 ] )
+ assert 0 in self._index.uniqueValues( 'foo' )
+
+ def testNone(self):
+ """ make sure None gets indexed """
+ self._populateIndex()
+ values = self._values
+ self._checkApply(self._none_req, values[-1:])
+ assert None in self._index.uniqueValues('foo')
+
+ def testRange(self):
+ """Test a range search"""
+ index = FieldIndex( 'foo' )
+ for i in range(100):
+ index.index_object(i, Dummy(i%10))
+
+ r=index._apply_index({
+ 'foo_usage': 'range:min:max',
+ 'foo': [-99, 3]})
+
+ assert tuple(r[1])==('foo',), r[1]
+ r=list(r[0].keys())
+
+ expect=[
+ 0, 1, 2, 3, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33,
+ 40, 41, 42, 43, 50, 51, 52, 53, 60, 61, 62, 63, 70, 71, 72, 73,
+ 80, 81, 82, 83, 90, 91, 92, 93
+ ]
+
+ assert r==expect, r
+
+def test_suite():
+ return unittest.makeSuite( TestCase )