コード例 #1
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_setattr_path():
    assert getattr_path(setattr_path(Struct(a=0), 'a', 1), 'a') == 1
    assert getattr_path(setattr_path(Struct(a=Struct(b=0)), 'a__b', 2),
                        'a__b') == 2

    with pytest.raises(AttributeError):
        setattr_path(Struct(a=1), 'a__b', 1)
コード例 #2
0
def test_order_after_name_last():
    sorts_right([
        Struct(name='foo', expected_position=0),
        Struct(name='quux', after='qoox', expected_position=3),
        Struct(name='qoox', after=LAST, expected_position=2),
        Struct(name='bar', expected_position=1),
    ])
コード例 #3
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_getattr_path():
    assert getattr_path(Struct(a=1), 'a') == 1
    assert getattr_path(Struct(a=Struct(b=2)), 'a__b') == 2
    with pytest.raises(AttributeError):
        getattr_path(Struct(a=2), 'b')

    assert getattr_path(Struct(a=None), 'a__b__c__d') is None
コード例 #4
0
def test_order_after_0():
    sorts_right([
        Struct(name='foo', expected_position=1),
        Struct(name='bar', expected_position=2),
        Struct(name='quux', after=0, expected_position=0),
        Struct(name='baz', expected_position=3),
    ])
コード例 #5
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_parse():
    # The spaces in the data are there to check that we strip input
    form = MyTestForm(request=Struct(method='POST',
                                     POST=Data(party='ABC ',
                                               username='******',
                                               joined=' 2014-12-12 01:02:03  ',
                                               staff=' true',
                                               admin='false ',
                                               manages=['DEF  ', 'KTH '],
                                               a_date='  2014-02-12  ',
                                               a_time='  01:02:03  ',
                                               **{'-': '-'})))

    assert [x.errors for x in form.fields] == [set() for _ in form.fields]
    assert form.is_valid()
    assert form.fields_by_name['party'].parsed_data == 'ABC'
    assert form.fields_by_name['party'].value == 'ABC'

    assert form.fields_by_name['username'].parsed_data == 'abc_foo'
    assert form.fields_by_name['username'].value == 'abc_foo'

    assert form.fields_by_name['joined'].raw_data == '2014-12-12 01:02:03'
    assert form.fields_by_name['joined'].parsed_data == datetime(
        2014, 12, 12, 1, 2, 3)
    assert form.fields_by_name['joined'].value == datetime(
        2014, 12, 12, 1, 2, 3)

    assert form.fields_by_name['staff'].raw_data == 'true'
    assert form.fields_by_name['staff'].parsed_data is True
    assert form.fields_by_name['staff'].value is True

    assert form.fields_by_name['admin'].raw_data == 'false'
    assert form.fields_by_name['admin'].parsed_data is False
    assert form.fields_by_name['admin'].value is False

    assert form.fields_by_name['manages'].raw_data_list == ['DEF', 'KTH']
    assert form.fields_by_name['manages'].parsed_data_list == ['DEF', 'KTH']
    assert form.fields_by_name['manages'].value_list == ['DEF', 'KTH']

    assert form.fields_by_name['a_date'].raw_data == '2014-02-12'
    assert form.fields_by_name['a_date'].parsed_data == date(2014, 2, 12)
    assert form.fields_by_name['a_date'].value == date(2014, 2, 12)

    assert form.fields_by_name['a_time'].raw_data == '01:02:03'
    assert form.fields_by_name['a_time'].parsed_data == time(1, 2, 3)
    assert form.fields_by_name['a_time'].value == time(1, 2, 3)

    instance = Struct(contact=Struct())
    form.apply(instance)
    assert instance == Struct(
        contact=Struct(joined=datetime(2014, 12, 12, 1, 2, 3)),
        party='ABC',
        staff=True,
        admin=False,
        username='******',
        manages=['DEF', 'KTH'],
        a_date=date(2014, 2, 12),
        a_time=time(1, 2, 3),
        not_editable='Some non-editable text')
コード例 #6
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_bound_field_render_css_classes():
    assert BoundField(
        field=Struct(
            container_css_classes={'a', 'b'},
            required=True,
        ),
        form=Struct(style='compact')).render_container_css_classes(
        ) == ' class="a b key-value required"'
コード例 #7
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_choice_not_required():
    class MyForm(Form):
        foo = Field.choice(required=False, choices=['bar'])

    assert MyForm(
        request=Struct(method='POST', POST=Data(
            foo='bar', **{'-': '-'}))).fields[0].value == 'bar'
    assert MyForm(
        request=Struct(method='POST', POST=Data(
            foo='', **{'-': '-'}))).fields[0].value is None
コード例 #8
0
def test_sort_after_points_to_nothing_plural():
    with pytest.raises(KeyError) as e:
        sort_after([
            Struct(name='quux'),
            Struct(name='foo', after='does-not-exist2'),
            Struct(name='quux6', after='does-not-exist'),
        ])

    assert "'Tried to order after does-not-exist, does-not-exist2 but those keys do not exist'" == str(
        e.value).replace("u'", "'")
コード例 #9
0
ファイル: __init__.py プロジェクト: erik-sjoestedt/tri.table
class ColumnBase(NamedStruct):
    """
    Class that describes a column, i.e. the text of the header, how to get and display the data in the cell, etc.
    """

    name = NamedStructField()
    """ :type: unicode """
    after = NamedStructField()
    attrs = NamedStructField()
    attr = NamedStructField(default=lambda table, column: column.name)
    css_class = NamedStructField(default=set())
    url = NamedStructField()
    title = NamedStructField()
    show = NamedStructField(default=True)
    sort_key = NamedStructField(lambda column: column.attr)
    sort_default_desc = NamedStructField(default=False)
    display_name = NamedStructField(default=lambda table, column: force_text(
        column.name).rsplit('__', 1)[-1].replace("_", " ").capitalize())
    sortable = NamedStructField(default=True)
    group = NamedStructField()
    auto_rowspan = NamedStructField(default=False)
    cell = NamedStructField()
    model = NamedStructField()
    choices = NamedStructField()
    bulk = NamedStructField()
    query = NamedStructField()

    extra = NamedStructField(default=Struct())
コード例 #10
0
ファイル: __init__.py プロジェクト: erik-sjoestedt/tri.table
 def bind_columns():
     for index, column in enumerate(self.columns):
         values = evaluate_recursive(Struct(column),
                                     table=self,
                                     column=column)
         values = merged(values, column=column, table=self, index=index)
         yield BoundColumn(**values)
コード例 #11
0
ファイル: __init__.py プロジェクト: dhaggen/tri.form
    def choice_queryset(**kwargs):

        def choice_queryset_is_valid(form, field, parsed_data):
            del form
            return field.choices.filter(pk=parsed_data.pk).exists(), '%s not in available choices' % (field.raw_data or ', '.join(field.raw_data_list))

        def choice_queryset_endpoint_dispatch(field, value, **_):
            limit = 10
            result = field.choices.filter(**{field.extra.endpoint_attr + '__icontains': value}).values_list(*['pk', field.extra.endpoint_attr])
            return [
                dict(
                    id=row[0],
                    text=row[1],
                )
                for row in result[:limit]
            ]

        kwargs = setdefaults_path(
            Struct(),
            kwargs,
            parse=lambda form, field, string_value: field.model.objects.get(pk=string_value) if string_value else None,
            choice_to_option=lambda form, field, choice: (choice, choice.pk, "%s" % choice, choice == field.value),
            endpoint_path=lambda form, field: '__' + form.endpoint_dispatch_prefix + '__field__' + field.name,
            endpoint_dispatch=choice_queryset_endpoint_dispatch,
            extra__endpoint_attr='name',
            is_valid=choice_queryset_is_valid,
        )
        return Field.choice(**kwargs)
コード例 #12
0
ファイル: __init__.py プロジェクト: erik-sjoestedt/tri.table
 def __init__(self, **kwargs):
     new_kwargs = setdefaults_path(
         Struct(),
         kwargs,
         bulk__attr=kwargs.get('attr'),
         query__attr=kwargs.get('attr'),
     )
     super(BoundColumn, self).__init__(**new_kwargs)
コード例 #13
0
ファイル: __init__.py プロジェクト: erik-sjoestedt/tri.table
    class Meta:
        bulk_filter = {}
        bulk_exclude = {}
        sortable = True
        attrs = Struct()
        attrs__class__listview = True
        row__attrs = Struct()
        row__template = None
        filter__template = 'tri_query/form.html'
        header__template = 'tri_table/table_header_rows.html'
        links__template = 'tri_table/links.html'

        endpoint__query__ = lambda table, key, value: table.query.endpoint_dispatch(
            key=key, value=value) if table.query is not None else None
        endpoint__bulk__ = lambda table, key, value: table.bulk.endpoint_dispatch(
            key=key, value=value) if table.bulk is not None else None

        model = None
コード例 #14
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_mode_initials_from_get():
    class FooForm(Form):
        foo = Field(required=True)
        bar = Field(required=True)
        baz = Field.boolean(initial=True)

    # empty GET
    form = FooForm(request=Struct(method='GET', GET={}))
    assert form.is_valid()

    # initials from GET
    form = FooForm(request=Struct(method='GET', GET={'foo': 'foo_initial'}))
    assert form.is_valid()
    assert form.fields_by_name['foo'].value == 'foo_initial'

    assert form.fields_by_name['foo'].errors == set()
    assert form.fields_by_name['bar'].errors == set()
    assert form.fields_by_name['baz'].errors == set()
コード例 #15
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_mode_full_form_from_request():
    class FooForm(Form):
        foo = Field(required=True)
        bar = Field(required=True)
        baz = Field.boolean(initial=True)

    # empty POST
    form = FooForm(request=Struct(method='POST', POST={'-': '-'}))
    assert not form.is_valid()
    assert form.errors == set()
    assert form.fields_by_name['foo'].errors == {'This field is required'}
    assert form.fields_by_name['bar'].errors == {'This field is required'}
    assert form.fields_by_name['baz'].errors == set(
    )  # not present in POST request means false

    form = FooForm(request=Struct(method='POST',
                                  POST={
                                      '-': '-',
                                      'foo': 'x',
                                      'bar': 'y',
                                      'baz': 'false'
                                  }))
    assert form.is_valid()
    assert form.fields_by_name['baz'].value is False

    # all params in GET
    form = FooForm(request=Struct(method='GET', GET={'-': '-'}))
    assert not form.is_valid()
    assert form.fields_by_name['foo'].errors == {'This field is required'}
    assert form.fields_by_name['bar'].errors == {'This field is required'}
    assert form.fields_by_name['baz'].errors == set(
    )  # not present in POST request means false

    form = FooForm(request=Struct(method='GET',
                                  GET={
                                      '-': '-',
                                      'foo': 'x',
                                      'bar': 'y',
                                      'baz': 'on'
                                  }))
    assert not form.errors
    assert not form.fields[0].errors

    assert form.is_valid()
コード例 #16
0
def test_setdefaults_path_ordering():
    expected = Struct(x=Struct(y=17, z=42))

    actual_foo = setdefaults_path(
        Struct(), OrderedDict([
            ('x', {
                'z': 42
            }),
            ('x__y', 17),
        ]))
    assert actual_foo == expected

    actual_bar = setdefaults_path(
        Struct(), OrderedDict([
            ('x__y', 17),
            ('x', {
                'z': 42
            }),
        ]))
    assert actual_bar == expected
コード例 #17
0
ファイル: __init__.py プロジェクト: erik-sjoestedt/tri.table
    def _prepare_headers(self):
        headers = prepare_headers(self.request, self.shown_bound_columns)

        # The id(header) and the type(x.display_name) stuff is to make None not be equal to None in the grouping
        header_groups = []

        class HeaderGroup(Struct):
            def render_css_class(self):
                return render_class(self.attrs['class'])

        for group_name, group_iterator in groupby(
                headers, key=lambda header: header.group or id(header)):

            header_group = list(group_iterator)

            header_groups.append(
                HeaderGroup(display_name=group_name,
                            sortable=False,
                            colspan=len(header_group),
                            attrs=Struct({'class': Struct(superheader=True)})))

            for x in header_group:
                x.attrs['class']['subheader'] = True
                if x.is_sorting:
                    x.attrs['class']['sorted_column'] = True

            header_group[0].attrs['class']['first_column'] = True

        if header_groups:
            header_groups[0].attrs['class']['first_column'] = True

        for x in header_groups:
            if not isinstance(x.display_name, string_types):
                x.display_name = ''
        if all([x.display_name == '' for x in header_groups]):
            header_groups = []

        self.header_levels = [header_groups, headers
                              ] if len(header_groups) > 1 else [headers]
        return headers
コード例 #18
0
ファイル: __init__.py プロジェクト: erik-sjoestedt/tri.table
    def __init__(self, table, row, row_index):
        self.table = table
        """ :type : Table """
        self.row = row
        """ :type : object """
        self.row_index = row_index

        args = Struct(
            evaluate_recursive(extract_subkeys(table.Meta, 'row'),
                               table=table,
                               row=row))
        self.template = args.template
        self.attrs = args.attrs
コード例 #19
0
def get_meta(cls):
    """
        Collect all members of any contained :code:`Meta` class declarations from the given class or any of its base classes.
        (Sub class values take precedence.)

        :type cls: class
        :rtype: Struct
    """
    merged_attributes = Struct()
    for class_ in reversed(cls.mro()):
        if hasattr(class_, 'Meta'):
            for key, value in class_.Meta.__dict__.items():
                merged_attributes[key] = value
    return merged_attributes
コード例 #20
0
ファイル: __init__.py プロジェクト: erik-sjoestedt/tri.table
 def generate_variables():
     for column in self.bound_columns:
         if column.query.show:
             query_kwargs = setdefaults_path(
                 Struct(), column.query,
                 dict(
                     name=column.name,
                     gui__label=column.display_name,
                     attr=column.attr,
                     model=column.table.Meta.model,
                 ), {
                     'class': Variable,
                 })
             yield query_kwargs.pop('class')(**query_kwargs)
コード例 #21
0
ファイル: __init__.py プロジェクト: erik-sjoestedt/tri.table
 def generate_bulk_fields():
     for column in self.bound_columns:
         if column.bulk.show:
             bulk_kwargs = setdefaults_path(
                 Struct(), column.bulk,
                 dict(
                     name=column.name,
                     attr=column.attr,
                     required=False,
                     empty_choice_tuple=(None, '', '---', True),
                     model=self.Meta.model,
                 ), {
                     'class': Field.from_model,
                 })
             if bulk_kwargs['class'] == Field.from_model:
                 bulk_kwargs['field_name'] = column.attr
             yield bulk_kwargs.pop('class')(**bulk_kwargs)
コード例 #22
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_file():
    class FooForm(Form):
        foo = Field.file(required=False)

    form = FooForm(data=Data(foo='1'))
    instance = Struct(foo=None)
    assert form.is_valid()
    form.apply(instance)
    assert instance.foo == '1'

    # Non-existent form entry should not overwrite data
    form = FooForm(data=Data(foo=''))
    assert form.is_valid(), {x.name: x.errors for x in form.fields}
    form.apply(instance)
    assert instance.foo == '1'

    form = FooForm(data=Data())
    assert form.is_valid(), {x.name: x.errors for x in form.fields}
    form.apply(instance)
    assert instance.foo == '1'
コード例 #23
0
ファイル: test_views.py プロジェクト: dhaggen/tri.form
def test_create_or_edit_object():
    # 1. View create form
    request = Struct(method='GET',
                     META={},
                     GET={},
                     user=Struct(is_authenticated=lambda: True))

    response = create_object(
        request=request,
        model=CreateOrEditObjectTest,
        form__field__f_int__initial=1,
        form__field__f_float__initial=lambda form, field: 2,
        render__context={'foo': 'FOO'},
        render=lambda **kwargs: kwargs)
    assert response['context_instance'][
        'object_name'] == 'create or edit object test'
    assert response['context_instance']['is_create'] is True
    form = response['context_instance']['form']
    assert response['context_instance']['foo'] == 'FOO'
    assert form.mode is INITIALS_FROM_GET
    assert form.fields_by_name['f_int'].initial == 1
    assert form.fields_by_name['f_int'].errors == set()
    assert form.fields_by_name['f_int'].value == 1
    assert form.fields_by_name['f_float'].value == 2
    assert form.fields_by_name['f_bool'].value is None
    assert set(form.fields_by_name.keys()) == {'f_int', 'f_float', 'f_bool'}

    # 2. Create
    request.method = 'POST'
    request.POST = {
        'f_int': '3',
        'f_float': '5.1',
        'f_bool': 'True',
        '-': '-',
    }
    create_object(request=request,
                  model=CreateOrEditObjectTest,
                  render=lambda **kwargs: kwargs)
    assert get_saved_something() is not None
    assert get_saved_something().f_int == 3
    assert get_saved_something().f_float == 5.1
    assert get_saved_something().f_bool is True

    # 3. View edit form
    request.method = 'GET'
    del request.POST
    response = edit_object(request=request,
                           instance=get_saved_something(),
                           render=lambda **kwargs: kwargs)
    form = response['context_instance']['form']
    assert form.get_errors() == {}
    assert form.fields_by_name['f_int'].value == 3
    assert form.fields_by_name['f_float'].value == 5.1
    assert form.fields_by_name['f_bool'].value is True

    # 4. Edit
    request.method = 'POST'
    request.POST = {
        'f_int': '7',
        'f_float': '11.2',
        '-': '-',
        # Not sending a parameter in a POST is the same thing as false
    }
    response = edit_object(
        request=request,
        instance=get_saved_something(),
        redirect=lambda form, **_: {'context_instance': {
            'form': form
        }},
        render=lambda **kwargs: kwargs)
    form = response['context_instance']['form']
    assert form.get_errors() == {}
    assert form.is_valid()
    assert get_saved_something() is not None
    assert get_saved_something().f_int == 7
    assert get_saved_something().f_float == 11.2
    assert not get_saved_something().f_bool
コード例 #24
0
ファイル: __init__.py プロジェクト: dhaggen/tri.form
 def evaluate(self):
     for field in self.fields:
         field.evaluate()
     self.fields = [field for field in self.fields if should_show(field)]
     self.fields_by_name = Struct({field.name: field for field in self.fields})
コード例 #25
0
def test_sort_after_indexes():
    sorts_right([
        Struct(name='baz', after=1, expected_position=2),
        Struct(name='foo', after=0, expected_position=1),
        Struct(name='bar', after=-1, expected_position=0),
    ])
コード例 #26
0
ファイル: views.py プロジェクト: boxed/great_apis
 def data():
     for app_name, models in apps.all_models.items():
         for name, cls in models.items():
             if app.get(app_name, {}).get(name, {}).get('show', True):
                 yield Struct(app_name=app_name, model_name=name, model=cls)
コード例 #27
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_parse_errors():
    def post_validation(form):
        form.add_error('General snafu')

    form = MyTestForm(data=Data(party='foo',
                                username='******',
                                joined='foo',
                                staff='foo',
                                admin='foo',
                                a_date='fooasd',
                                a_time='asdasd',
                                **{'-': ''}),
                      post_validation=post_validation)

    assert not form.is_valid()

    assert form.errors == {'General snafu'}

    assert form.fields_by_name['party'].parsed_data == 'foo'
    assert form.fields_by_name['party'].errors == {
        'foo not in available choices'
    }
    assert form.fields_by_name['party'].value is None

    assert form.fields_by_name['username'].parsed_data == 'bar_foo'
    assert form.fields_by_name['username'].errors == {
        'Username must begin with "foo_"'
    }
    assert form.fields_by_name['username'].value is None

    assert form.fields_by_name['joined'].raw_data == 'foo'
    assert_one_error_and_matches_reg_exp(
        form.fields_by_name['joined'].errors,
        "time data u?'foo' does not match format u?'%Y-%m-%d %H:%M:%S'")
    assert form.fields_by_name['joined'].parsed_data is None
    assert form.fields_by_name['joined'].value is None

    assert form.fields_by_name['staff'].raw_data == 'foo'
    assert form.fields_by_name['staff'].parsed_data is None
    assert form.fields_by_name['staff'].value is None

    assert form.fields_by_name['admin'].raw_data == 'foo'
    assert form.fields_by_name['admin'].parsed_data is None
    assert form.fields_by_name['admin'].value is None

    assert form.fields_by_name['a_date'].raw_data == 'fooasd'
    assert_one_error_and_matches_reg_exp(
        form.fields_by_name['a_date'].errors,
        "time data u?'fooasd' does not match format u?'%Y-%m-%d'")
    assert form.fields_by_name['a_date'].parsed_data is None
    assert form.fields_by_name['a_date'].value is None

    assert form.fields_by_name['a_time'].raw_data == 'asdasd'
    assert_one_error_and_matches_reg_exp(
        form.fields_by_name['a_time'].errors,
        "time data u?'asdasd' does not match format u?'%H:%M:%S'")
    assert form.fields_by_name['a_time'].parsed_data is None
    assert form.fields_by_name['a_time'].value is None

    with pytest.raises(AssertionError):
        form.apply(Struct())
コード例 #28
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_initial_from_instance():
    assert Form(instance=Struct(a=Struct(b=7)),
                fields=[Field(name='a__b')]).fields[0].initial == 7
コード例 #29
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_initial_list_from_instance():
    assert Form(instance=Struct(a=Struct(b=[7])),
                fields=[Field(name='a__b',
                              is_list=True)]).fields[0].initial_list == [7]
コード例 #30
0
ファイル: test_forms.py プロジェクト: dhaggen/tri.form
def test_required():
    form = MyTestForm(request=Struct(method='POST', POST=Data({'-': '-'})))
    assert form.fields_by_name['a_date'].value is None
    assert form.fields_by_name['a_date'].errors == {'This field is required'}