Ejemplo n.º 1
0
 def test_hidden(self):
     row, fields = self._fields((
         pp.Field('numeric', type=pd.Integer()),
         pp.Field('string', type=pd.String()),
         pp.Field('multiline', type=pd.String(), height=4),
         pp.Field('date', type=pd.Date()),
         pp.Field('datetime', type=pd.DateTime()),
         pp.Field('boolean', type=pd.Boolean()),
         pp.Field('checklist', type=pd.Array(inner_type=pd.Integer()),
                  enumerator=pd.FixedEnumerator(range(10)),
                  selection_type=pp.SelectionType.CHECKLIST),
         pp.Field('choice', type=pd.Integer(),
                  enumerator=pd.FixedEnumerator(range(10)),
                  selection_type=pp.SelectionType.CHOICE),
         pp.Field('radio', type=pd.Integer(),
                  enumerator=pd.FixedEnumerator(range(10)),
                  selection_type=pp.SelectionType.RADIO),
     ))
     context = self._export_context('cs')
     for fid, value, exported in (
             ('numeric', 5, '5'),
             ('string', 'x', 'x'),
             ('multiline', 'xxx\nxxx', 'xxx\nxxx'),
             ('date', datetime.date(2016, 8, 30), '30.08.2016'),
             ('datetime', datetime.datetime(2016, 8, 30, 12, 40, tzinfo=context.timezone()),
              '30.08.2016 12:40:00'),
             ('boolean', True, 'T'),
             ('boolean', False, 'F'),
             ('checklist', (pd.ival(1), pd.ival(4)), ('1', '4')),
             ('choice', 5, '5'),
             ('radio', 5, '5'),
     ):
         field = pu.find(fid, fields, key=lambda f: f.id)
         row[fid] = pd.Value(row.type(fid), value)
         self.assertEqual(context.localize(field.hidden(context)),
                          ''.join('<input type="hidden" name="%s" value=%s/>' %
                                  (fid, saxutils.quoteattr(v))
                                  for v in pu.xtuple(exported)))
         error = field.validate(self.Request(params={fid: exported}), context.locale_data())
         self.assertIs(error, None, "%s: %s" % (error and error.message(), exported))
         self.assertEqual(row[fid].value(), value)
Ejemplo n.º 2
0
 def _find_column(self, cid):
     return find(cid, self._columns, key=lambda c: c.id())
Ejemplo n.º 3
0
 def _find_column(self, cid):
     return find(cid, self._columns, key=lambda c: c.id())
Ejemplo n.º 4
0
def cmd_type_kwargs(filename, lines, type_map=None):
    """Convert type kwargs in field specifications to type instance aruments.

    The optional argument 'type_map' may be used to supply type classes to fields
    where the type can not be determined from the field specification itself.

    The value of the argument is a file name as a string.  The current type map
    file format follows the format of pytis/tools/dump-specifications.py
    output.

    """
    lines_to_delete = []
    type_kwargs = ('not_null', 'unique', 'constraints', 'minlen', 'maxlen',
                   'minimum', 'maximum', 'encrypted', 'precision', 'format',
                   'mindate', 'maxdate', 'utc', 'validation_messages',
                   'inner_type', 'minsize', 'maxsize', 'formats', 
                   'strength', 'md5', 'verify', 'text',)
    if type_map:
        type_dict = make_type_map(type_map)
    else:
        type_dict = None
    for node, args, cls in FieldLocator().search_fields(lines, filename):
        #print "*", filename, node.lineno, node.args and unparse(node.args[0]) or '?'
        type_cls = None
        type_arg = find('type', args, key=lambda a: a.name)
        type_args = [arg for arg in args if arg.name in type_kwargs]
        if args and args[-1].end is None and (args[-1] in type_args or
                                              args[-1] == type_arg and type_args):
            # The end of the last argument may not be always obvious!
            print ("File %s, line %d\n"
                   "  Can't determine end of '%s' argument when it is the last argument.\n"
                   "  Please reformat the source code.") % \
                (filename, args[-1].start.ln + 1, args[-1].name)
            continue
        if type_args and not type_arg:
            argnames = [a.name for a in type_args]
            if all(name in ('not_null', 'unique') for name in argnames):
                continue
            if 'maxlen' in argnames:
                type_cls = 'pd.String'
            elif 'precision' in argnames:
                type_cls = 'pd.Float'
            elif 'utc' in argnames:
                type_cls = 'pd.DateTime'
            elif 'format' in argnames:
                fmt = unparse(find('format', type_args, key=lambda a: a.name).value)
                if fmt.startswith('pd.Date.'):
                    type_cls = 'pd.Date'
                elif fmt.startswith('pd.Time.'):
                    type_cls = 'pd.Time'
                elif fmt.startswith('pd.DateTime.'):
                    type_cls = 'pd.DateTime'
            if type_cls is None:
                field_id = '.'.join((os.path.splitext(os.path.split(filename)[-1])[0],
                                     cls,
                                     node.args and eval(unparse(node.args[0])) or '?'))
                if type_dict:
                    type_cls = type_dict.get(field_id)
                    #if type_cls:
                    #    print ("File %s, line %d\n"
                    #           "  Data type %s of field %s taken from type map %s.") % \
                    #        (filename, node.lineno, type_cls, field_id, type_map)
                if type_cls is None:
                    print ("File %s, line %d\n"
                           "  Can't determine type for %s (%s)") % \
                        (filename, node.lineno, field_id,
                         ', '.join([unparse(a.kw) for a in type_args]))
                    continue
        # Remove all directly passed type kwargs.
        for arg in type_args:
            lines[arg.start.ln] = (lines[arg.start.ln][:arg.start.offset] +
                                   lines[arg.end.ln][arg.end.offset:])
            for ln in range(arg.start.ln + 1, arg.end.ln + 1):
                if ln not in lines_to_delete:
                    lines_to_delete.append(ln)
            if range(arg.start.ln + 1, arg.end.ln + 1):
                lx = lines_to_delete[-1]+1
            for a in args[args.index(arg)+1:]:
                if a.start.ln == arg.end.ln:
                    if arg.start.ln == arg.end.ln:
                        a.start.offset -= arg.end.offset - arg.start.offset
                        if a.end and a.end.ln == a.start.ln:
                            a.end.offset -= arg.end.offset - arg.start.offset
                    else:
                        start_ln, start_offset = a.start.ln, a.start.offset
                        a.start.ln = arg.start.ln
                        a.start.offset = arg.start.offset + a.start.offset - arg.end.offset
                        if a.end and a.end.ln == start_ln:
                            a.end.ln = arg.start.ln
                            a.end.offset = a.start.offset + a.end.offset - start_offset
        # Move type direct kwargs to type instance kwargs. 
        if type_arg and (type_args or not isinstance(type_arg.value, ast.Call)):
            if type_arg.start.ln == type_arg.end.ln:
                x = lines[type_arg.start.ln][type_arg.start.offset:type_arg.end.offset]
            else:
                x = (lines[type_arg.start.ln][type_arg.start.offset:].strip() + ' ' +
                     ''.join([lines[ln].strip() + ' '
                              for ln in range(type_arg.start.ln+1, type_arg.end.ln)
                              if ln not in lines_to_delete]) +
                     lines[type_arg.end.ln][:type_arg.end.offset].strip())
            x = x.strip(',').strip()
            if x != unparse(type_arg.kw):
                print ("File %s, line %d\n"
                       "  Warning: Can't verify position, please check this change.\n"
                       "  '%s'\n  '%s'") % \
                    (filename,
                     type_arg.start.ln - len([l for l in lines_to_delete if l < type_arg.start.ln]),
                     x, unparse(type_arg.kw))
            ln, offset = type_arg.end.ln, type_arg.end.offset
            if isinstance(type_arg.value, ast.Call):
                offset -= 1
                insert = ', '.join([unparse(a.kw) for a in type_args
                                    if unparse(a.kw) not in unparse(type_arg.value)])
                if lines[ln][offset - 1] != '(':
                    insert = ', ' + insert
            else:
                insert = '(' + ', '.join([unparse(a.kw) for a in type_args]) + ')'
        # Insert type kwarg as an instance.
        elif type_args:
            assert type_cls is not None
            ln, offset = type_args[0].start.ln, type_args[0].start.offset
            insert = ', type=%s(%s)' % (type_cls,
                                        ', '.join([unparse(a.kw) for a in type_args]))
        else:
            insert = None
        if insert:
            lines[ln] = lines[ln][:offset] + insert + lines[ln][offset:]
    for i, ln in enumerate(sorted(lines_to_delete)):
        del lines[ln - i]