330 lines
10 KiB
Python
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]
|