debian-django-tables2/tests/columns/test_general.py

330 lines
10 KiB
Python

# coding: utf-8
# pylint: disable=R0912,E0102
from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy
from django.utils.safestring import mark_safe, SafeData
import pytest
import django_tables2 as tables
from ..app.models import Person
from ..utils import parse, warns
def test_column_render_supports_kwargs():
class TestColumn(tables.Column):
def render(self, **kwargs):
expected = {"record", "value", "column", "bound_column", "bound_row", "table"}
actual = set(kwargs.keys())
assert actual == expected
return "success"
class TestTable(tables.Table):
foo = TestColumn()
table = TestTable([{"foo": "bar"}])
assert table.rows[0]["foo"] == "success"
def test_column_header_should_use_titlised_verbose_name_unless_given_explicitly():
class SimpleTable(tables.Table):
basic = tables.Column()
acronym = tables.Column(verbose_name="has FBI help")
table = SimpleTable([])
assert table.columns["basic"].header == "Basic"
assert table.columns["acronym"].header == "has FBI help"
def test_should_support_safe_verbose_name():
class SimpleTable(tables.Table):
safe = tables.Column(verbose_name=mark_safe("<b>Safe</b>"))
table = SimpleTable([])
assert isinstance(table.columns["safe"].header, SafeData)
def test_should_support_safe_verbose_name_via_model():
class PersonTable(tables.Table):
safe = tables.Column()
table = PersonTable(Person.objects.all())
assert isinstance(table.columns["safe"].header, SafeData)
@pytest.mark.django_db
def test_handle_verbose_name_of_many2onerel():
class Table(tables.Table):
count = tables.Column(accessor='info_list.count')
Person.objects.create(first_name='bradley', last_name='ayers')
table = Table(Person.objects.all())
assert table.columns['count'].verbose_name == 'Information'
def test_sortable_backwards_compatibility():
# Table.Meta.sortable (not set)
class SimpleTable(tables.Table):
name = tables.Column()
table = SimpleTable([])
with warns(DeprecationWarning):
assert table.columns['name'].sortable is True
# Table.Meta.sortable = False
with warns(DeprecationWarning):
class SimpleTable(tables.Table):
name = tables.Column()
class Meta:
sortable = False
table = SimpleTable([])
with warns(DeprecationWarning):
assert table.columns['name'].sortable is False # backwards compatible
assert table.columns['name'].orderable is False
# Table.Meta.sortable = True
with warns(DeprecationWarning):
class SimpleTable(tables.Table):
name = tables.Column()
class Meta:
sortable = True
table = SimpleTable([])
with warns(DeprecationWarning):
assert table.columns['name'].sortable is True # backwards compatible
assert table.columns['name'].orderable is True
def test_orderable():
# Table.Meta.orderable = False
class SimpleTable(tables.Table):
name = tables.Column()
table = SimpleTable([])
assert table.columns['name'].orderable is True
# Table.Meta.orderable = False
class SimpleTable(tables.Table):
name = tables.Column()
class Meta:
orderable = False
table = SimpleTable([])
assert table.columns['name'].orderable is False
with warns(DeprecationWarning):
assert table.columns['name'].sortable is False # backwards compatible
# Table.Meta.orderable = True
class SimpleTable(tables.Table):
name = tables.Column()
class Meta:
orderable = True
table = SimpleTable([])
with warns(DeprecationWarning):
assert table.columns['name'].sortable is True # backwards compatible
assert table.columns['name'].orderable is True
def test_order_by_defaults_to_accessor():
class SimpleTable(tables.Table):
foo = tables.Column(accessor="bar")
table = SimpleTable([])
assert table.columns["foo"].order_by == ("bar", )
def test_supports_order_by():
class SimpleTable(tables.Table):
name = tables.Column(order_by=("last_name", "-first_name"))
age = tables.Column()
table = SimpleTable([], order_by=("-age", ))
# alias
assert table.columns["name"].order_by_alias == "name"
assert table.columns["age"].order_by_alias == "-age"
# order by
assert table.columns["name"].order_by == ("last_name", "-first_name")
assert table.columns["age"].order_by == ("-age", )
# now try with name ordered
table = SimpleTable([], order_by=("-name", ))
# alias
assert table.columns["name"].order_by_alias == "-name"
assert table.columns["age"].order_by_alias == "age"
# alias next
assert table.columns["name"].order_by_alias.next == "name"
assert table.columns["age"].order_by_alias.next == "age"
# order by
assert table.columns["name"].order_by == ("-last_name", "first_name")
assert table.columns["age"].order_by == ("age", )
def test_supports_is_ordered():
class SimpleTable(tables.Table):
name = tables.Column()
# sorted
table = SimpleTable([], order_by='name')
assert table.columns["name"].is_ordered
# unsorted
table = SimpleTable([])
assert not table.columns["name"].is_ordered
def test_translation():
"""
Tests different types of values for the ``verbose_name`` property of a
column.
"""
class TranslationTable(tables.Table):
text = tables.Column(verbose_name=ugettext_lazy("Text"))
table = TranslationTable([])
assert "Text" == table.columns["text"].header
def test_sequence():
"""
Ensures that the sequence of columns is configurable.
"""
class TestTable(tables.Table):
a = tables.Column()
b = tables.Column()
c = tables.Column()
assert ["a", "b", "c"] == TestTable([]).columns.names()
assert ["b", "a", "c"] == TestTable([], sequence=("b", "a", "c")).columns.names()
class TestTable2(TestTable):
class Meta:
sequence = ("b", "a", "c")
assert ["b", "a", "c"] == TestTable2([]).columns.names()
assert ["a", "b", "c"] == TestTable2([], sequence=("a", "b", "c")).columns.names()
class TestTable3(TestTable):
class Meta:
sequence = ("c", )
assert ["c", "a", "b"] == TestTable3([]).columns.names()
assert ["c", "a", "b"] == TestTable([], sequence=("c", )).columns.names()
class TestTable4(TestTable):
class Meta:
sequence = ("...", )
assert ["a", "b", "c"] == TestTable4([]).columns.names()
assert ["a", "b", "c"] == TestTable([], sequence=("...", )).columns.names()
class TestTable5(TestTable):
class Meta:
sequence = ("b", "...")
assert ["b", "a", "c"] == TestTable5([]).columns.names()
assert ["b", "a", "c"] == TestTable([], sequence=("b", "...")).columns.names()
class TestTable6(TestTable):
class Meta:
sequence = ("...", "b")
assert ["a", "c", "b"] == TestTable6([]).columns.names()
assert ["a", "c", "b"] == TestTable([], sequence=("...", "b")).columns.names()
class TestTable7(TestTable):
class Meta:
sequence = ("b", "...", "a")
assert ["b", "c", "a"] == TestTable7([]).columns.names()
assert ["b", "c", "a"] == TestTable([], sequence=("b", "...", "a")).columns.names()
# Let's test inheritence
class TestTable8(TestTable):
d = tables.Column()
e = tables.Column()
f = tables.Column()
class Meta:
sequence = ("d", "...")
class TestTable9(TestTable):
d = tables.Column()
e = tables.Column()
f = tables.Column()
assert ["d", "a", "b", "c", "e", "f"] == TestTable8([]).columns.names()
assert ["d", "a", "b", "c", "e", "f"] == TestTable9([], sequence=("d", "...")).columns.names()
def test_should_support_both_meta_sequence_and_constructor_exclude():
"""
Issue #32 describes a problem when both ``Meta.sequence`` and
``Table(..., exclude=...)`` are used on a single table. The bug caused an
exception to be raised when the table was iterated.
"""
class SequencedTable(tables.Table):
a = tables.Column()
b = tables.Column()
c = tables.Column()
class Meta:
sequence = ('a', '...')
table = SequencedTable([], exclude=('c', ))
table.as_html()
def test_bound_columns_should_support_indexing():
class SimpleTable(tables.Table):
a = tables.Column()
b = tables.Column()
table = SimpleTable([])
assert 'b' == table.columns[1].name
assert 'b' == table.columns['b'].name
def test_cell_attrs_applies_to_td_and_th():
class SimpleTable(tables.Table):
a = tables.Column(attrs={"cell": {"key": "value"}})
# providing data ensures 1 row is rendered
table = SimpleTable([{"a": "value"}])
root = parse(table.as_html())
assert root.findall('.//thead/tr/th')[0].attrib == {"key": "value", "class": "a orderable sortable"}
assert root.findall('.//tbody/tr/td')[0].attrib == {"key": "value", "class": "a"}
def test_cells_are_automatically_given_column_name_as_class():
class SimpleTable(tables.Table):
a = tables.Column()
table = SimpleTable([{"a": "value"}])
root = parse(table.as_html())
assert root.findall('.//thead/tr/th')[0].attrib == {"class": "a orderable sortable"}
assert root.findall('.//tbody/tr/td')[0].attrib == {"class": "a"}
def test_th_are_given_sortable_class_if_column_is_orderable():
class SimpleTable(tables.Table):
a = tables.Column()
b = tables.Column(orderable=False)
table = SimpleTable([{"a": "value"}])
root = parse(table.as_html())
# return classes of an element as a set
classes = lambda x: set(x.attrib["class"].split())
assert "sortable" in classes(root.findall('.//thead/tr/th')[0])
assert "sortable" not in classes(root.findall('.//thead/tr/th')[1])
# Now try with an ordered table
table = SimpleTable([], order_by="a")
root = parse(table.as_html())
# return classes of an element as a set
assert "sortable" in classes(root.findall('.//thead/tr/th')[0])
assert "asc" in classes(root.findall('.//thead/tr/th')[0])
assert "sortable" not in classes(root.findall('.//thead/tr/th')[1])
def test_empty_values_triggers_default():
class Table(tables.Table):
a = tables.Column(empty_values=(1, 2), default="--")
table = Table([{"a": 1}, {"a": 2}, {"a": 3}, {"a": 4}])
assert [x["a"] for x in table.rows] == ["--", "--", 3, 4]