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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
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, PersonProxy, 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 list-like 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_no_warning_model_identical(self):
class MyTable(Table):
class Meta:
model = Person
with warnings.catch_warnings(record=True) as w:
MyTable(Person.objects.all())
self.assertEqual(len(w), 0)
def test_warning_model_mismatch(self):
class MyTable(Table):
class Meta:
model = Person
with warnings.catch_warnings(record=True) as w:
MyTable(Region.objects.all())
self.assertEqual(len(w), 1)
def test_no_warning_model_subclass(self):
class MyTable(Table):
class Meta:
model = Person
with warnings.catch_warnings(record=True) as w:
MyTable(PersonProxy.objects.all())
self.assertEqual(len(w), 0)
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)
|