def test_render_display(self):
        # Render in display mode
        form = factory(
            'form',
            name='myform',
            props={
                'action': 'myaction'
            })
        form['image'] = factory(
            'image',
            value={
                'file': StringIO(self.dummy_png),
                'mimetype': 'image/png'
            },
            props={
                'src': 'http://www.example.com/someimage.png',
                'alt': 'Alternative text'
            },
            mode='display')
        self.check_output("""
        <form action="myaction" enctype="multipart/form-data" id="form-myform"
              method="post" novalidate="novalidate">
          <img alt="Alternative text"
               src="http://www.example.com/someimage.png"/>
        </form>
        """, fxml(form()))

        # Rendering is skipped if no source
        form['image'].attrs['src'] = None
        self.check_output("""
        <form action="myaction" enctype="multipart/form-data"
              id="form-myform" method="post" novalidate="novalidate"/>
        """, fxml(form()))
Example #2
0
    def test_fieldset_blueprint(self):
        compound = factory('fieldset',
                           'COMPOUND',
                           props={'legend': 'Some Test'})
        compound['inner'] = factory('text', 'inner', 'value')
        compound['inner2'] = factory('text', 'inner2', 'value2')
        self.check_output(
            """
        <fieldset id="fieldset-COMPOUND">
          <legend>Some Test</legend>
          <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner"
                 type="text" value="value"/>
          <input class="text" id="input-COMPOUND-inner2" name="COMPOUND.inner2"
                 type="text" value="value2"/>
        </fieldset>
        """, fxml(compound()))

        # Structural fieldset renders without id attribute
        compound = factory('fieldset', 'COMPOUND', props={'structural': True})
        self.assertEqual(compound(), '<fieldset></fieldset>')

        # Fieldset display renderers are the same as fieldset edit renderers
        compound = factory('fieldset',
                           'COMPOUND',
                           props={'legend': 'Some Test'},
                           mode='display')
        self.check_output(
            """
        <fieldset id="fieldset-COMPOUND">
          <legend>Some Test</legend>
        </fieldset>
        """, fxml(compound()))
Example #3
0
    def test_div_blueprint_as_leaf(self):
        # Div blueprint as leaf
        input = factory(
            'div:text',
            name='DIV',
            value='1')
        self.check_output("""
        <div>
          <input class="text" id="input-DIV" name="DIV"
                 type="text" value="1"/>
        </div>
        """, fxml(input()))

        data = input.extract({
            'DIV': '2',
        })
        self.assertEqual(data.name, 'DIV')
        self.assertEqual(data.value, '1')
        self.assertEqual(data.extracted, '2')
        self.assertEqual(data.errors, [])

        # Empty div
        input = factory(
            'div',
            name='DIV')
        self.assertEqual(input(), '<div></div>')

        # Div with data attributes
        input = factory(
            'div',
            name='DIV',
            props={
                'data': {
                    'foo': 'bar'
                }
            })
        self.assertEqual(input(), "<div data-foo='bar'></div>")

        # Display mode
        div = factory(
            'div',
            name='DIV',
            props={
                'class': 'foo'
            },
            mode='display')
        self.assertEqual(div(), '<div class="foo"></div>')

        input = factory(
            'div:text',
            name='DIV',
            value='1',
            mode='display')
        self.check_output("""
        <div>
          <div class="display-text" id="display-DIV">1</div>
        </div>
        """, fxml(input()))
 def test_render_with_preset_value_src_property_callable(self):
     # Src property can be callable
     form = factory(
         'form',
         name='myform',
         props={
             'action': 'myaction'
         })
     form['image'] = factory(
         'image',
         value={
             'file': StringIO(self.dummy_png),
             'mimetype': 'image/png'
         },
         props={
             'src': lambda w, d: 'http://www.example.com/otherimage.png',
             'alt': 'Alternative text'
         })
     self.check_output("""
     <form action="myaction" enctype="multipart/form-data" id="form-myform"
           method="post" novalidate="novalidate">
       <img alt="Alternative text" class="image-preview"
            id="image-preview-myform-image"
            src="http://www.example.com/otherimage.png?nocache=..."/>
       <input accept="image/*" class="image" id="input-myform-image"
              name="myform.image" type="file"/>
       ...
     </form>
     """, fxml(form()))
 def test_render_with_preset_value_src_property(self):
     # If file URL of existing image is known, ``src`` property can be set
     # do display image above controls
     form = factory(
         'form',
         name='myform',
         props={
             'action': 'myaction'
         })
     form['image'] = factory(
         'image',
         value={
             'file': StringIO(self.dummy_png),
             'mimetype': 'image/png'
         },
         props={
             'src': 'http://www.example.com/someimage.png',
             'alt': 'Alternative text'
         })
     self.check_output("""
     <form action="myaction" enctype="multipart/form-data" id="form-myform"
           method="post" novalidate="novalidate">
       <img alt="Alternative text" class="image-preview"
            id="image-preview-myform-image"
            src="http://www.example.com/someimage.png?nocache=..."/>
       <input accept="image/*" class="image" id="input-myform-image"
              name="myform.image" type="file"/>
       ...
     </form>
     """, fxml(form()))
 def test_plain_widget_source_is_tree(self):
     # Render plain widget, source is tree
     widget = factory(
         'dynatree',
         name='root',
         props={
             'source': self.mock_tree
         })
     self.check_output("""
     <div class="yafowil-widget-dynatree">
       <input id="input-root" name="root" type="hidden"/>
       <ul class="hiddenStructure" id="dynatree-source-root">
     <li id="animal">Animals<ul>
     <li id="mammal">Mammals<ul>
     <li id="horse">Horse
     </li><li id="ape">Ape
     </li><li id="elephant">Elephant
     </li></ul>
     </li><li id="bird">Birds<ul>
     <li id="turkey">Turkey
     </li><li id="swan">Swan
     </li><li id="hummingbird">Hummingbird
     </li><li id="duck">Duck
     </li></ul>
     </li></ul>
     </li></ul>
       <div class="dynatree-params hiddenStructure">selectMode,1|minExpandLevel,1|rootVisible,False|autoCollapse,False|checkbox,True|imagePath,skin-bootstrap|type,local|initId,dynatree-source-root</div>
       <div class="yafowil-widget-dynatree-tree"/>
     </div>
     """, fxml(widget()))
Example #7
0
    def test_extraction(self):
        widget = factory('ace', 'acefield', props={'required': True})
        request = {'acefield': ''}
        data = widget.extract(request)
        self.assertEqual(data.name, 'acefield')
        self.assertEqual(data.value, UNSET)
        self.assertEqual(data.extracted, '')
        self.assertEqual(data.errors, [
            ExtractionError('Mandatory field was empty')
        ])

        request = {'acefield': 'class Foo(object): pass'}
        data = widget.extract(request)
        self.assertEqual(data.name, 'acefield')
        self.assertEqual(data.value, UNSET)
        self.assertEqual(data.extracted, 'class Foo(object): pass')
        self.assertEqual(data.errors, [])

        self.check_output("""
        <div class="ace-editor-wrapper ace-option-theme-github ace-option-mode-python">
         <textarea class="ace-editor-value"
                   id="ace-acefield-value"
                   name="acefield"
                   style="display:none;">class Foo(object): pass</textarea>
         <div class="ace-editor"
              id="ace-acefield">class Foo(object): pass</div>
        </div>
        """, fxml(widget(data)))
Example #8
0
    def test_compound_blueprint_extraction(self):
        compound = factory('compound', name='COMPOUND')
        compound['inner'] = factory('text', value='value1')
        compound['inner2'] = factory('error:text',
                                     value='value2',
                                     props={'required': True})

        # Extract Compound with empty request
        data = compound.extract({})
        self.assertEqual(data.name, 'COMPOUND')
        self.assertEqual(data.value, UNSET)
        expected = odict()
        expected['inner'] = UNSET
        expected['inner2'] = UNSET
        self.assertEqual(data.extracted, expected)
        self.assertEqual(data.errors, [])

        inner_data = data['inner']
        self.assertEqual(inner_data.name, 'inner')
        self.assertEqual(inner_data.value, 'value1')
        self.assertEqual(inner_data.extracted, UNSET)
        self.assertEqual(inner_data.errors, [])

        # Extract with a value in request
        request = {
            'COMPOUND.inner': 'newvalue',
            'COMPOUND.inner2': '',
        }
        data = compound.extract(request)
        data_inner = data['inner']
        self.assertEqual(data_inner.name, 'inner')
        self.assertEqual(data_inner.value, 'value1')
        self.assertEqual(data_inner.extracted, 'newvalue')
        self.assertEqual(data_inner.errors, [])

        data_inner2 = data['inner2']
        self.assertEqual(data_inner2.name, 'inner2')
        self.assertEqual(data_inner2.value, 'value2')
        self.assertEqual(data_inner2.extracted, '')
        self.assertEqual(data_inner2.errors,
                         [ExtractionError('Mandatory field was empty')])

        expected = odict()
        expected['inner'] = 'newvalue'
        expected['inner2'] = ''
        self.assertEqual(data.extracted, expected)

        self.check_output(
            """
        <div>
          <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner"
                 type="text" value="newvalue"/>
          <div class="error">
            <div class="errormessage">Mandatory field was empty</div>
            <input class="required text" id="input-COMPOUND-inner2"
                   name="COMPOUND.inner2" required="required"
                   type="text" value=""/>
          </div>
        </div>
        """, fxml('<div>' + compound(data=data) + '</div>'))
Example #9
0
 def test_render_table(self):
     form = factory(
         'form',
         name='myform',
         props={
             'action': 'myaction',
         })
     form['table'] = factory('table')
     form['table']['row1'] = factory('tr')
     form['table']['row1']['field1'] = factory(
         'td:text',
         name='field1')
     self.check_output("""
     <form action="myaction" enctype="multipart/form-data" id="form-myform"
           method="post" novalidate="novalidate">
       <table>
         <tr>
           <td>
             <input class="text" id="input-myform-table-row1-field1"
                    name="myform.table.row1.field1" type="text" value=""/>
           </td>
         </tr>
       </table>
     </form>
     """, fxml(form()))
Example #10
0
 def test_nested_form_structural_compound(self):
     # Create nested form, case structural compound
     main_path = os.path.join(self.tempdir, 'main.yaml')
     with open(main_path, 'w') as file:
         file.write(self.yaml_main_tmpl)
     nested_raw = """
         factory: compound
         props:
             structural: True
         widgets:
         - subfieldname:
             factory: text
             value: subfieldvalue
     """
     nested_path = os.path.join(self.tempdir, 'sub.yaml')
     with open(nested_path, 'w') as file:
         file.write(nested_raw)
     context = DummyContext()
     form = YAMLParser(main_path, context=context)()
     self.check_output("""
     <form action="mainformaction" enctype="multipart/form-data"
           id="form-mainform" method="post" novalidate="novalidate">
       <input class="text" id="input-mainform-subfieldname"
              name="mainform.subfieldname" type="text"
              value="subfieldvalue"/>
     </form>
     """, fxml(form()))
Example #11
0
 def test_yaml_form_flat(self):
     raw = """
         factory: form
         name: demoform
         props:
             action: demoaction
         widgets:
         - firstfield:
             factory: text
             value: context.some_attr
     """
     template_path = os.path.join(self.tempdir, 'tmpl.yaml')
     with open(template_path, 'w') as file:
         file.write(raw)
     context = DummyContext()
     form = YAMLParser(template_path, context=context)()
     self.check_output(
         """
     <form action="demoaction" enctype="multipart/form-data"
           id="form-demoform" method="post" novalidate="novalidate">
       <input class="text" id="input-demoform-firstfield"
              name="demoform.firstfield" type="text"
              value="context.some_attr"/>
     </form>
     """, fxml(form()))
Example #12
0
 def test_nested_form_structural_compound(self):
     # Create nested form, case structural compound
     main_path = os.path.join(self.tempdir, 'main.yaml')
     with open(main_path, 'w') as file:
         file.write(self.yaml_main_tmpl)
     nested_raw = """
         factory: compound
         props:
             structural: True
         widgets:
         - subfieldname:
             factory: text
             value: subfieldvalue
     """
     nested_path = os.path.join(self.tempdir, 'sub.yaml')
     with open(nested_path, 'w') as file:
         file.write(nested_raw)
     context = DummyContext()
     form = YAMLParser(main_path, context=context)()
     self.check_output(
         """
     <form action="mainformaction" enctype="multipart/form-data"
           id="form-mainform" method="post" novalidate="novalidate">
       <input class="text" id="input-mainform-subfieldname"
              name="mainform.subfieldname" type="text"
              value="subfieldvalue"/>
     </form>
     """, fxml(form()))
 def test_edit_renderer(self):
     # Render map widget with defaults
     widget = factory(
         'recaptcha',
         name='recaptcha',
         props={
             'public_key': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
             'private_key': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
             'lang': 'de',
             'theme': 'clean',
         })
     self.check_output("""
     <div>
       <div class="recaptcha" data-lang="de"
            data-public_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            data-theme="clean" id="recaptcha-recaptcha">
       </div>
       <noscript>
         <iframe src="http://www.google.com/recaptcha/api/noscript?k=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                 height="300" width="500" frameborder="0">
         </iframe>
         <br/>
         <textarea name="recaptcha_challenge_field" rows="3" cols="40"/>
         <input type="hidden" name="recaptcha_response_field"
                value="manual_challenge"/>
       </noscript>
     </div>
     """, fxml('<div>\n' + widget() + '</div>'))
Example #14
0
 def test_compound_blueprint_value_via_compound(self):
     # Render Compound with values set via compound widget
     value = {
         'inner': 'Value 1 from parent',
         'inner2': 'Value 2 from parent',
     }
     compound = factory(
         'compound',
         name='COMPOUND',
         value=value)
     compound['inner'] = factory('text')
     compound['inner2'] = factory(
         'text',
         props={
             'required': True
         })
     self.check_output("""
     <div>
       <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner"
              type="text" value="Value 1 from parent"/>
       <input class="required text" id="input-COMPOUND-inner2"
              name="COMPOUND.inner2" required="required" type="text"
              value="Value 2 from parent"/>
     </div>
     """, fxml(tag('div', compound())))
Example #15
0
 def test_skip_labels(self):
     widget = factory('dict', name='mydict')
     rendered = fxml('<div>{}</div>'.format(widget()))
     # search for empty th
     index = rendered.find('<th> </th>')
     self.assertTrue(index > -1)
     # search for second empty th
     self.assertTrue(rendered.find('<th> </th>', index + 1) > index)
Example #16
0
    def test_edit_renderer(self):
        # Render widget
        widget = factory('cron', name='cronwidget')
        self.check_output(
            """
        <div class="crontab widget" id="input-cronwidget">
          <div class="cron-value minute">
            <input class="hidden" id="input-cronwidget-minute"
                   name="cronwidget.minute" type="hidden" value=""/>
            <button class="btn btn-sm edit">Minute</button>
          </div>
          <div class="cron-value hour">
            <input class="hidden" id="input-cronwidget-hour"
                   name="cronwidget.hour" type="hidden" value=""/>
            <button class="btn btn-sm edit">Hour</button>
          </div>
          <div class="cron-value dom">
            <input class="hidden" id="input-cronwidget-dom"
                   name="cronwidget.dom" type="hidden" value=""/>
            <button class="btn btn-sm edit">Day of Month</button>
          </div>
          <div class="cron-value month">
            <input class="hidden" id="input-cronwidget-month"
                   name="cronwidget.month" type="hidden" value=""/>
            <button class="btn btn-sm edit">Month</button>
          </div>
          <div class="cron-value dow">
            <input class="hidden" id="input-cronwidget-dow"
                   name="cronwidget.dow" type="hidden" value=""/>
            <button class="btn btn-sm edit">Day of Week</button>
          </div>
          <div class="cron-value year">
            <input class="hidden" id="input-cronwidget-year"
                   name="cronwidget.year" type="hidden" value=""/>
            <button class="btn btn-sm edit">Year</button>
          </div>
          <div class="editarea"/>
        </div>
        """, fxml(widget()))

        # Render with JS config properties
        widget = factory('cron',
                         name='cronwidget',
                         props={
                             'lang': 'de',
                             'start_year': 2010,
                             'end_year': 2020
                         })
        self.check_output(
            """
        <div class="crontab widget"
             data-end_year='2020'
             data-lang='de'
             data-start_year='2010'
             id="input-cronwidget">...</div>
        """, widget())
Example #17
0
    def test_compound_blueprint_structural_children(self):
        # Compound with structural compound as child
        value = {
            'inner': 'Value 1 from parent',
            'inner2': 'Value 2 from parent',
        }
        compound = factory('compound', name='COMPOUND', value=value)
        structural = compound['STRUCTURAL'] = factory(
            'compound', props={'structural': True})
        structural['inner'] = factory('text')
        structural['inner2'] = factory('text', props={'required': True})
        self.check_output(
            """
        <div>
          <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner"
                 type="text" value="Value 1 from parent"/>
          <input class="required text" id="input-COMPOUND-inner2"
                 name="COMPOUND.inner2" required="required" type="text"
                 value="Value 2 from parent"/>
        </div>
        """, fxml(tag('div', compound())))

        self.assertEqual(compound.treerepr().split('\n'), [
            "<class 'yafowil.base.Widget'>: COMPOUND",
            "  <class 'yafowil.base.Widget'>: STRUCTURAL",
            "    <class 'yafowil.base.Widget'>: inner",
            "    <class 'yafowil.base.Widget'>: inner2", ""
        ])

        data = compound.extract({
            'COMPOUND.inner': 'newvalue',
            'COMPOUND.inner2': '',
        })
        self.assertEqual(data.name, 'COMPOUND')
        self.assertEqual(data.value, {
            'inner2': 'Value 2 from parent',
            'inner': 'Value 1 from parent'
        })
        expected = odict()
        expected['inner'] = 'newvalue'
        expected['inner2'] = ''
        self.assertEqual(data.extracted, expected)

        data_inner = data['inner']
        self.assertEqual(data_inner.name, 'inner')
        self.assertEqual(data_inner.value, 'Value 1 from parent')
        self.assertEqual(data_inner.extracted, 'newvalue')
        self.assertEqual(data_inner.errors, [])

        data_inner2 = data['inner2']
        self.assertEqual(data_inner2.name, 'inner2')
        self.assertEqual(data_inner2.value, 'Value 2 from parent')
        self.assertEqual(data_inner2.extracted, '')
        self.assertEqual(data_inner2.errors,
                         [ExtractionError('Mandatory field was empty')])
Example #18
0
 def test_static_dict(self):
     widget = factory(
         'error:dict',
         name='mydict',
         value=odict([('k1', 'v1')]),
         props={
             'static': True,
             'key_label': 'Key',
             'value_label': 'Value'
         })
     rendered = widget()
     self.assertEqual(widget.treerepr().split('\n'), [
         "<class 'yafowil.base.Widget'>: mydict",
         "  <class 'yafowil.base.Widget'>: exists",
         "  <class 'yafowil.base.Widget'>: table",
         "    <class 'yafowil.base.Widget'>: head",
         "      <class 'yafowil.base.Widget'>: row",
         "        <class 'yafowil.base.Widget'>: key",
         "        <class 'yafowil.base.Widget'>: value",
         "    <class 'yafowil.base.Widget'>: body",
         "      <class 'yafowil.base.Widget'>: entry0",
         "        <class 'yafowil.base.Widget'>: key",
         "        <class 'yafowil.base.Widget'>: value",
         ""
     ])
     self.check_output("""
     <div>
       <input class="hidden" id="input-mydict-exists"
              name="mydict.exists" type="hidden" value="1"/>
       <table class="dictwidget key-keyfield value-valuefield"
              id="dictwidget_mydict.entry">
         <thead>
           <tr>
             <th>Key</th>
             <th>Value</th>
           </tr>
         </thead>
         <tbody>
           <tr>
             <td class="key">
               <input class="keyfield" disabled="disabled"
                      id="input-mydict-entry0-key"
                      name="mydict.entry0.key"
                      type="text" value="k1"/>
             </td>
             <td class="value">
               <input class="valuefield" id="input-mydict-entry0-value"
                      name="mydict.entry0.value" type="text" value="v1"/>
             </td>
           </tr>
         </tbody>
       </table>
     </div>
     """, fxml('<div>{}</div>'.format(rendered)))
Example #19
0
 def test_edit_renderer(self):
     widget = factory('ace', 'acefield', props={'required': True})
     self.check_output("""
     <div class="ace-editor-wrapper ace-option-theme-github ace-option-mode-python">
       <textarea class="ace-editor-value"
                 id="ace-acefield-value"
                 name="acefield"
                 style="display:none;"/>
       <div class="ace-editor" id="ace-acefield"/>
     </div>
     """, fxml(widget()))
Example #20
0
 def test_display_renderer_no_labels(self):
     widget = factory(
         'dict',
         name='display_dict',
         mode='display'
     )
     self.check_output("""
     <div>
       <dl/>
     </div>
     """, fxml('<div>{}</div>'.format(widget())))
def app(environ, start_response):
    url = 'http://%s/' % environ['HTTP_HOST']
    if environ['PATH_INFO'] == '/ywd.js':
        return javascript_response(environ, start_response)
    elif environ['PATH_INFO'] == '/ywd.json':
        return json_response(environ, start_response)
    elif environ['PATH_INFO'] == '/jquery.dynatree.js':
        return javascript_response2(environ, start_response)
    elif environ['PATH_INFO'].startswith('/skin/'):
        return skin_response(environ, start_response)
    elif environ['PATH_INFO'] != '/':
        response = Response(status=404)
        return response(environ, start_response)
    form = factory(u'form', name='yqaexample', props={
        'action': url})
    form['local'] = factory('field:label:error:dynatree', props={
        'label': 'Select single value',
        'value': '',
        'source': sample_tree})
    form['remote'] = factory('field:label:error:dynatree', props={
        'label': 'Select multiple',
        'value': '',
        'source': '%sywd.json' % url,
        'selectMode': 2})
    form['submit'] = factory('field:submit', props={        
        'label': 'submit',
        'action': 'save',
        'handler': lambda widget, data: None,
        'next': lambda request: url})
    controller = Controller(form, Request(environ))
    tag = controller.data.tag
    jq = tag('script', ' ',
             src='https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js',
             type='text/javascript')
    jqui = tag('script', ' ', 
               src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.js',
               type='text/javascript')
    jqdy = tag('script', ' ',
              src='%sjquery.dynatree.js' % url,
              type='text/javascript')    
    ywd = tag('script', ' ',
              src='%sywd.js' % url,
              type='text/javascript')    
    css = tag("style",
              "@import url(%sskin/ui.dynatree.css)" % url,
              type='text/css')
    css += tag('style',
              '.hiddenStructure { display: none; }', 
              type='text/css')
    head = tag('head', jq, jqui, jqdy, ywd, css)
    h1 = tag('h1', 'YAFOWIL Widget Dynatree Example')
    body = tag('body', h1, controller.rendered)
    response = Response(body=fxml(tag('html', head, body)))
    return response(environ, start_response)
Example #22
0
 def test_display_renderer(self):
     widget = factory('cron',
                      name='cronwidget',
                      value='* * * * *',
                      mode='display')
     self.check_output(
         """
     <div class="display-crontab widget" id="display-cronwidget">
       <code>* * * * *</code>
     </div>
     """, fxml(widget()))
Example #23
0
    def test_div_blueprint_as_leaf(self):
        # Div blueprint as leaf
        input = factory('div:text', name='DIV', value='1')
        self.check_output(
            """
        <div>
          <input class="text" id="input-DIV" name="DIV"
                 type="text" value="1"/>
        </div>
        """, fxml(input()))

        data = input.extract({
            'DIV': '2',
        })
        self.assertEqual(data.name, 'DIV')
        self.assertEqual(data.value, '1')
        self.assertEqual(data.extracted, '2')
        self.assertEqual(data.errors, [])

        # Empty div
        input = factory('div', name='DIV')
        self.assertEqual(input(), '<div></div>')

        # Div with data attributes
        input = factory('div', name='DIV', props={'data': {'foo': 'bar'}})
        self.assertEqual(input(), "<div data-foo='bar'></div>")

        # Display mode
        div = factory('div',
                      name='DIV',
                      props={'class': 'foo'},
                      mode='display')
        self.assertEqual(div(), '<div class="foo"></div>')

        input = factory('div:text', name='DIV', value='1', mode='display')
        self.check_output(
            """
        <div>
          <div class="display-text" id="display-DIV">1</div>
        </div>
        """, fxml(input()))
Example #24
0
    def test_fieldset_blueprint(self):
        compound = factory(
            'fieldset',
            'COMPOUND',
            props={
                'legend': 'Some Test'
            })
        compound['inner'] = factory('text', 'inner', 'value')
        compound['inner2'] = factory('text', 'inner2', 'value2')
        self.check_output("""
        <fieldset id="fieldset-COMPOUND">
          <legend>Some Test</legend>
          <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner"
                 type="text" value="value"/>
          <input class="text" id="input-COMPOUND-inner2" name="COMPOUND.inner2"
                 type="text" value="value2"/>
        </fieldset>
        """, fxml(compound()))

        # Structural fieldset renders without id attribute
        compound = factory(
            'fieldset',
            'COMPOUND',
            props={
                'structural': True
            })
        self.assertEqual(compound(), '<fieldset></fieldset>')

        # Fieldset display renderers are the same as fieldset edit renderers
        compound = factory(
            'fieldset',
            'COMPOUND',
            props={
                'legend': 'Some Test'
            },
            mode='display')
        self.check_output("""
        <fieldset id="fieldset-COMPOUND">
          <legend>Some Test</legend>
        </fieldset>
        """, fxml(compound()))
Example #25
0
 def test_key_label_and_value_label_bc_callables(self):
     # test B/C callable signature
     widget = factory(
         'dict',
         name='mydict',
         props={
             'key_label': lambda: 'B/C Computed Key',
             'value_label': lambda: 'B/C Computed Value'
         })
     rendered = fxml('<div>{}</div>'.format(widget()))
     self.assertTrue(rendered.find('B/C Computed Key') > -1)
     self.assertTrue(rendered.find('B/C Computed Value') > -1)
Example #26
0
 def test_key_label_and_value_label_callables(self):
     # ``key_label`` and ``value_label`` may be callables
     widget = factory(
         'dict',
         name='mydict',
         props={
             'key_label': lambda w, d: 'Computed Key',
             'value_label': lambda w, d: 'Computed Value'
         })
     rendered = fxml('<div>{}</div>'.format(widget()))
     self.assertTrue(rendered.find('Computed Key') > -1)
     self.assertTrue(rendered.find('Computed Value') > -1)
 def test_render_no_range(self):
     # Render no range
     widget = factory(
         'slider',
         name='sliderfield')
     self.check_output("""
     <div class="yafowil_slider">
       <input class="slider_value" id="input-sliderfield" name="sliderfield"
              style="display:none;" type="text" value=""/>
       <div class="slider"> </div>
     </div>
     """, fxml(widget()))
Example #28
0
 def test_bc_head_property_bc_callables(self):
     widget = factory(
         'dict',
         name='mydict',
         props={
             'head': {
                 'key': lambda: 'B/C Computed B/C Key',
                 'value': lambda: 'B/C Computed B/C Value',
             }
         })
     rendered = fxml('<div>{}</div>'.format(widget()))
     self.assertTrue(rendered.find('B/C Computed B/C Key') > -1)
     self.assertTrue(rendered.find('B/C Computed B/C Value') > -1)
Example #29
0
 def test_bc_head_property(self):
     # Test B/C ``head`` property
     widget = factory(
         'dict',
         name='mydict',
         props={
             'head': {
                 'key': 'B/C Key',
                 'value': 'B/C Value',
             }
         })
     rendered = fxml('<div>{}</div>'.format(widget()))
     self.assertTrue(rendered.find('B/C Key') > -1)
     self.assertTrue(rendered.find('B/C Value') > -1)
Example #30
0
 def test_display_empty_value(self):
     widget = factory(
         'dict',
         name='display_dict',
         props={
             'key_label': 'Key',
             'value_label': 'Value'
         },
         mode='display')
     self.check_output("""
     <div>
       <h5>Key: Value</h5>
       <dl/>
     </div>
     """, fxml('<div>{}</div>'.format(widget())))
Example #31
0
 def test_display_bc_callable_labels(self):
     widget = factory(
         'dict',
         name='display_dict',
         props={
             'key_label': lambda: 'B/C Computed Key',
             'value_label': lambda: 'B/C Computed Value'
         },
         mode='display')
     self.check_output("""
     <div>
       <h5>B/C Computed Key: B/C Computed Value</h5>
       <dl/>
     </div>
     """, fxml('<div>{}</div>'.format(widget())))
 def test_render_empty(self):
     form = factory(
         'form',
         name='myform',
         props={
             'action': 'myaction'
         })
     form['image'] = factory('image')
     self.check_output("""
     <form action="myaction" enctype="multipart/form-data" id="form-myform"
           method="post" novalidate="novalidate">
       <input accept="image/*" class="image" id="input-myform-image"
              name="myform.image" type="file"/>
     </form>
     """, fxml(form()))
 def test_plain_widget_source_is_string(self):
     # Render plain widget, source is string
     widget = factory(
         'dynatree',
         name='root',
         props={
             'source': 'http://www.foo.bar/baz.json'
         })
     self.check_output("""
     <div class="yafowil-widget-dynatree">
       <input id="input-root" name="root" type="hidden"/>
       <div class="dynatree-source hiddenStructure">http://www.foo.bar/baz.json</div>
       <div class="dynatree-params hiddenStructure">selectMode,1|minExpandLevel,1|rootVisible,False|autoCollapse,False|checkbox,True|imagePath,skin-bootstrap|type,remote</div>
       <div class="yafowil-widget-dynatree-tree"/>
     </div>
     """, fxml(widget()))
Example #34
0
    def test_div_blueprint_compound(self):
        # Div blueprint as compound
        div = factory(
            'div',
            name='DIV_COMPOUND')
        div['inner'] = factory(
            'text',
            value='value1')
        div['inner2'] = factory(
            'text',
            value='value2',
            props={
                'required': True
            })
        self.check_output("""
        <div>
          <input class="text" id="input-DIV_COMPOUND-inner"
                 name="DIV_COMPOUND.inner" type="text" value="value1"/>
          <input class="required text" id="input-DIV_COMPOUND-inner2"
                 name="DIV_COMPOUND.inner2" required="required" type="text"
                 value="value2"/>
        </div>
        """, fxml(div()))

        data = div.extract({
            'DIV_COMPOUND.inner': '1',
            'DIV_COMPOUND.inner2': '2',
        })
        self.assertEqual(data.name, 'DIV_COMPOUND')
        self.assertEqual(data.value, UNSET)
        expected = odict()
        expected['inner'] = '1'
        expected['inner2'] = '2'
        self.assertEqual(data.extracted, expected)
        self.assertEqual(data.errors, [])

        data_inner = data['inner']
        self.assertEqual(data_inner.name, 'inner')
        self.assertEqual(data_inner.value, 'value1')
        self.assertEqual(data_inner.extracted, '1')
        self.assertEqual(data_inner.errors, [])

        data_inner2 = data['inner2']
        self.assertEqual(data_inner2.name, 'inner2')
        self.assertEqual(data_inner2.value, 'value2')
        self.assertEqual(data_inner2.extracted, '2')
        self.assertEqual(data_inner2.errors, [])
Example #35
0
 def test_compound_blueprint_value_via_members(self):
     # Render Compound with values set via compound members
     compound = factory('compound', name='COMPOUND')
     compound['inner'] = factory('text', value='value1')
     compound['inner2'] = factory('error:text',
                                  value='value2',
                                  props={'required': True})
     self.check_output(
         """
     <div>
       <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner"
              type="text" value="value1"/>
       <input class="required text" id="input-COMPOUND-inner2"
              name="COMPOUND.inner2" required="required" type="text"
              value="value2"/>
     </div>
     """, fxml(tag('div', compound())))
Example #36
0
 def test_display_computed_bc_labels(self):
     widget = factory(
         'dict',
         name='display_dict',
         props={
             'head': {
                 'key': lambda w, d: 'Computed B/C Key',
                 'value': lambda w, d: 'Computed B/C Value',
             }
         },
         mode='display')
     self.check_output("""
     <div>
       <h5>Computed B/C Key: Computed B/C Value</h5>
       <dl/>
     </div>
     """, fxml('<div>{}</div>'.format(widget())))
Example #37
0
 def test_datetime_with_preset_value(self):
     # Test widget with given datetime value
     widget = factory(
         'datetime',
         name='dt',
         value=datetime.datetime(2011, 5, 1),
         props={
             'time': True,
         })
     self.check_output("""
     <div>
       <input class="dateinput datetime" id="input-dt" name="dt" size="10"
              type="text" value="2011.5.1"/>
       <input class="timeinput" id="input-dt-time" name="dt.time" size="5"
              type="text" value="00:00"/>
     </div>
     """, fxml('<div>{}</div>'.format(widget())))
Example #38
0
 def test_empty_dict(self):
     # Create empty Dict widget
     widget = factory(
         'dict',
         name='mydict',
         props={
             'key_label': 'Key',
             'value_label': 'Value',
         })
     result = widget()
     self.assertEqual(widget.treerepr().split('\n'), [
         "<class 'yafowil.base.Widget'>: mydict",
         "  <class 'yafowil.base.Widget'>: exists",
         "  <class 'yafowil.base.Widget'>: table",
         "    <class 'yafowil.base.Widget'>: head",
         "      <class 'yafowil.base.Widget'>: row",
         "        <class 'yafowil.base.Widget'>: key",
         "        <class 'yafowil.base.Widget'>: value",
         "        <class 'yafowil.base.Widget'>: actions",
         "    <class 'yafowil.base.Widget'>: body",
         ""
     ])
     self.check_output("""
     <div>
       <input class="hidden" id="input-mydict-exists"
              name="mydict.exists" type="hidden" value="1"/>
       <table class="dictwidget key-keyfield value-valuefield"
              id="dictwidget_mydict.entry">
         <thead>
           <tr>
             <th>Key</th>
             <th>Value</th>
             <th class="actions">
               <div class="dict_actions">
                 <a class="dict_row_add" href="#">
                   <span class="icon-plus-sign"> </span>
                 </a>
               </div>
             </th>
           </tr>
         </thead>
         <tbody/>
       </table>
     </div>
     """, fxml('<div>' + result + '</div>'))
Example #39
0
 def test_compound_blueprint_value_via_compound(self):
     # Render Compound with values set via compound widget
     value = {
         'inner': 'Value 1 from parent',
         'inner2': 'Value 2 from parent',
     }
     compound = factory('compound', name='COMPOUND', value=value)
     compound['inner'] = factory('text')
     compound['inner2'] = factory('text', props={'required': True})
     self.check_output(
         """
     <div>
       <input class="text" id="input-COMPOUND-inner" name="COMPOUND.inner"
              type="text" value="Value 1 from parent"/>
       <input class="required text" id="input-COMPOUND-inner2"
              name="COMPOUND.inner2" required="required" type="text"
              value="Value 2 from parent"/>
     </div>
     """, fxml(tag('div', compound())))
 def test_render_no_range_display_value(self):
     # Render no range, display value
     widget = factory(
         'slider',
         name='sliderfield',
         value=20,
         props={
             'show_value': True,
             'unit': 'Unit'
         })
     self.check_output("""
     <div class="yafowil_slider">
       <input class="slider_value" id="input-sliderfield" name="sliderfield"
              style="display:none;" type="text" value="20"/>
       <span class="unit">Unit: </span>
       <span class="slider_value">20</span>
       <div class="slider"> </div>
     </div>
     """, fxml(widget()))
Example #41
0
 def test_parse_from_yaml(self):
     template_path = os.path.join(self.tempdir, 'tmpl.yaml')
     with open(template_path, 'w') as file:
         file.write(self.yaml_tmpl)
     context = DummyContext()
     _ = lambda x, default=None: default and default or x
     form = parse_from_YAML(template_path, context, _)
     self.assertEqual(form.treerepr().split('\n'), [
         "<class 'yafowil.base.Widget'>: demoform",
         "  <class 'yafowil.base.Widget'>: firstfield",
         "  <class 'yafowil.base.Widget'>: secondfield", ""
     ])
     self.assertEqual(sorted(form.attrs.items()),
                      [('action', 'demoaction')])
     self.check_output(
         """
     <form action="demoaction" enctype="multipart/form-data"
           id="form-demoform" method="post" novalidate="novalidate">
       <div class="field" id="field-demoform-firstfield">
         <label for="input-demoform-firstfield">First Field</label>
         <input class="required text" id="input-demoform-firstfield"
                name="demoform.firstfield" required="required"
                type="text" value="First value"/>
       </div>
       <div class="field" id="field-demoform-secondfield">
         <label for="input-demoform-secondfield"
                title="Second Field">secondfield</label>
         <input id="exists-demoform-secondfield"
                name="demoform.secondfield-exists"
                type="hidden" value="exists"/>
         <select class="select" id="input-demoform-secondfield"
                 multiple="multiple" name="demoform.secondfield">
           <option id="input-demoform-secondfield-a"
                   selected="selected" value="a">a</option>
           <option id="input-demoform-secondfield-b"
                   selected="selected" value="b">b</option>
           <option id="input-demoform-secondfield-c"
                   value="c">c</option>
         </select>
       </div>
     </form>
     """, fxml(form()))
Example #42
0
 def test_yaml_form_compounds(self):
     raw = """
         factory: form
         name: demoform
         props:
             action: demoaction
         widgets:
         - sometable:
             factory: table
             props:
                 structural: True
             widgets:
             - row_1:
                 factory: tr
                 props:
                     structural: True
                 widgets:
                 - somefield:
                     factory: td:field:text
     """
     template_path = os.path.join(self.tempdir, 'tmpl.yaml')
     with open(template_path, 'w') as file:
         file.write(raw)
     context = DummyContext()
     form = YAMLParser(template_path, context=context)()
     self.check_output(
         """
     <form action="demoaction" enctype="multipart/form-data"
           id="form-demoform" method="post" novalidate="novalidate">
       <table>
         <tr>
           <td>
             <div class="field" id="field-demoform-somefield">
               <input class="text" id="input-demoform-somefield"
                      name="demoform.somefield" type="text" value=""/>
             </div>
           </td>
         </tr>
       </table>
     </form>
     """, fxml(form()))
Example #43
0
    def test_div_blueprint_compound(self):
        # Div blueprint as compound
        div = factory('div', name='DIV_COMPOUND')
        div['inner'] = factory('text', value='value1')
        div['inner2'] = factory('text',
                                value='value2',
                                props={'required': True})
        self.check_output(
            """
        <div>
          <input class="text" id="input-DIV_COMPOUND-inner"
                 name="DIV_COMPOUND.inner" type="text" value="value1"/>
          <input class="required text" id="input-DIV_COMPOUND-inner2"
                 name="DIV_COMPOUND.inner2" required="required" type="text"
                 value="value2"/>
        </div>
        """, fxml(div()))

        data = div.extract({
            'DIV_COMPOUND.inner': '1',
            'DIV_COMPOUND.inner2': '2',
        })
        self.assertEqual(data.name, 'DIV_COMPOUND')
        self.assertEqual(data.value, UNSET)
        expected = odict()
        expected['inner'] = '1'
        expected['inner2'] = '2'
        self.assertEqual(data.extracted, expected)
        self.assertEqual(data.errors, [])

        data_inner = data['inner']
        self.assertEqual(data_inner.name, 'inner')
        self.assertEqual(data_inner.value, 'value1')
        self.assertEqual(data_inner.extracted, '1')
        self.assertEqual(data_inner.errors, [])

        data_inner2 = data['inner2']
        self.assertEqual(data_inner2.name, 'inner2')
        self.assertEqual(data_inner2.value, 'value2')
        self.assertEqual(data_inner2.extracted, '2')
        self.assertEqual(data_inner2.errors, [])
Example #44
0
 def test_nested_form_single_field(self):
     # Create nested form, case single field
     main_path = os.path.join(self.tempdir, 'main.yaml')
     with open(main_path, 'w') as file:
         file.write(self.yaml_main_tmpl)
     nested_raw = """
         factory: text
         value: context.some_attr
         props:
             class_add: nested_input
     """
     nested_path = os.path.join(self.tempdir, 'sub.yaml')
     with open(nested_path, 'w') as file:
         file.write(nested_raw)
     context = DummyContext()
     form = YAMLParser(main_path, context=context)()
     self.check_output(
         """
     <form action="mainformaction" enctype="multipart/form-data"
           id="form-mainform" method="post" novalidate="novalidate">
       <input class="nested_input text" id="input-mainform-sub"
              name="mainform.sub" type="text" value="context.some_attr"/>
     </form>
     """, fxml(form()))
Example #45
0
    def test_controller(self):
        # Dummy context
        class Context(object):
            value = 'hello world'

        context = Context()

        # Dummy getter
        def getter(widget, data):
            return data.request.context.value

        # Create Widget tree
        form = factory(u'form',
                       name='testform',
                       props={'action': 'http://fubar.com'})
        form['field1'] = factory('text', value=getter)
        form['field2'] = factory('text', value='', props={'required': True})

        # Define action ``handler``
        def handler(widget, data):
            self.handler_result = 'handler called "%s"' % '.'.join(widget.path)

        # Define action ``next``
        def next(request):
            return 'next return value'

        # Indicate widget to be an ``action`` definition by setting ``action``
        # attribute to widget properties. ``expression``, ``handler`` and
        # ``next`` are action referring properties
        props = {
            'action': 'save',
            'expression': True,
            'handler': handler,
            'next': next,
            'label': 'Save',
            'skip': False,
        }

        # Add save action
        form['save'] = factory('submit', props=props)

        # Add cancel action. In this case we want the form processing to be
        # skipped and just the next action to be performed
        props = {
            'action': 'cancel',
            'expression': True,
            'handler': None,
            'next': next,
            'label': 'Cancel',
            'skip': True,
        }
        form['cancel'] = factory('submit', props=props)

        # Check widget tree
        self.assertEqual(form.treerepr().split('\n'), [
            "<class 'yafowil.base.Widget'>: testform",
            "  <class 'yafowil.base.Widget'>: field1",
            "  <class 'yafowil.base.Widget'>: field2",
            "  <class 'yafowil.base.Widget'>: save",
            "  <class 'yafowil.base.Widget'>: cancel", ""
        ])

        # Dummy request
        class Request(dict):
            context = None

        Request.context = context
        request = Request()

        # Render form with empty request
        data = form.extract(request)
        self.check_output(
            """
        <form action="http://fubar.com" enctype="multipart/form-data"
              id="form-testform" method="post" novalidate="novalidate">
          <input class="text" id="input-testform-field1" name="testform.field1"
                 type="text" value="hello world"/>
          <input class="required text" id="input-testform-field2"
                 name="testform.field2" required="required" type="text"
                 value=""/>
          <input id="input-testform-save" name="action.testform.save"
                 type="submit" value="Save"/>
          <input id="input-testform-cancel" name="action.testform.cancel"
                 type="submit" value="Cancel"/>
        </form>
        """, fxml(form(data)))

        # Create controller for form
        controller = Controller(form, request)

        # If action is not triggered, or ``action['next']`` is not set,
        # ``Controller.next`` is ``None``
        self.assertEqual(controller.next, None)

        # An empty request does not trigger validation failures
        self.assertFalse(controller.error)

        # Provide empty required field and it fails!
        request['testform.field2'] = ''
        controller = Controller(form, request)
        self.assertTrue(controller.error)

        # Provide required field and all is fine
        request['testform.field2'] = '1'
        controller = Controller(form, request)
        self.assertFalse(controller.error)

        # Trigger save action without required field
        request['testform.field2'] = ''
        request['action.testform.save'] = '1'
        controller = Controller(form, request)
        self.assertTrue(controller.error, True)
        self.assertTrue(controller.performed, True)

        # Trigger save action with valid input
        request['testform.field2'] = '1'
        controller = Controller(form, request)
        self.assertEqual(self.handler_result, 'handler called "testform"')
        self.handler_result = None
        self.assertEqual(controller.next, 'next return value')
        self.assertFalse(controller.error)
        self.assertTrue(controller.performed)

        # Render the form performed
        self.check_output(
            """
        <form action="http://fubar.com" enctype="multipart/form-data"
              id="form-testform" method="post" novalidate="novalidate">
          <input class="text" id="input-testform-field1" name="testform.field1"
                 type="text" value="hello world"/>
          <input class="required text" id="input-testform-field2"
                 name="testform.field2" required="required" type="text"
                 value="1"/>
          <input id="input-testform-save" name="action.testform.save"
                 type="submit" value="Save"/>
          <input id="input-testform-cancel" name="action.testform.cancel"
                 type="submit" value="Cancel"/>
        </form>
        """, fxml(controller.rendered))

        # Trigger cancel action. performing is skipped
        del request['action.testform.save']
        request['action.testform.cancel'] = '1'
        controller = Controller(form, request)
        self.assertEqual(controller.next, 'next return value')
        self.assertFalse(controller.performed)

        # Render form not performed
        self.check_output(
            """
        <form action="http://fubar.com" enctype="multipart/form-data"
              id="form-testform" method="post" novalidate="novalidate">
          <input class="text" id="input-testform-field1" name="testform.field1"
                 type="text" value="hello world"/>
          <input class="required text" id="input-testform-field2"
                 name="testform.field2" required="required" type="text"
                 value=""/>
          <input id="input-testform-save" name="action.testform.save"
                 type="submit" value="Save"/>
          <input id="input-testform-cancel" name="action.testform.cancel"
                 type="submit" value="Cancel"/>
        </form>
        """, fxml(controller.rendered))

        # Try recursive lookup of actions
        form = factory(u'form',
                       name='testform',
                       props={'action': 'http://fubar.com'})
        form['level1'] = factory('submit', props={'action': 'l1action'})
        form['fieldset'] = factory('fieldset')
        form['fieldset']['level2'] = factory('submit',
                                             props={'action': 'l2action'})
        form['fieldset']['subset'] = factory('fieldset')
        form['fieldset']['subset']['level3'] = factory(
            'submit', props={'action': 'l3action'})
        controller = Controller(form, {})
        self.assertEqual(len(controller.actions), 3)
        self.assertEqual(controller.actions[0].name, 'level1')
        self.assertEqual(controller.actions[1].name, 'level2')
        self.assertEqual(controller.actions[2].name, 'level3')
Example #46
0
    def test_form_blueprint(self):
        # Test Form
        form = factory('form',
                       name='FORM',
                       props={'action': 'http://fubar.com'})
        self.assertEqual(
            form(),
            ('<form action="http://fubar.com" enctype="multipart/form-data" '
             'id="form-FORM" method="post" novalidate="novalidate"></form>'))

        # Form action as callable
        def action(widget, data):
            return 'http://fubar.com'

        form = factory('form', name='FORM', props={'action': action})
        self.assertEqual(
            form(),
            ('<form action="http://fubar.com" enctype="multipart/form-data" '
             'id="form-FORM" method="post" novalidate="novalidate"></form>'))

        # Form display renderer
        form = factory('form',
                       name='FORM',
                       props={'action': 'http://fubar.com'},
                       mode='display')
        self.assertEqual(form(), '<div></div>')

        # Create a form with some children
        form = factory('form',
                       name='myform',
                       props={'action': 'http://www.domain.tld/someform'})
        form['someinput'] = factory('label:text', props={'label': 'Your Text'})

        self.form_data = None

        def formaction(widget, data):
            self.form_data = data

        def formnext(request):
            return 'http://www.domain.tld/result'

        form['submit'] = factory('submit',
                                 props={
                                     'handler': formaction,
                                     'next': formnext,
                                     'action': True
                                 })

        # Render an empty form
        self.check_output(
            """
        <form action="http://www.domain.tld/someform"
              enctype="multipart/form-data" id="form-myform" method="post"
              novalidate="novalidate">
          <label for="input-myform-someinput">Your Text</label>
          <input class="text" id="input-myform-someinput"
                 name="myform.someinput" type="text" value=""/>
          <input id="input-myform-submit" name="action.myform.submit"
                 type="submit" value="submit"/>
        </form>
        """, fxml(form()))

        # Get form data out of request (request is expected dict-like)
        request = {
            'myform.someinput': 'Hello World',
            'action.myform.submit': 'submit'
        }
        Controller(form, request)

        form_data = self.form_data
        self.assertEqual(form_data.name, 'myform')
        self.assertEqual(form_data.value, UNSET)
        expected = odict()
        expected['someinput'] = 'Hello World'
        expected['submit'] = UNSET
        self.assertEqual(form_data.extracted, expected)
        self.assertEqual(form_data.errors, [])

        input_data = form_data['someinput']
        self.assertEqual(input_data.name, 'someinput')
        self.assertEqual(input_data.value, UNSET)
        self.assertEqual(input_data.extracted, 'Hello World')
        self.assertEqual(input_data.errors, [])

        # submit blueprint gets a runtime data as well, but it's never needed
        # or used so far
        submit_data = form_data['submit']
        self.assertEqual(submit_data.name, 'submit')
        self.assertEqual(submit_data.value, UNSET)
        self.assertEqual(submit_data.extracted, UNSET)
        self.assertEqual(submit_data.errors, [])

        del self.form_data

        # Form action property can be callable
        def action(widget, data):
            return 'actionfromcall'

        form = factory('form', name='form', props={
            'action': action,
        })
        self.assertEqual(
            form(),
            ('<form action="actionfromcall" enctype="multipart/form-data" '
             'id="form-form" method="post" novalidate="novalidate"></form>'))

        # Create label for field in other compound
        form = factory('form', name='form', props={'action': 'action'})
        form['label'] = factory('label',
                                props={
                                    'label': 'Foo',
                                    'for': 'field'
                                })
        form['field'] = factory('text')
        self.check_output(
            """
        <form action="action" enctype="multipart/form-data" id="form-form"
              method="post" novalidate="novalidate">
          <label for="input-form-field">Foo</label>
          <input class="text" id="input-form-field" name="form.field"
                 type="text" value=""/>
        </form>
        """, fxml(form()))
Example #47
0
    def test_datetime_advanced(self):
        # Widget with more advanced configuration. Widget now renders time
        # input and input converting is locale aware. You can pass ``tzinfo``
        # property as well if you want the conversion to consider timezones
        widget = factory(
            'datetime',
            name='dt',
            props={
                'datepicker': True,
                'required': 'No date given',
                'delimiter': '.',
                'locale': 'de',
                'time': True,
                'timepicker': True,
                'tzinfo': None,
            })
        self.check_output("""
        <div>
          <input class="dateinput datepicker datetime required"
                 id="input-dt" name="dt" size="10" type="text" value=""/>
          <input class="timeinput timepicker" id="input-dt-time" name="dt.time"
                 size="5" type="text" value=""/>
        </div>
        """, fxml('<div>{}</div>'.format(widget())))

        # Widget extraction, no date input was given
        request = {'dt': '', 'dt.time': ''}
        data = widget.extract(request)
        self.assertEqual(
            [data.name, data.value, data.extracted, data.errors],
            ['dt', UNSET, '', [ExtractionError('No date given')]]
        )

        # Widget renders empty value
        self.check_output("""
        <div>
          <input class="dateinput datepicker datetime required" id="input-dt"
                 name="dt" size="10" type="text" value=""/>
          <input class="timeinput timepicker" id="input-dt-time" name="dt.time"
                 size="5" type="text" value=""/>
        </div>
        """, fxml('<div>{}</div>'.format(widget(data))))

        # Widget extraction with non-datetime input
        request = {'dt': 'xyz', 'dt.time': 'x'}
        data = widget.extract(request)
        self.assertEqual(
            [data.name, data.value, data.extracted, data.errors],
            ['dt', UNSET, 'xyz', [ExtractionError('Not a valid date input.')]]
        )
        self.check_output("""
        <div>
          <input class="dateinput datepicker datetime required" id="input-dt"
                 name="dt" size="10" type="text" value="xyz"/>
          <input class="timeinput timepicker" id="input-dt-time" name="dt.time"
                 size="5" type="text" value="x"/>
        </div>
        """, fxml('<div>{}</div>'.format(widget(data))))

        # Valid widget extraction. Returns datetime instance
        request = {'dt': '1.1.2010', 'dt.time': '10:15'}
        data = widget.extract(request)
        self.assertEqual(
            [data.name, data.value, data.extracted, data.errors],
            ['dt', UNSET, datetime.datetime(2010, 1, 1, 10, 15), []]
        )
        self.check_output("""
        <div>
          <input class="dateinput datepicker datetime required" id="input-dt"
                 name="dt" size="10" type="text" value="1.1.2010"/>
          <input class="timeinput timepicker" id="input-dt-time" name="dt.time"
                 size="5" type="text" value="10:15"/>
        </div>
        """, fxml('<div>{}</div>'.format(widget(data))))
Example #48
0
    def test_table_with_structural(self):
        # Build same table again but set some nodes structural. This is
        # considered in ``Widget.dottedpath``
        form = factory(
            'form',
            name='mytableform',
            props={
                'action': 'mytableaction',
            })
        form['table'] = factory(
            'table',
            props={
                'structural': True
            })
        form['table']['row1'] = factory(
            'tr',
            props={
                'structural': True
            })
        # note: td is used in a blueprint chain here
        form['table']['row1']['field1'] = factory(
            'td:error:text',
            props={
                'required': 'Field 1 is required',
            }
        )
        self.check_output("""
        <form action="mytableaction" enctype="multipart/form-data"
              id="form-mytableform" method="post" novalidate="novalidate">
          <table>
            <tr>
              <td>
                <input class="required text" id="input-mytableform-field1"
                       name="mytableform.field1" required="required"
                       type="text" value=""/>
              </td>
            </tr>
          </table>
        </form>
        """, fxml(form()))

        data = form.extract({})
        self.assertEqual(data.name, 'mytableform')
        self.assertEqual(data.value, UNSET)
        self.assertEqual(data.extracted, odict([('field1', UNSET)]))
        self.assertEqual(data.errors, [])

        field_data = data['field1']
        self.assertEqual(field_data.name, 'field1')
        self.assertEqual(field_data.value, UNSET)
        self.assertEqual(field_data.extracted, UNSET)
        self.assertEqual(field_data.errors, [])

        data = form.extract({'mytableform.field1': ''})
        self.assertEqual(data.name, 'mytableform')
        self.assertEqual(data.value, UNSET)
        self.assertEqual(data.extracted, odict([('field1', '')]))
        self.assertEqual(data.errors, [])
        self.assertTrue(data.has_errors)

        field_data = data['field1']
        self.assertEqual(field_data.name, 'field1')
        self.assertEqual(field_data.value, UNSET)
        self.assertEqual(field_data.extracted, '')
        self.assertEqual(field_data.errors, [
            ExtractionError('Field 1 is required')
        ])

        self.check_output("""
        <form action="mytableaction" enctype="multipart/form-data"
              id="form-mytableform" method="post" novalidate="novalidate">
          <table>
            <tr>
              <td>
                <div class="error">
                  <div class="errormessage">Field 1 is required</div>
                  <input class="required text" id="input-mytableform-field1"
                         name="mytableform.field1" required="required"
                         type="text" value=""/>
                </div>
              </td>
            </tr>
          </table>
        </form>
        """, fxml(form(data)))
Example #49
0
    def test_compound_blueprint_address_compound_value_parent(self):
        # Address different compounds with value on parent
        value = {
            'c1': {
                'f1': 'Foo',
            },
            'c2': {
                'f2': 'Bar',
                'f3': 'Baz',
            },
        }
        compound = factory('compound', 'comp', value=value)
        compound['c1'] = factory('compound')
        compound['c1']['f1'] = factory('text')
        compound['c2'] = factory('compound')
        compound['c2']['f2'] = factory('text')
        compound['c2']['f3'] = factory('text')
        compound['c3'] = factory('compound')
        compound['c3']['f4'] = factory('text')

        self.check_output(
            """
        <div>
          <input class="text" id="input-comp-c1-f1" name="comp.c1.f1"
                 type="text" value="Foo"/>
          <input class="text" id="input-comp-c2-f2" name="comp.c2.f2"
                 type="text" value="Bar"/>
          <input class="text" id="input-comp-c2-f3" name="comp.c2.f3"
                 type="text" value="Baz"/>
          <input class="text" id="input-comp-c3-f4" name="comp.c3.f4"
                 type="text" value=""/>
        </div>
        """, fxml(tag('div', compound())))

        self.assertEqual(compound.treerepr().split('\n'), [
            "<class 'yafowil.base.Widget'>: comp",
            "  <class 'yafowil.base.Widget'>: c1",
            "    <class 'yafowil.base.Widget'>: f1",
            "  <class 'yafowil.base.Widget'>: c2",
            "    <class 'yafowil.base.Widget'>: f2",
            "    <class 'yafowil.base.Widget'>: f3",
            "  <class 'yafowil.base.Widget'>: c3",
            "    <class 'yafowil.base.Widget'>: f4", ""
        ])

        data = compound.extract({
            'comp.c1.f1': 'Foo 1',
            'comp.c2.f2': 'Bar 2',
            'comp.c2.f3': 'Baz 1',
        })
        self.assertEqual(data.name, 'comp')
        self.assertEqual(data.value, {
            'c2': {
                'f2': 'Bar',
                'f3': 'Baz'
            },
            'c1': {
                'f1': 'Foo'
            }
        })
        expected = odict()
        expected['c1'] = odict()
        expected['c1']['f1'] = 'Foo 1'
        expected['c2'] = odict()
        expected['c2']['f2'] = 'Bar 2'
        expected['c2']['f3'] = 'Baz 1'
        expected['c3'] = odict()
        expected['c3']['f4'] = UNSET
        self.assertEqual(data.extracted, expected)
        self.assertEqual(data.errors, [])

        # c1
        data_c1 = data['c1']
        self.assertEqual(data_c1.name, 'c1')
        self.assertEqual(data_c1.value, {'f1': 'Foo'})
        expected = odict()
        expected['f1'] = 'Foo 1'
        self.assertEqual(data_c1.extracted, expected)
        self.assertEqual(data_c1.errors, [])

        data_f1 = data['c1']['f1']
        self.assertEqual(data_f1.name, 'f1')
        self.assertEqual(data_f1.value, 'Foo')
        self.assertEqual(data_f1.extracted, 'Foo 1')
        self.assertEqual(data_f1.errors, [])

        # c2
        data_c2 = data['c2']
        self.assertEqual(data_c2.name, 'c2')
        self.assertEqual(data_c2.value, {'f2': 'Bar', 'f3': 'Baz'})
        expected = odict()
        expected['f2'] = 'Bar 2'
        expected['f3'] = 'Baz 1'
        self.assertEqual(data_c2.extracted, expected)
        self.assertEqual(data_c2.errors, [])

        data_f2 = data['c2']['f2']
        self.assertEqual(data_f2.name, 'f2')
        self.assertEqual(data_f2.value, 'Bar')
        self.assertEqual(data_f2.extracted, 'Bar 2')
        self.assertEqual(data_f2.errors, [])

        data_f3 = data['c2']['f3']
        self.assertEqual(data_f3.name, 'f3')
        self.assertEqual(data_f3.value, 'Baz')
        self.assertEqual(data_f3.extracted, 'Baz 1')
        self.assertEqual(data_f3.errors, [])

        # c3
        data_c3 = data['c3']
        self.assertEqual(data_c3.name, 'c3')
        self.assertEqual(data_c3.value, UNSET)
        expected = odict()
        expected['f4'] = UNSET
        self.assertEqual(data_c3.extracted, expected)
        self.assertEqual(data_c3.errors, [])

        data_f4 = data['c3']['f4']
        self.assertEqual(data_f4.name, 'f4')
        self.assertEqual(data_f4.value, UNSET)
        self.assertEqual(data_f4.extracted, UNSET)
        self.assertEqual(data_f4.errors, [])
Example #50
0
    def test_table_with_compound_td(self):
        # Create table with 'td' as compound
        form = factory(
            'form',
            name='mytableform',
            props={
                'action': 'mytableaction',
            })
        form['table'] = factory(
            'table',
            props={
                'structural': True
            })
        form['table']['row1'] = factory(
            'tr',
            props={
                'structural': True
            })
        form['table']['row1']['td1'] = factory(
            'td',
            props={
                'structural': True
            })
        form['table']['row1']['td1']['field1'] = factory(
            'error:text',
            props={
                'required': 'Field 1 is required',
            }
        )
        self.check_output("""
        <form action="mytableaction" enctype="multipart/form-data"
              id="form-mytableform" method="post" novalidate="novalidate">
          <table>
            <tr>
              <td>
                <input class="required text" id="input-mytableform-field1"
                       name="mytableform.field1" required="required"
                       type="text" value=""/>
              </td>
            </tr>
          </table>
        </form>
        """, fxml(form()))

        data = form.extract({})
        self.assertEqual(data.name, 'mytableform')
        self.assertEqual(data.value, UNSET)
        self.assertEqual(data.extracted, odict([('field1', UNSET)]))
        self.assertEqual(data.errors, [])

        field_data = data['field1']
        self.assertEqual(field_data.name, 'field1')
        self.assertEqual(field_data.value, UNSET)
        self.assertEqual(field_data.extracted, UNSET)
        self.assertEqual(field_data.errors, [])

        data = form.extract({'mytableform.field1': ''})
        self.assertEqual(data.name, 'mytableform')
        self.assertEqual(data.value, UNSET)
        self.assertEqual(data.extracted, odict([('field1', '')]))
        self.assertEqual(data.errors, [])
        self.assertTrue(data.has_errors)

        field_data = data['field1']
        self.assertEqual(field_data.name, 'field1')
        self.assertEqual(field_data.value, UNSET)
        self.assertEqual(field_data.extracted, '')
        self.assertEqual(field_data.errors, [
            ExtractionError('Field 1 is required')
        ])

        self.check_output("""
        <form action="mytableaction" enctype="multipart/form-data"
              id="form-mytableform" method="post" novalidate="novalidate">
          <table>
            <tr>
              <td>
                <div class="error">
                  <div class="errormessage">Field 1 is required</div>
                  <input class="required text" id="input-mytableform-field1"
                         name="mytableform.field1" required="required"
                         type="text" value=""/>
                </div>
              </td>
            </tr>
          </table>
        </form>
        """, fxml(form(data)))
Example #51
0
    def test_compound_blueprint_compound_children(self):
        # Compound with compound as child
        value = {
            'CHILD_COMPOUND': {
                'inner': 'Value 1 from parent',
                'inner2': 'Value 2 from parent',
            }
        }
        compound = factory('compound', name='COMPOUND', value=value)
        child_compound = compound['CHILD_COMPOUND'] = factory('compound')
        child_compound['inner'] = factory('text')
        child_compound['inner2'] = factory('text', props={'required': True})
        self.check_output("""
        <div>
          <input class="text" id="input-COMPOUND-CHILD_COMPOUND-inner"
                 name="COMPOUND.CHILD_COMPOUND.inner" type="text"
                 value="Value 1 from parent"/>
          <input class="required text" id="input-COMPOUND-CHILD_COMPOUND-inner2"
                 name="COMPOUND.CHILD_COMPOUND.inner2" required="required"
                 type="text" value="Value 2 from parent"/>
        </div>
        """, fxml(tag('div', compound())))  # noqa

        self.assertEqual(compound.treerepr().split('\n'), [
            "<class 'yafowil.base.Widget'>: COMPOUND",
            "  <class 'yafowil.base.Widget'>: CHILD_COMPOUND",
            "    <class 'yafowil.base.Widget'>: inner",
            "    <class 'yafowil.base.Widget'>: inner2", ""
        ])

        data = compound.extract({
            'COMPOUND.CHILD_COMPOUND.inner': 'newvalue',
            'COMPOUND.CHILD_COMPOUND.inner2': 'newvalue2',
        })
        self.assertEqual(data.name, 'COMPOUND')
        self.assertEqual(
            data.value, {
                'CHILD_COMPOUND': {
                    'inner2': 'Value 2 from parent',
                    'inner': 'Value 1 from parent'
                }
            })
        expected = odict()
        expected['CHILD_COMPOUND'] = odict()
        expected['CHILD_COMPOUND']['inner'] = 'newvalue'
        expected['CHILD_COMPOUND']['inner2'] = 'newvalue2'
        self.assertEqual(data.extracted, expected)
        self.assertEqual(data.errors, [])

        data_compound = data['CHILD_COMPOUND']
        self.assertEqual(data_compound.name, 'CHILD_COMPOUND')
        self.assertEqual(data_compound.value, {
            'inner2': 'Value 2 from parent',
            'inner': 'Value 1 from parent'
        })
        expected = odict()
        expected['inner'] = 'newvalue'
        expected['inner2'] = 'newvalue2'
        self.assertEqual(data_compound.extracted, expected)
        self.assertEqual(data_compound.errors, [])

        data_inner = data['CHILD_COMPOUND']['inner']
        self.assertEqual(data_inner.name, 'inner')
        self.assertEqual(data_inner.value, 'Value 1 from parent')
        self.assertEqual(data_inner.extracted, 'newvalue')
        self.assertEqual(data_inner.errors, [])

        data_inner2 = data['CHILD_COMPOUND']['inner2']
        self.assertEqual(data_inner2.name, 'inner2')
        self.assertEqual(data_inner2.value, 'Value 2 from parent')
        self.assertEqual(data_inner2.extracted, 'newvalue2')
        self.assertEqual(data_inner2.errors, [])