Fix off by 1 error in batch_messages & add unit tests
Fix an off by one error in the batch_messages function. And add some unit tests for the batch_messages function. Also handle if batch_size is less than or equal to zero. In that case just return the input messages. Change-Id: Id7be110379c212104fba70588b647dfd3a13e765 Closes-Bug: #1570446
This commit is contained in:
parent
b14b2fb3cf
commit
cd1f4760df
@ -20,16 +20,57 @@ import os.path
|
||||
|
||||
|
||||
def batch_meetings(meetings, batch_size):
|
||||
col_length = len(meetings) // batch_size
|
||||
"""Batches the meetings to be consumed by the jinja2 'batch' filter.
|
||||
|
||||
This will pivot the meeting list into a virtual number of columns. This
|
||||
can be used in a jinja template like:
|
||||
|
||||
{% for column in batch_meetings(meetings, 4)|batch(4) %}
|
||||
|
||||
So the list:
|
||||
[A, B, C, D, E, F , G, H, I]
|
||||
|
||||
Is returned as:
|
||||
[A, D, F, H, B, E, G, I, C]]
|
||||
|
||||
Or another way of looking at it is:
|
||||
[A, D, F, H,
|
||||
B, E, G, I,
|
||||
C]]
|
||||
|
||||
And displays as:
|
||||
A D F H
|
||||
B E G I
|
||||
C
|
||||
|
||||
Rather than:
|
||||
A B C D
|
||||
E F G H
|
||||
I
|
||||
|
||||
:param meetings: An iterable
|
||||
:param batch_size: Number of columns to split up the output into
|
||||
:returns: A list that has 'pivoted' the meetings input
|
||||
|
||||
"""
|
||||
if batch_size <= 0:
|
||||
return meetings
|
||||
col_length = (len(meetings) // batch_size) + 1
|
||||
new_meetings = [None] * len(meetings)
|
||||
src = 0
|
||||
|
||||
for row in range(batch_size):
|
||||
for col in range(col_length):
|
||||
dest = col * batch_size + row
|
||||
if dest >= len(meetings):
|
||||
break
|
||||
new_meetings[dest] = meetings[src]
|
||||
src += 1
|
||||
|
||||
# Sanity check
|
||||
if all(meetings):
|
||||
assert all(new_meetings), "Empty item found in: {}".format(
|
||||
new_meetings)
|
||||
return new_meetings
|
||||
|
||||
|
||||
|
151
yaml2ical/tests/test_index.py
Normal file
151
yaml2ical/tests/test_index.py
Normal file
@ -0,0 +1,151 @@
|
||||
# Copyright 2016 Intel Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import unittest
|
||||
|
||||
from yaml2ical import index
|
||||
|
||||
|
||||
class IndexTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
# Make 23 entries as 23 is a prime number
|
||||
self.meetings = [x for x in range(1, 24)]
|
||||
|
||||
def test_batch_meetings_3_cols(self):
|
||||
# NOTE(jlvillal): Please format the expected values to easily see the
|
||||
# columns and rows
|
||||
tests = (
|
||||
# 1 row
|
||||
(1, [1]),
|
||||
(2, [1, 2]),
|
||||
(3, [1, 2, 3]),
|
||||
# 2 rows
|
||||
(4, [1, 3, 4,
|
||||
2]),
|
||||
(5, [1, 3, 5,
|
||||
2, 4]),
|
||||
# 3 rows
|
||||
(7, [1, 4, 6,
|
||||
2, 5, 7,
|
||||
3]),
|
||||
(9, [1, 4, 7,
|
||||
2, 5, 8,
|
||||
3, 6, 9]),
|
||||
# 4 rows
|
||||
(11, [1, 5, 9,
|
||||
2, 6, 10,
|
||||
3, 7, 11,
|
||||
4, 8]),
|
||||
# 8 rows
|
||||
(23, [1, 9, 17,
|
||||
2, 10, 18,
|
||||
3, 11, 19,
|
||||
4, 12, 20,
|
||||
5, 13, 21,
|
||||
6, 14, 22,
|
||||
7, 15, 23,
|
||||
8, 16]),
|
||||
)
|
||||
|
||||
for test_length, expected in tests:
|
||||
self.assertEqual(
|
||||
expected, index.batch_meetings(self.meetings[:test_length], 3))
|
||||
|
||||
def test_batch_meetings_4_cols(self):
|
||||
# NOTE(jlvillal): Please format the expected values to easily see the
|
||||
# columns and rows
|
||||
tests = (
|
||||
# Empty
|
||||
(0, []),
|
||||
# 1 row
|
||||
(1, [1]),
|
||||
(2, [1, 2]),
|
||||
(3, [1, 2, 3]),
|
||||
(4, [1, 2, 3, 4]),
|
||||
# 2 rows
|
||||
(5, [1, 3, 4, 5,
|
||||
2]),
|
||||
(7, [1, 3, 5, 7,
|
||||
2, 4, 6]),
|
||||
(8, [1, 3, 5, 7,
|
||||
2, 4, 6, 8]),
|
||||
# 3 rows
|
||||
(9, [1, 4, 6, 8,
|
||||
2, 5, 7, 9,
|
||||
3]),
|
||||
(11, [1, 4, 7, 10,
|
||||
2, 5, 8, 11,
|
||||
3, 6, 9]),
|
||||
# 5 rows
|
||||
(23, [1, 7, 13, 19,
|
||||
2, 8, 14, 20,
|
||||
3, 9, 15, 21,
|
||||
4, 10, 16, 22,
|
||||
5, 11, 17, 23,
|
||||
6, 12, 18]),
|
||||
)
|
||||
|
||||
for test_length, expected in tests:
|
||||
self.assertEqual(
|
||||
expected, index.batch_meetings(self.meetings[:test_length], 4))
|
||||
|
||||
# Make sure our docstring example is correct
|
||||
self.assertEqual(
|
||||
['A', 'D', 'F', 'H',
|
||||
'B', 'E', 'G', 'I',
|
||||
'C'],
|
||||
index.batch_meetings(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
|
||||
4))
|
||||
|
||||
def test_batch_meetings_misc_cols(self):
|
||||
# Test various column values and inputs
|
||||
|
||||
# NOTE(jlvillal): Please format the expected values to easily see the
|
||||
# columns and rows
|
||||
tests = (
|
||||
# Formatted as:
|
||||
# Number of items, columns, expected_result
|
||||
|
||||
# Empty
|
||||
(0, 1, []),
|
||||
# 2 rows
|
||||
(8, 5, [1, 3, 5, 7, 8,
|
||||
2, 4, 6]),
|
||||
(10, 6, [1, 3, 5, 7, 9, 10,
|
||||
2, 4, 6, 8, ]),
|
||||
(7, 6, [1, 3, 4, 5, 6, 7,
|
||||
2]),
|
||||
)
|
||||
|
||||
for test_length, columns, expected in tests:
|
||||
self.assertEqual(
|
||||
expected,
|
||||
index.batch_meetings(self.meetings[:test_length], columns))
|
||||
|
||||
def test_batch_meetings_zero_or_less(self):
|
||||
# Make sure we return the passed in value if columns less than or equal
|
||||
# to zero
|
||||
self.assertEqual([1, 2], index.batch_meetings([1, 2], 0))
|
||||
self.assertEqual([1, 2], index.batch_meetings([1, 2], -1))
|
||||
self.assertEqual([1, 2], index.batch_meetings([1, 2], -5551.5))
|
||||
|
||||
def test_batch_meetings_sanity_check_not_triggered(self):
|
||||
# Make sure that an input containing None, False, 0, or "" doesn't
|
||||
# trigger the assert
|
||||
self.assertEqual([None, None], index.batch_meetings([None, None], 1))
|
||||
self.assertEqual(
|
||||
[False, False], index.batch_meetings([False, False], 1))
|
||||
self.assertEqual([0, 0], index.batch_meetings([0, 0], 4))
|
||||
self.assertEqual(["", ""], index.batch_meetings(["", ""], 1))
|
Loading…
Reference in New Issue
Block a user