def testLastOneDoesnotReturnValue(self):
        multi = MultiLevelDrilldown(
            {'date': [('yearAndMonth', 2, False), ('year', 2, False)]})
        drilldown = CallTrace('Drilldown')
        doDrilldownArguments = []

        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            doDrilldownArguments.append(
                (bitMatrixRow, fieldNamesAndMaxResults))
            self.assertEqual(1, len(fieldNamesAndMaxResults))
            levelField, levelMax, levelSorted = fieldNamesAndMaxResults[0]
            if levelField == 'yearAndMonth':
                return iter([('yearAndMonth',
                              iter([('2008-01', 11), ('2008-02', 2),
                                    ('2007-12', 1)][:levelMax]))])
            else:
                return iter([('year', iter([]))])
            yield

        drilldown.drilldown = doDrilldown
        multi.addObserver(drilldown)

        result = list(
            compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))

        self.assertEqual(2, len(doDrilldownArguments))
        self.assertEqual(('bitMatrixRow', [('yearAndMonth', 2, False)]),
                         doDrilldownArguments[0])
        self.assertEqual(('bitMatrixRow', [('year', 2, False)]),
                         doDrilldownArguments[1])
        self.assertEqual(1, len(result))
        (inField, realField), termCounts = result[0]
        self.assertEqual('yearAndMonth', realField)
        self.assertEqual([('2008-01', 11), ('2008-02', 2)], list(termCounts))
    def testLastZeroReturnValue(self):
        multi = MultiLevelDrilldown(
            {'date': [('yearAndMonth', 2, False), ('year', 2, False)]})
        drilldown = CallTrace('Drilldown')
        doDrilldownArguments = []

        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            doDrilldownArguments.append(
                (bitMatrixRow, fieldNamesAndMaxResults))
            self.assertEqual(1, len(fieldNamesAndMaxResults))
            levelField, levelMax, sorted = fieldNamesAndMaxResults[0]
            if levelField == 'yearAndMonth':
                return iter([('yearAndMonth', iter([]))])
            else:
                return iter([('year', iter([]))])
            yield

        drilldown.drilldown = doDrilldown
        multi.addObserver(drilldown)

        result = list(
            compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))

        self.assertEqual(1, len(result))
        (inField, realField), termCounts = result[0]
        self.assertEqual(None, realField)
    def testFieldWithMultiLevel(self):
        multi = MultiLevelDrilldown(
            {'date':[('yearAndMonth', 2, False), ('year', 2, False)]
            }
        )
        drilldown = CallTrace('Drilldown')
        doDrilldownArguments = []
        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            doDrilldownArguments.append((bitMatrixRow, fieldNamesAndMaxResults))
            self.assertEquals(1, len(fieldNamesAndMaxResults))
            levelField, levelMax, levelSorted = fieldNamesAndMaxResults[0]
            if levelField == 'yearAndMonth':
                raise StopIteration(iter([('yearAndMonth', iter([('2008-01',11),('2008-02',2),('2007-12',1)][:levelMax]))]))
            else:
                raise StopIteration(iter([('year', iter([('2008',13),('2003',10),('2007',10)][:levelMax]))]))
            yield
        drilldown.drilldown = doDrilldown
        multi.addObserver(drilldown)

        result = list(compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))

        self.assertEquals(2, len(doDrilldownArguments))
        self.assertEquals(('bitMatrixRow', [('yearAndMonth', 2, False)]), doDrilldownArguments[0])
        self.assertEquals(('bitMatrixRow', [('year', 2, False)]), doDrilldownArguments[1])
        self.assertEquals(1, len(result))
        (inField, realField), termCounts = result[0]
        self.assertEquals('year', realField)
        self.assertEquals([('2008',13),('2003',10)], list(termCounts))
    def testTwoFieldNamesCalled(self):
        multi = MultiLevelDrilldown(
            {'date':[('datelevel2',3, False),('datelevel1', 10, False)],
             'genre':[('type', 10, False)]
            }
        )
        drilldown = CallTrace('Drilldown')
        doDrilldownArguments = []
        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            doDrilldownArguments.append((bitMatrixRow, fieldNamesAndMaxResults))
            self.assertEquals(1, len(fieldNamesAndMaxResults))
            levelField, levelMax, levelSorted = fieldNamesAndMaxResults[0]
            if 'datelevel2' == levelField:
                raise StopIteration(iter([('datelevel2', iter([('2008',13),('2007',10)][:levelMax]))]))
            else:
                raise StopIteration(iter([('type', iter([('literature',43),('donaldduck',30)][:levelMax]))]))
            yield
        drilldown.drilldown = doDrilldown
        multi.addObserver(drilldown)

        result = list(compose(multi.multiLevelDrilldown('bitMatrixRow', ['date', 'genre'])))

        self.assertEquals(2, len(doDrilldownArguments))
        self.assertEquals(('bitMatrixRow', [('datelevel2', 3, False)]), doDrilldownArguments[0])
        self.assertEquals(('bitMatrixRow', [('type', 10, False)]), doDrilldownArguments[1])
        self.assertEquals(2, len(result))
        self.assertEquals([('date', 'datelevel2'),('genre', 'type')], [(inField, realField) for (inField, realField), termCounts in result])
    def testWithSorting(self):
        mockData = {
            'yearAndMonth': [('2008-01',1),('2008-02',2),('2007-12',11)],
            'year': [('2008',13),('2003',10),('2005',9), ('2007', 15)]
        }
        drilldown = CallTrace('Drilldown')
        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            levelField, levelMax, levelSorted = fieldNamesAndMaxResults[0]
            data = mockData[levelField]
            if levelSorted:
                data = sorted(data, cmp=lambda (term0, card0), (term1, card1): cmp(card1, card0))
            if levelMax > 0:
                data = data[:levelMax]
            raise StopIteration(iter([(levelField, iter(data))]))
            yield
        drilldown.drilldown = doDrilldown

        multi = MultiLevelDrilldown({'date':[('yearAndMonth', 2, False), ('year', 3, True)]})
        multi.addObserver(drilldown)
        result = list(compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))
        self.assertEquals([(('date', 'year'), [('2007', 15), ('2008', 13), ('2003', 10)])], result)

        multi = MultiLevelDrilldown({'date':[('yearAndMonth', 4, False), ('year', 3, False)]})
        multi.addObserver(drilldown)

        result = list(compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))
        self.assertEquals([(('date', 'yearAndMonth'), [('2008-01',1),('2008-02',2),('2007-12',11)])], result)
    def testTwoFieldNamesCalled(self):
        multi = MultiLevelDrilldown({
            'date': [('datelevel2', 3, False), ('datelevel1', 10, False)],
            'genre': [('type', 10, False)]
        })
        drilldown = CallTrace('Drilldown')
        doDrilldownArguments = []

        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            doDrilldownArguments.append(
                (bitMatrixRow, fieldNamesAndMaxResults))
            self.assertEquals(1, len(fieldNamesAndMaxResults))
            levelField, levelMax, levelSorted = fieldNamesAndMaxResults[0]
            if 'datelevel2' == levelField:
                raise StopIteration(
                    iter([('datelevel2',
                           iter([('2008', 13), ('2007', 10)][:levelMax]))]))
            else:
                raise StopIteration(
                    iter([('type',
                           iter([('literature', 43),
                                 ('donaldduck', 30)][:levelMax]))]))
            yield

        drilldown.drilldown = doDrilldown
        multi.addObserver(drilldown)

        result = list(
            compose(
                multi.multiLevelDrilldown('bitMatrixRow', ['date', 'genre'])))

        self.assertEquals(2, len(doDrilldownArguments))
        self.assertEquals(('bitMatrixRow', [('datelevel2', 3, False)]),
                          doDrilldownArguments[0])
        self.assertEquals(('bitMatrixRow', [('type', 10, False)]),
                          doDrilldownArguments[1])
        self.assertEquals(2, len(result))
        self.assertEquals([('date', 'datelevel2'), ('genre', 'type')],
                          [(inField, realField)
                           for (inField, realField), termCounts in result])
    def testWithSorting(self):
        mockData = {
            'yearAndMonth': [('2008-01', 1), ('2008-02', 2), ('2007-12', 11)],
            'year': [('2008', 13), ('2003', 10), ('2005', 9), ('2007', 15)]
        }
        drilldown = CallTrace('Drilldown')

        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            levelField, levelMax, levelSorted = fieldNamesAndMaxResults[0]
            data = mockData[levelField]
            if levelSorted:
                # py3: no unpacking in lambda's allowed anymore. Items are (term, cardinality)
                #      pairs sorted on descending on cardinality
                data = sorted(data, key=lambda each: each[1], reverse=True)
            if levelMax > 0:
                data = data[:levelMax]
            return iter([(levelField, iter(data))])
            yield

        drilldown.drilldown = doDrilldown

        multi = MultiLevelDrilldown(
            {'date': [('yearAndMonth', 2, False), ('year', 3, True)]})
        multi.addObserver(drilldown)
        result = list(
            compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))
        self.assertEqual([(('date', 'year'), [('2007', 15), ('2008', 13),
                                              ('2003', 10)])], result)

        multi = MultiLevelDrilldown(
            {'date': [('yearAndMonth', 4, False), ('year', 3, False)]})
        multi.addObserver(drilldown)

        result = list(
            compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))
        self.assertEqual([(('date', 'yearAndMonth'), [('2008-01', 1),
                                                      ('2008-02', 2),
                                                      ('2007-12', 11)])],
                         result)
    def testWithSorting(self):
        mockData = {
            'yearAndMonth': [('2008-01', 1), ('2008-02', 2), ('2007-12', 11)],
            'year': [('2008', 13), ('2003', 10), ('2005', 9), ('2007', 15)]
        }
        drilldown = CallTrace('Drilldown')

        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            levelField, levelMax, levelSorted = fieldNamesAndMaxResults[0]
            data = mockData[levelField]
            if levelSorted:
                data = sorted(data,
                              cmp=lambda (term0, card0),
                              (term1, card1): cmp(card1, card0))
            if levelMax > 0:
                data = data[:levelMax]
            raise StopIteration(iter([(levelField, iter(data))]))
            yield

        drilldown.drilldown = doDrilldown

        multi = MultiLevelDrilldown(
            {'date': [('yearAndMonth', 2, False), ('year', 3, True)]})
        multi.addObserver(drilldown)
        result = list(
            compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))
        self.assertEquals([(('date', 'year'), [('2007', 15), ('2008', 13),
                                               ('2003', 10)])], result)

        multi = MultiLevelDrilldown(
            {'date': [('yearAndMonth', 4, False), ('year', 3, False)]})
        multi.addObserver(drilldown)

        result = list(
            compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))
        self.assertEquals([(('date', 'yearAndMonth'), [('2008-01', 1),
                                                       ('2008-02', 2),
                                                       ('2007-12', 11)])],
                          result)
    def testFieldWithMultiLevel(self):
        multi = MultiLevelDrilldown(
            {'date': [('yearAndMonth', 2, False), ('year', 2, False)]})
        drilldown = CallTrace('Drilldown')
        doDrilldownArguments = []

        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            doDrilldownArguments.append(
                (bitMatrixRow, fieldNamesAndMaxResults))
            self.assertEquals(1, len(fieldNamesAndMaxResults))
            levelField, levelMax, levelSorted = fieldNamesAndMaxResults[0]
            if levelField == 'yearAndMonth':
                raise StopIteration(
                    iter([('yearAndMonth',
                           iter([('2008-01', 11), ('2008-02', 2),
                                 ('2007-12', 1)][:levelMax]))]))
            else:
                raise StopIteration(
                    iter([('year',
                           iter([('2008', 13), ('2003', 10),
                                 ('2007', 10)][:levelMax]))]))
            yield

        drilldown.drilldown = doDrilldown
        multi.addObserver(drilldown)

        result = list(
            compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))

        self.assertEquals(2, len(doDrilldownArguments))
        self.assertEquals(('bitMatrixRow', [('yearAndMonth', 2, False)]),
                          doDrilldownArguments[0])
        self.assertEquals(('bitMatrixRow', [('year', 2, False)]),
                          doDrilldownArguments[1])
        self.assertEquals(1, len(result))
        (inField, realField), termCounts = result[0]
        self.assertEquals('year', realField)
        self.assertEquals([('2008', 13), ('2003', 10)], list(termCounts))
    def testLastZeroReturnValue(self):
        multi = MultiLevelDrilldown(
            {'date':[('yearAndMonth', 2, False), ('year', 2, False)]
            }
        )
        drilldown = CallTrace('Drilldown')
        doDrilldownArguments = []
        def doDrilldown(bitMatrixRow, fieldNamesAndMaxResults):
            doDrilldownArguments.append((bitMatrixRow, fieldNamesAndMaxResults))
            self.assertEquals(1, len(fieldNamesAndMaxResults))
            levelField, levelMax, sorted = fieldNamesAndMaxResults[0]
            if levelField == 'yearAndMonth':
                raise StopIteration(iter([('yearAndMonth', iter([]))]))
            else:
                raise StopIteration(iter([('year', iter([]))]))
            yield
        drilldown.drilldown = doDrilldown
        multi.addObserver(drilldown)

        result = list(compose(multi.multiLevelDrilldown('bitMatrixRow', ['date'])))

        self.assertEquals(1, len(result))
        (inField, realField), termCounts = result[0]
        self.assertEquals(None, realField)