1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
import warnings
from django.test import TestCase
from django_tables2 import Table
from django_tables2.data import TableData, TableListData, TableQuerysetData
from .app.models import Person, Region
from .utils import build_request
class TableDataFactoryTest(TestCase):
def test_invalid_data(self):
message = "data must be QuerySet-like (have count() and order_by()) or support list(data)"
class Klass:
pass
class Bad:
def __len__(self):
pass
invalid = [None, 1, Klass(), Bad()]
for data in invalid:
with self.subTest(data=data), self.assertRaisesMessage(ValueError, message):
TableData.from_data(data)
def test_valid_QuerySet(self):
data = TableData.from_data(Person.objects.all())
self.assertIsInstance(data, TableQuerysetData)
def test_valid_list_of_dicts(self):
data = TableData.from_data([{"name": "John"}, {"name": "Pete"}])
self.assertIsInstance(data, TableListData)
self.assertEqual(len(data), 2)
def test_valid_tuple_of_dicts(self):
data = TableData.from_data(({"name": "John"}, {"name": "Pete"}))
self.assertIsInstance(data, TableListData)
self.assertEqual(len(data), 2)
def test_valid_class(self):
class Datasource:
def __len__(self):
return 1
def __getitem__(self, pos):
if pos != 0:
raise IndexError()
return {"a": 1}
data = TableData.from_data(Datasource())
self.assertEqual(len(data), 1)
class TableDataTest(TestCase):
def test_knows_its_default_name(self):
data = TableData.from_data([{}])
self.assertEqual(data.verbose_name, "item")
self.assertEqual(data.verbose_name_plural, "items")
def test_knows_its_name(self):
data = TableData.from_data(Person.objects.all())
self.assertEqual(data.verbose_name, "person")
self.assertEqual(data.verbose_name_plural, "people")
def generator(max_value):
for i in range(max_value):
yield {"foo": i, "bar": chr(i), "baz": hex(i), "inv": max_value - i}
class TableListsDataTest(TestCase):
def test_TableListData_basic_list(self):
list_data = list(generator(100))
data = TableListData(list_data)
self.assertEqual(len(list_data), len(data))
self.assertEqual(data.verbose_name, "item")
self.assertEqual(data.verbose_name_plural, "items")
def test_TableListData_with_verbose_name(self):
"""
TableListData uses the attributes on the listlike object to generate
it's verbose_name.
"""
class listlike(list):
verbose_name = "unit"
verbose_name_plural = "units"
list_data = listlike(generator(100))
data = TableListData(list_data)
self.assertEqual(len(list_data), len(data))
self.assertEqual(data.verbose_name, "unit")
self.assertEqual(data.verbose_name_plural, "units")
class TableQuerysetDataTest(TestCase):
def test_custom_TableData(self):
"""If TableQuerysetData._length is set, no count() query will be performed"""
for i in range(11):
Person.objects.create(first_name=f"first {i}")
data = TableQuerysetData(Person.objects.all())
data._length = 10
table = Table(data=data)
self.assertEqual(len(table.data), 10)
def test_model_mismatch(self):
class MyTable(Table):
class Meta:
model = Person
with warnings.catch_warnings(record=True):
MyTable(Region.objects.all())
def test_queryset_union(self):
for i in range(10):
Person.objects.create(first_name=f"first {i}", last_name="foo")
Person.objects.create(first_name=f"first {i * 2}", last_name="bar")
class MyTable(Table):
class Meta:
model = Person
fields = ("first_name",)
qs = Person.objects.filter(last_name="bar").union(Person.objects.filter(last_name="foo"))
table = MyTable(qs.order_by("-last_name"))
self.assertEqual(len(table.rows), 20)
html = table.as_html(build_request())
self.assertIn("first 18", html)
self.assertIn("first 10", html)
|