コード例 #1
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_permissions(self):
     data = pd.RestrictedMemData(
         [pd.ColumnSpec(c, pd.String()) for c in ('x', 'y', 'z')],
         access_rights=pd.AccessRights(('x', (None, pd.Permission.ALL)),
                                       ('y', (None, pd.Permission.VIEW)),
                                       ('z', ((), pd.Permission.ALL))),
     )
     row = pp.PresentedRow((
         pp.Field('x'),
         pp.Field('y'),
         pp.Field('z'),
         pp.Field('zz',
                  virtual=True,
                  computer=pp.computer(lambda r, z: '-' + z + '-')),
     ),
                           data,
                           None,
                           new=True)
     assert row.permitted('x', pd.Permission.VIEW)
     assert row.permitted('x', True)
     assert row.permitted('y', pd.Permission.VIEW)
     assert not row.permitted('y', pd.Permission.UPDATE)
     assert not row.permitted('z', pd.Permission.VIEW)
     protected_row = row.protected()
     with pytest.raises(protected_row.ProtectionError):
         protected_row['z'].value()
     with pytest.raises(protected_row.ProtectionError):
         protected_row['zz'].value()
     # Cover special cases for a non-permitted field in various methods.
     assert row.get('z', secure=True) is None
     assert row.display('z') == ''
     assert row.enumerate('z') == []
     assert not row.editable('z')
コード例 #2
0
ファイル: test.py プロジェクト: cerha/pytis
    def test_validation_order(self):
        # This test reproduces a previously existing bug in computer input
        # validation dependencies.
        fields = (
            pp.Field('a', type=pd.String(not_null=True)),
            pp.Field('b',
                     type=pd.String(not_null=True, maxlen=1),
                     computer=pp.computer(lambda r, a: a[0].upper(),
                                          validate=True)),
            pp.Field('c',
                     type=pd.String(enumerator=pd.FixedEnumerator(range(10)),
                                    not_null=True),
                     computer=pp.computer(lambda r, b: str(ord(b) % 10),
                                          validate=True)),
        )
        row = self._row(fields, new=True)
        row.validate('a', 'foo')
        assert row['b'].value() == 'F'
        assert row['c'].value() == '0'
        # Set 'b' to an invalid value (violates maxlen=1).
        row.validate('b', 'xxx')

        def cb():
            # This used to fail when the computer for 'c' was not called
            # due to invalid value of 'b' (when 'b' validity was not refreshed
            # correctly).
            assert row['c'].value() == '6'

        row.register_callback(row.CALL_CHANGE, 'c', cb)
        row.validate('a', 'bar')
コード例 #3
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_completer(self):
     completer = self._enumerator(
         ('x', ),
         data=(('Apple', ), ('Bananas', ), ('Basil', ), ('Bacardi', ),
               ('Cinamon', )),
     )
     fields = (
         pp.Field('a', type=pd.Integer(not_null=True)),
         pp.Field('x0',
                  type=pd.String(enumerator=pd.FixedEnumerator(('a', 'b',
                                                                'c')))),
         pp.Field('x1', type=pd.String(), completer=('yes', 'no', 'maybe')),
         pp.Field('x2',
                  type=pd.String(),
                  completer=completer,
                  runtime_filter=pp.computer(lambda r, a: pd.NE(
                      'x', pd.sval('Bacardi')) if a == 1 else None)),
     )
     row = self._row(fields, new=True)
     assert not row.has_completer('a')
     assert row.has_completer('x0')
     assert row.has_completer('x1', static=True)
     assert row.has_completer('x2')
     assert not row.has_completer('x2', static=True)
     assert row.completions('a') == []
     assert row.completions('x0') == ['a', 'b', 'c']
     assert row.completions('x1') == ['maybe', 'no', 'yes']
     assert row.completions('x1', prefix='y') == ['yes']
     assert row.completions('x2') == ('Apple', 'Bananas', 'Basil',
                                      'Bacardi', 'Cinamon')
     assert row.completions('x2',
                            prefix='ba') == ('Bananas', 'Basil', 'Bacardi')
     row['a'] = 1
     assert row.completions('x2', prefix='ba') == ('Bananas', 'Basil')
コード例 #4
0
 class Specification(pp.Specification):
     table = 'grid_test'
     fields = (
         pp.Field('id', type=pd.Integer()),
         pp.Field('name', type=pd.String()),
         pp.Field('price', type=pd.Float(precision=2)),
         pp.Field('flag', type=pd.Boolean()),
     )
コード例 #5
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_prefill_untouched(self):
     row = self._row((
         pp.Field('a', type=pd.Integer()),
         pp.Field('b', type=pd.Integer()),
     ))
     prefill = dict(a=5, b=8)
     row.set_row(None, reset=True, prefill=prefill)
     assert prefill == dict(a=5, b=8)
コード例 #6
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_sorting(self):
     fields = (
         pp.Field('a', 'Field A'),
         pp.Field('b', 'Field B'),
         pp.Field('c', 'Field C'),
         pp.Field('d', 'Field D'),
     )
     unsorted = (fields[2], fields[0], fields[1], fields[3])
     assert tuple(sorted(unsorted)) == fields
コード例 #7
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_filename(self):
     row = self._row((
         pp.Field('x', default='aaa'),
         pp.Field('y', filename='x'),
         pp.Field('z', filename=lambda r: 'file_%s.pdf' % r['x'].value()),
     ),
                     new=True)
     assert row.filename('x') == None
     assert row.filename('y') == 'aaa'
     assert row.filename('z') == 'file_aaa.pdf'
コード例 #8
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_set_transaction(self):
     row = self._row((pp.Field('x'), pp.Field('y')))
     assert row.transaction() == None
     # TODO: This whole test file tries to avoid using a real database connection,
     # so we can't create a real transaction here.  Using 'x' is invalid for
     # real use but it stil verifies that set_transaction works as long as
     # set_transaction doesn't validate its argument.
     transaction = 'x'  # pd.DBTransactionDefault(pytis.config.dbconnection)
     row.set_transaction(transaction)
     assert row.transaction() == transaction
コード例 #9
0
ファイル: test.py プロジェクト: cerha/pytis
 class Fruits(pytis.presentation.Specification):
     fields = (
         pp.Field('id'),
         pp.Field('title'),
         pp.Field('code', type=pd.Integer()),
         pp.Field('tropical', type=pd.Boolean()),
     )
     data_cls = pd.MemData
     data = (('apl', 'Apple', 123, False), ('ban', 'Banana', 234, True),
             ('str', 'Strawberry', 234, False), ('org', 'Orange', 456,
                                                 True))
コード例 #10
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_attachment_storage(self):
     storage = pytis.presentation.AttachmentStorage()
     row = self._row((
         pp.Field('a', type=pd.String()),
         pp.Field('b', type=pd.String(), attachment_storage=storage),
         pp.Field('c',
                  type=pd.String(),
                  attachment_storage=lambda row: storage),
     ))
     assert row.attachment_storage('a') is None
     assert row.attachment_storage('b') == storage
     assert row.attachment_storage('c') == storage
コード例 #11
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_cbcomputer_display(self):
     enumerator = self._enumerator(('id', 'title'),
                                   data=(('1', 'First'), ('2', 'Second')))
     fields = (
         pp.Field('a',
                  type=pd.String(enumerator=enumerator),
                  display='title'),
         pp.Field('b', computer=pp.CbComputer('a', 'title')),
     )
     row = self._row(fields)
     row['a'] = '1'
     assert row.display('a') == 'First'
     assert row.display('b') == ''
コード例 #12
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_display_functions(self):
     enumerator = self._enumerator(
         ('id', 'title', 'letter'),
         data=(('1', 'First', 'A'), ('2', 'Second', 'B')))
     fields = (
         pp.Field('a'),
         pp.Field('b',
                  type=pd.String(enumerator=enumerator),
                  display=lambda x: '-' + x + '-'),
         pp.Field('c',
                  type=pd.String(enumerator=enumerator),
                  display=lambda row: row['title'].value().lower()),
     )
     row = self._row(fields, None, new=True, prefill=dict(b='1', c='2'))
     assert row.display('b') == '-1-'
     assert row.display('c') == 'second'
コード例 #13
0
ファイル: web.py プロジェクト: nicLucian/pytis
 class Spec(wiking.Specification):
     table = 'cms_access_log_data'
     fields = [
         pp.Field(_id)
         for _id in ('log_id', 'timestamp', 'uri', 'uid', 'modname',
                     'action', 'ip_address', 'user_agent', 'referer')
     ]
コード例 #14
0
ファイル: web.py プロジェクト: nicLucian/pytis
 class Spec(wiking.Specification):
     table = 'cms_session_log_data'
     fields = [
         pp.Field(_id)
         for _id in ('log_id', 'session_id', 'uid', 'login', 'success',
                     'start_time', 'ip_address', 'user_agent', 'referer')
     ]
コード例 #15
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_binary_computer(self):
     a = '\x04\x00\x00\x05\x00\x19\x00'
     b = '\x00\x05\x04\xa4\xbb\x10\x00'
     row = self._row((
         pp.Field('x', type=pd.String()),
         pp.Field(
             'data',
             type=pd.Binary(not_null=True),
             computer=pp.computer(
                 lambda r, x: x == 'a' and a or x == 'b' and b or None)),
     ))
     assert row['data'].value() is None
     row['x'] = pd.sval('a')
     assert row['data'].value() == a
     assert isinstance(row['data'].value(), pd.Binary.Data)
     row['x'] = pd.sval('b')
     assert row['data'].value() == b
コード例 #16
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_inline_display(self):
     enumerator = self._enumerator(
         ('id', 'title', 'letter'),
         data=(('1', 'First', 'A'), ('2', 'Second', 'B')))
     fields = (
         pp.Field('a',
                  type=pd.String(enumerator=enumerator),
                  display='title',
                  inline_display='b',
                  null_display='-'),
         pp.Field('b', type=pd.String()),
     )
     row = self._row(fields, new=True, prefill=dict(a='1', b='FIRST'))
     assert row.display('a') == 'FIRST'
     assert row.display('a', export=lambda x: x.value().lower()) == 'first'
     row['b'] = None
     assert row.display('a') == '-'
コード例 #17
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_unique(self):
     data = pd.MemData(
         (pd.ColumnSpec('a', pd.String(not_null=True, unique=True)), ),
         data=(('1', ), ('2', ), ('3', )),
     )
     row = pp.PresentedRow((pp.Field('a'), ), data, None, new=True)
     assert row.validate('a', '1') is not None
     assert row.validate('a', '4') is None
コード例 #18
0
ファイル: test.py プロジェクト: cerha/pytis
    def test_str(self):
        class BigString(pd.String, pd.Big):
            pass

        row = self._row((
            pp.Field('x', type=pd.Integer(not_null=True)),
            pp.Field('y', type=pd.Integer(), default=88),
            pp.Field('passwd', type=pd.Password()),
            pp.Field('data', type=BigString()),
        ),
                        new=True,
                        prefill=dict(x=1,
                                     y=3,
                                     passwd='secret',
                                     data=1024 * 'x'))
        assert unistr(
            row
        ) == '<PresentedRow: x=1, y=3, passwd=***, data=<BigString 1 kB>>'
コード例 #19
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_editable_always_bool(self):
     row = self._row((
         pp.Field('a', type=pd.String()),
         pp.Field('b', type=pd.Integer()),
         pp.Field('c', editable=pp.computer(lambda r, a, b: a or b)),
     ))
     for a, b, editable in (
         (None, None, False),
         ('', None, False),
         (None, 0, False),
         ('', 0, False),
         (None, 1, True),
         ('', 5, True),
         ('x', None, True),
         ('y', 8, True),
     ):
         row['a'] = a
         row['b'] = b
         assert row.editable('c') is editable
コード例 #20
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_validation_cache(self):
     # This test reproduces a previously existing bug in validation result caching.
     enumerator = self._enumerator(('id', 'title'),
                                   data=(('1', 'First'), ('2', 'Second')))
     row = self._row((pp.Field('a',
                               type=pd.String(not_null=True,
                                              enumerator=enumerator)), ))
     assert not row.validate('a', '3') is None
     data = enumerator._data  # There is currently no need to make this public elsewhere.
     data.insert(pd.Row(
         (('id', pd.sval('3')), ('title', pd.sval('Third')))))
     assert row.validate('a', '3') == None
コード例 #21
0
ファイル: _test.py プロジェクト: nicLucian/pytis
    def setUp(self):
        self.longMessage = True
        key = pd.ColumnSpec('a', pd.Integer())
        self._columns = (key, pd.ColumnSpec('b', pd.Integer()),
                         pd.ColumnSpec('c', pd.Integer()),
                         pd.ColumnSpec('d', pd.Integer()),
                         pd.ColumnSpec('r', pd.IntegerRange()))
        self._data = pd.Data(self._columns, key)

        def twice(row):
            # Just try if it is possible to access the original row.
            row.original_row()['c'].value()
            c = row['c'].value()
            return c is not None and c * 2 or None

        def sum(row):
            b, c = (row['b'].value(), row['c'].value())
            if b is None or c is None:
                return 0
            return b + c

        def inc(row):
            sum = row['sum'].value()
            return sum is not None and sum + 1 or None

        def gt5(row):
            return row['sum'].value() > 5

        self._fields = (
            pp.Field('a'),
            pp.Field('b'),
            pp.Field('c', default=lambda: 5),
            pp.Field('d',
                     editable=pp.Computer(gt5, depends=('sum', )),
                     computer=pp.Computer(twice, depends=('c', ))),
            pp.Field('e', type=pd.Integer(), virtual=True, default=88),
            pp.Field('sum',
                     type=pd.Integer(),
                     virtual=True,
                     editable=pp.Editable.NEVER,
                     computer=pp.Computer(sum, depends=('b', 'c'))),
            pp.Field('inc',
                     type=pd.Integer(),
                     virtual=True,
                     editable=pp.Editable.NEVER,
                     computer=pp.Computer(inc, depends=('sum', ))),
            pp.Field('r'),
        )
コード例 #22
0
ファイル: test.py プロジェクト: cerha/pytis
    def test_recursive_computer_validation(self):
        fields = (
            pp.Field('a',
                     type=pd.Integer(not_null=True),
                     computer=pp.computer(lambda r, b: 2 * b, validate=True)),
            pp.Field(
                'b',
                type=pd.Integer(not_null=True,
                                enumerator=pd.FixedEnumerator(range(101))),
                runtime_filter=pp.computer(lambda r, a: lambda x: x % a == 0,
                                           validate=True)),
        )
        # The computer for 'a' is called to compute the initial value and will lead to recursion
        # because it requires validation of 'b' which needs the value of 'a'...
        with pytest.raises(RuntimeError):
            self._row(fields, new=True)

        class Specification(pp.Specification):
            pass

        Specification.fields = fields
        # ViewSpec initialization should detect the cyclic dependency.
        with pytest.raises(AssertionError):
            Specification().view_spec()

        class Specification2(Specification):
            def _customize_fields(self, fields):
                fields.modify('b',
                              runtime_filter=pp.computer(
                                  lambda r, a: lambda x: x % a == 0,
                                  validate=True,
                                  novalidate=('a', )))

        row = self._row(Specification2().view_spec().fields(), new=True)
        # 'a' is None so runtime_filter will try to compute x % None (because 'a' is not validated).
        with pytest.raises(TypeError):
            row.enumerate('b')
コード例 #23
0
ファイル: web.py プロジェクト: cerha/pytis
 class Spec(Specification):
     table = 'cms_session'
     fields = [pp.Field(_id) for _id in ('session_id', 'uid', 'session_key', 'last_access')]
コード例 #24
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_fields(self):
     fields = (pp.Field('x'), pp.Field('y'))
     row = self._row(fields)
     assert row.fields() == fields
コード例 #25
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_keys(self):
     row = self._row((pp.Field('x'), pp.Field('y')))
     assert sorted(row.keys()) == ['x', 'y']
コード例 #26
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_resolver(self):
     row = self._row((pp.Field('x'), pp.Field('y')))
     assert row.resolver() == pytis.config.resolver
コード例 #27
0
ファイル: test.py プロジェクト: cerha/pytis
    def _mega_row(self, new=False, row=None, singleline=False, **prefill):
        # TODO: This all-in-one row was historically used for all tests
        # but it proved to be problematic.  You can not see the definition
        # of the fields from paticular tests so it is hard to guess the test
        # logic.  Morover the specification is getting too complicated
        # and hard to maintain usable in all situations.  Thus new tests should
        # Define their own fields directly just for their purpose.

        class BigString(pd.String, pd.Big):
            pass

        class SpecialEnumerator(pd.FixedEnumerator):
            # This class is overriden just to allow definition of runtime_filter
            # and runtime_arguments for the same field (which is only important
            # to improve test coverage)

            def values(self, a=None):
                # Accepts argument a as returned by runtime_arguments.
                return super(SpecialEnumerator, self).values()

        fields = (
            pp.Field('a', type=pd.Integer(not_null=True)),
            pp.Field('b',
                     type=pd.Integer(not_null=True,
                                     enumerator=SpecialEnumerator(range(101))),
                     runtime_filter=pp.computer(
                         lambda r, a: lambda x: x % a == 0, validate=True),
                     runtime_arguments=pp.computer(lambda r, a: dict(a=a))),
            pp.Field('c', type=pd.Integer(not_null=True), default=lambda: 5),
            pp.Field('d',
                     type=pd.Integer(),
                     editable=pp.computer(lambda r, total: total > 5
                                          if total else False),
                     computer=pp.computer(lambda r, c: c * 2, validate=True)),
            pp.Field('fruit',
                     type=pd.String(),
                     codebook='Fruits',
                     display='title',
                     null_display='none'),
            pp.Field('fruit_code',
                     virtual=True,
                     computer=pp.CbComputer('fruit', 'code')),
            pp.Field('range',
                     type=pd.IntegerRange(),
                     visible=pp.computer(lambda r, a: a != 0)),
            pp.Field('total',
                     type=pd.Integer(),
                     virtual=True,
                     editable=pp.Editable.NEVER,
                     computer=pp.computer(lambda r, b, c: b + c,
                                          validate=True,
                                          fallback=0)),
            pp.Field('half_total',
                     type=pd.Integer(),
                     virtual=True,
                     editable=pp.Editable.NEVER,
                     computer=pp.computer(lambda r, total: total // 2
                                          if total is not None else None)),
            pp.Field('x', type=pd.Integer(), virtual=True, default=88),
            pp.Field('password', type=pd.Password(), virtual=True),
            pp.Field('big', type=BigString(), virtual=True),
            pp.Field('array',
                     type=pd.Array,
                     inner_type=pd.String,
                     codebook='Fruits',
                     display='title',
                     virtual=True),
        )

        class Fruits(pytis.presentation.Specification):
            fields = (
                pp.Field('id'),
                pp.Field('title'),
                pp.Field('code', type=pd.Integer()),
                pp.Field('tropical', type=pd.Boolean()),
            )
            data_cls = pd.MemData
            data = (('apl', 'Apple', 123, False), ('ban', 'Banana', 234, True),
                    ('str', 'Strawberry', 234, False), ('org', 'Orange', 456,
                                                        True))

        class TestResolver(pytis.util.Resolver):
            _specifications = {'Fruits': Fruits}

            def _get_object_by_name(self, name):
                try:
                    return self._specifications[name]
                except KeyError:
                    return super(TestResolver, self)._get_object_by_name(name)

        pytis.config.resolver = TestResolver()
        return self._row(fields,
                         row=row,
                         new=new,
                         singleline=singleline,
                         prefill=prefill)
コード例 #28
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_data(self):
     row = self._row((pp.Field('x'), pp.Field('y')))
     assert isinstance(row.data(), pd.MemData)
コード例 #29
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_invalid_codebook_field_type(self):
     row = self._row((pp.Field('a', codebook='InvalidName'), ))
     assert isinstance(row.type('a'), pytis.data.String)
コード例 #30
0
ファイル: test.py プロジェクト: cerha/pytis
 def test_virtual_field_type_class(self):
     row = self._row((pp.Field('a', type=pytis.data.Integer), ))
     assert isinstance(row.type('a'), pytis.data.Integer)