[Checkins] SVN: z3c.table/branches/lazyvalues2/ - ``IValues`` conform to ``len`` protocol. ``table.Table`` has new
Godefroid Chapelle
gotcha at bubblenet.be
Thu Aug 5 10:11:34 EDT 2010
Log message for revision 115495:
- ``IValues`` conform to ``len`` protocol. ``table.Table`` has new
``allRowsCount`` attribute that surfaces the total number of rows.
- ``table.Table`` modified to use the new ``IValues`` attributes.
- ``IValues`` has two new attributes: ``isSorted`` and ``sortOn``.
They can be queried by tables to avoid to sort again when values where
initially sorted (for example, values coming from a sorted SQL query).
- Add tests that verify interfaces for classes in ``value.py``
Changed:
U z3c.table/branches/lazyvalues2/CHANGES.txt
U z3c.table/branches/lazyvalues2/src/z3c/table/README.txt
U z3c.table/branches/lazyvalues2/src/z3c/table/interfaces.py
U z3c.table/branches/lazyvalues2/src/z3c/table/table.py
U z3c.table/branches/lazyvalues2/src/z3c/table/tests.py
U z3c.table/branches/lazyvalues2/src/z3c/table/value.py
-=-
Modified: z3c.table/branches/lazyvalues2/CHANGES.txt
===================================================================
--- z3c.table/branches/lazyvalues2/CHANGES.txt 2010-08-05 12:59:56 UTC (rev 115494)
+++ z3c.table/branches/lazyvalues2/CHANGES.txt 2010-08-05 14:11:34 UTC (rev 115495)
@@ -2,12 +2,24 @@
CHANGES
=======
-0.8.2 (unreleased)
+0.9.0 (unreleased)
------------------
-- Split single doctest file (README.txt) into different files
+- ``IValues`` conform to ``len`` protocol. ``table.Table`` has new
+ ``allRowsCount`` attribute that surfaces the total number of rows.
+- ``table.Table`` modified to use the new ``IValues`` attributes.
+
+- ``IValues`` has two new attributes: ``isSorted`` and ``sortOn``.
+ They can be queried by tables to avoid to sort again when values where
+ initially sorted (for example, values coming from a sorted SQL query).
+
+- Add tests that verify interfaces for classes in ``value.py``
+
+- Split single doctest file (``README.txt``) into different files
+
+
0.8.1 (2010-07-31)
------------------
Modified: z3c.table/branches/lazyvalues2/src/z3c/table/README.txt
===================================================================
--- z3c.table/branches/lazyvalues2/src/z3c/table/README.txt 2010-08-05 12:59:56 UTC (rev 115494)
+++ z3c.table/branches/lazyvalues2/src/z3c/table/README.txt 2010-08-05 14:11:34 UTC (rev 115495)
@@ -76,10 +76,18 @@
>>> request = TestRequest()
>>> plainTable = table.Table(container, request)
-Now we can update and render the table. As you can see with an empty container
-we will not get anything that looks like a table. We just get an empty string:
>>> plainTable.update()
+
+We can check the number of rows in the container.
+
+ >>> plainTable.allRowsCount
+ 3
+
+Now we render the table. As there are no columns,
+we will not get anything that looks like a table.
+We just get an empty string:
+
>>> plainTable.render()
u''
Modified: z3c.table/branches/lazyvalues2/src/z3c/table/interfaces.py
===================================================================
--- z3c.table/branches/lazyvalues2/src/z3c/table/interfaces.py 2010-08-05 12:59:56 UTC (rev 115494)
+++ z3c.table/branches/lazyvalues2/src/z3c/table/interfaces.py 2010-08-05 14:11:34 UTC (rev 115495)
@@ -22,7 +22,20 @@
values = zope.interface.Attribute('Iterable table row data sequence.')
+ def __len__():
+ """Count of rows"""
+ isSorted = zope.schema.Bool(
+ title=_(u'isSorted'),
+ description=_(u'True if values are sorted.'),
+ default=False)
+
+ sortOn = zope.schema.TextLine(
+ title=_(u'Sort on table column id'),
+ description=_(u'Sort on table column id'),
+ default=u'')
+
+
class ITable(zope.contentprovider.interfaces.IContentProvider):
"""Table provider"""
@@ -72,10 +85,10 @@
required=False)
# sort attributes
- sortOn = zope.schema.Int(
- title=_(u'Sort on table index'),
- description=_(u'Sort on table index'),
- default=0)
+ sortOn = zope.schema.TextLine(
+ title=_(u'Sort on table column id'),
+ description=_(u'Sort on table column id'),
+ default=u'')
sortOrder = zope.schema.TextLine(
title=_(u'Sort order'),
Modified: z3c.table/branches/lazyvalues2/src/z3c/table/table.py
===================================================================
--- z3c.table/branches/lazyvalues2/src/z3c/table/table.py 2010-08-05 12:59:56 UTC (rev 115494)
+++ z3c.table/branches/lazyvalues2/src/z3c/table/table.py 2010-08-05 14:11:34 UTC (rev 115495)
@@ -78,6 +78,8 @@
sortColumn = None
sortOrder = u'ascending'
reverseSortOrderNames = [u'descending', u'reverse', u'down']
+ hasSortedValues = False
+ valuesSortedOn = 0
# batch attributes
batchProviderName = 'batch'
@@ -116,6 +118,9 @@
def values(self):
adapter = zope.component.getMultiAdapter(
(self.context, self.request, self), interfaces.IValues)
+ self.allRowsCount = len(adapter)
+ self.hasSortedValues = adapter.isSorted
+ self.valuesSortedOn = adapter.sortOn
return adapter.values
# setup
@@ -185,8 +190,20 @@
return self.request.get(self.prefix + '-sortOrder',
self.sortOrder)
+ def _mustSort(self):
+ return (
+ # There is data to sort
+ (self.rows and self.columns)
+ # and there is a sort criteria
+ and (self.sortOn is not None)
+ # and, or values are not sorted
+ and (not self.hasSortedValues
+ # or, even though values are sorted,
+ # they are not sorted on the right criteria
+ or (self.hasSortedValues and self.valuesSortedOn != self.sortOn)))
+
def sortRows(self):
- if self.sortOn is not None and self.rows and self.columns:
+ if self._mustSort():
sortOnIdx = self.columnIndexById.get(self.sortOn, 0)
sortKeyGetter = getSortMethod(sortOnIdx)
rows = sorted(self.rows, key=sortKeyGetter)
Modified: z3c.table/branches/lazyvalues2/src/z3c/table/tests.py
===================================================================
--- z3c.table/branches/lazyvalues2/src/z3c/table/tests.py 2010-08-05 12:59:56 UTC (rev 115494)
+++ z3c.table/branches/lazyvalues2/src/z3c/table/tests.py 2010-08-05 14:11:34 UTC (rev 115495)
@@ -18,7 +18,11 @@
import unittest
import doctest
+
+from zope.interface import Interface
+from zope.component import getSiteManager
from zope.publisher.browser import TestRequest
+from zope.publisher.interfaces.browser import IBrowserRequest
import z3c.testing
from z3c.batching.batch import Batch
@@ -27,6 +31,7 @@
from z3c.table import table
from z3c.table import column
from z3c.table import batch
+from z3c.table import value
class FakeContainer(object):
@@ -34,7 +39,10 @@
def values(self):
pass
+ def __len__(self):
+ return 0
+
# table
class TestTable(z3c.testing.InterfaceBaseTest):
@@ -63,9 +71,46 @@
return table.SequenceTable
def getTestPos(self):
- return (None, TestRequest())
+ return ([], TestRequest())
+# values
+class TestValuesForContainer(z3c.testing.InterfaceBaseTest):
+
+ def setUp(test):
+ testing.setUpAdapters()
+
+ def getTestInterface(self):
+ return interfaces.IValues
+
+ def getTestClass(self):
+ return value.ValuesForContainer
+
+ def getTestPos(self):
+ container = FakeContainer()
+ request = TestRequest()
+ tableInstance = table.Table(container, request)
+ return (container, request, tableInstance)
+
+
+class TestValuesForSequence(z3c.testing.InterfaceBaseTest):
+
+ def setUp(test):
+ testing.setUpAdapters()
+
+ def getTestInterface(self):
+ return interfaces.IValues
+
+ def getTestClass(self):
+ return value.ValuesForSequence
+
+ def getTestPos(self):
+ container = FakeContainer()
+ request = TestRequest()
+ tableInstance = table.Table(container, request)
+ return (container, request, tableInstance)
+
+
# column
class TestColumn(z3c.testing.InterfaceBaseTest):
@@ -147,6 +192,80 @@
return ({}, TestRequest(), t)
+class NumberColumn(column.Column):
+
+ weight = 10
+ header = u'Number'
+
+ def renderCell(self, item):
+ return item
+
+
+SORT_ON_ID = "table-number-1"
+
+
+def sortedValues(valuesAreSorted):
+
+ class SortedValues(value.ValuesForSequence):
+
+ sortOn = SORT_ON_ID
+ isSorted = valuesAreSorted
+
+ return SortedValues
+
+
+def withIValuesAdapter(klass):
+
+ def decorator(func):
+
+ def decorated(self):
+ self.sm.registerAdapter(klass,
+ (Interface, IBrowserRequest, interfaces.ISequenceTable),
+ interfaces.IValues)
+ func(self)
+ self.sm.unregisterAdapter(klass,
+ (Interface, IBrowserRequest, interfaces.ISequenceTable),
+ interfaces.IValues)
+ return decorated
+ return decorator
+
+
+class TestSortedValues(unittest.TestCase):
+
+ def setUp(self):
+ self.sm = sm = getSiteManager()
+ sm.registerAdapter(NumberColumn,
+ (None, None, interfaces.ITable),
+ interfaces.IColumn, name='number')
+
+ @withIValuesAdapter(sortedValues(True))
+ def testHasSortedValuesRightCriteria(self):
+ request = TestRequest(form={'table-sortOn': 'table-number-1'})
+ tableInstance = table.SequenceTable([1], request)
+ tableInstance.update()
+ self.failUnless(tableInstance.hasSortedValues)
+ self.assertEquals(tableInstance.valuesSortedOn, SORT_ON_ID)
+ self.failIf(tableInstance._mustSort())
+
+ @withIValuesAdapter(sortedValues(True))
+ def testHasSortedValuesWrongCriteria(self):
+ request = TestRequest(form={'table-sortOn': 'table-number-2'})
+ tableInstance = table.SequenceTable([1], request)
+ tableInstance.update()
+ self.failUnless(tableInstance.hasSortedValues)
+ self.assertNotEquals(tableInstance.sortOn, SORT_ON_ID)
+ self.assertEquals(tableInstance.valuesSortedOn, SORT_ON_ID)
+ self.failUnless(tableInstance._mustSort())
+
+ @withIValuesAdapter(sortedValues(False))
+ def testHasNoSortedValues(self):
+ request = TestRequest(form={'table-sortOn': 'table-number-2'})
+ tableInstance = table.SequenceTable([1], request)
+ tableInstance.update()
+ self.failIf(tableInstance.hasSortedValues)
+ self.failUnless(tableInstance._mustSort())
+
+
def test_suite():
return unittest.TestSuite((
doctest.DocFileSuite('README.txt',
@@ -176,6 +295,9 @@
),
unittest.makeSuite(TestTable),
unittest.makeSuite(TestSequenceTable),
+ unittest.makeSuite(TestValuesForContainer),
+ unittest.makeSuite(TestValuesForSequence),
+ unittest.makeSuite(TestSortedValues),
unittest.makeSuite(TestColumn),
unittest.makeSuite(TestNoneCell),
unittest.makeSuite(TestNameColumn),
Modified: z3c.table/branches/lazyvalues2/src/z3c/table/value.py
===================================================================
--- z3c.table/branches/lazyvalues2/src/z3c/table/value.py 2010-08-05 12:59:56 UTC (rev 115494)
+++ z3c.table/branches/lazyvalues2/src/z3c/table/value.py 2010-08-05 14:11:34 UTC (rev 115495)
@@ -18,6 +18,7 @@
import zope.interface
from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.schema.fieldproperty import FieldProperty
from z3c.table import interfaces
@@ -27,12 +28,18 @@
zope.interface.implements(interfaces.IValues)
+ isSorted = FieldProperty(interfaces.IValues['isSorted'])
+ sortOn = FieldProperty(interfaces.IValues['sortOn'])
+
def __init__(self, context, request, table):
self.context = context
self.request = request
self.table = table
+ def __len__(self):
+ return len(self.context)
+
class ValuesForContainer(ValuesMixin):
"""Values from a simple IContainer."""
More information about the checkins
mailing list