Skip to content

Commit

Permalink
added empty option. Fixed a few conversion related bugs. added variou…
Browse files Browse the repository at this point in the history
…s scripts to help run tests
  • Loading branch information
Tim Parkin committed Jan 17, 2009
1 parent 5c95ebd commit 0475450
Show file tree
Hide file tree
Showing 20 changed files with 255 additions and 65 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG
Expand Up @@ -2,6 +2,16 @@
Changlelog
==========


0.6.1 (2009-01-17)
----------------

* Added the 'empty' attribute to allow empty values to come back as anything you like (normally they return None)
* Reviewed the way conversion works and added extra tests.. picked up on a couple of edge cases

BUG FIX: bugs in the conversion of none_option values


0.6 (2009-01-16)
----------------

Expand Down
9 changes: 6 additions & 3 deletions docs-build/introduction.rst
Expand Up @@ -251,11 +251,11 @@ You can see from the example that the main conversion process is done using ``st
def from_type(self, value, converter_options={}):
if value is None:
return None
return ''
return str(value)
def to_type(self, value, converter_options={}):
if value is None:
if value == '':
return None
value = value.strip()
try:
Expand All @@ -264,7 +264,7 @@ You can see from the example that the main conversion process is done using ``st
raise ConvertError("Not a valid number")
return value
So we short circuit None values, strip the data and cast it to the right type and raise a conversion exception if it fails.
So we short circuit None values [#f1]_, strip the data and cast it to the right type and raise a conversion exception if it fails.

The widget templates
--------------------
Expand Down Expand Up @@ -659,4 +659,7 @@ Other goals..



.. rubric:: Footnotes

.. [#f1] By default the formish widgets equate the empty string with None. This means if you put a default value of '' into a form, you will get None back. If you want to override this behaviour, set the ``empty`` widget attribute to something else (e.g. for a date field you might set the widget value to ``datetime.date.today()``
9 changes: 6 additions & 3 deletions docs/html/_sources/introduction.txt
Expand Up @@ -251,11 +251,11 @@ You can see from the example that the main conversion process is done using ``st

def from_type(self, value, converter_options={}):
if value is None:
return None
return ''
return str(value)

def to_type(self, value, converter_options={}):
if value is None:
if value == '':
return None
value = value.strip()
try:
Expand All @@ -264,7 +264,7 @@ You can see from the example that the main conversion process is done using ``st
raise ConvertError("Not a valid number")
return value

So we short circuit None values, strip the data and cast it to the right type and raise a conversion exception if it fails.
So we short circuit None values [#f1]_, strip the data and cast it to the right type and raise a conversion exception if it fails.

The widget templates
--------------------
Expand Down Expand Up @@ -659,4 +659,7 @@ Other goals..



.. rubric:: Footnotes

.. [#f1] By default the formish widgets equate the empty string with None. This means if you put a default value of '' into a form, you will get None back. If you want to override this behaviour, set the ``empty`` widget attribute to something else (e.g. for a date field you might set the widget value to ``datetime.date.today()``

13 changes: 10 additions & 3 deletions docs/html/introduction.html
Expand Up @@ -276,11 +276,11 @@ <h2>Convertish<a class="headerlink" href="#convertish" title="Permalink to this

<span class="k">def</span> <span class="nf">from_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">converter_options</span><span class="o">=</span><span class="p">{}):</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="k">return</span> <span class="s">&#39;&#39;</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">to_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">converter_options</span><span class="o">=</span><span class="p">{}):</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="s">&#39;&#39;</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">None</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
Expand All @@ -290,7 +290,7 @@ <h2>Convertish<a class="headerlink" href="#convertish" title="Permalink to this
<span class="k">return</span> <span class="n">value</span>
</pre></div>
</div>
<p>So we short circuit None values, strip the data and cast it to the right type and raise a conversion exception if it fails.</p>
<p>So we short circuit None values <a class="footnote-reference" href="#f1" id="id2">[1]</a>, strip the data and cast it to the right type and raise a conversion exception if it fails.</p>
</div>
<div class="section" id="the-widget-templates">
<h2>The widget templates<a class="headerlink" href="#the-widget-templates" title="Permalink to this headline"></a></h2>
Expand Down Expand Up @@ -610,6 +610,13 @@ <h2>The way forward<a class="headerlink" href="#the-way-forward" title="Permalin
<p class="first admonition-title">Note</p>
<p class="last">Please send any feedback to <a class="reference external" href="mailto:developers&#37;&#52;&#48;ish&#46;io">developers<span>&#64;</span>ish<span>&#46;</span>io</a></p>
</div>
<p class="rubric">Footnotes</p>
<table class="docutils footnote" frame="void" id="f1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[1]</a></td><td>By default the formish widgets equate the empty string with None. This means if you put a default value of &#8216;&#8217; into a form, you will get None back. If you want to override this behaviour, set the <tt class="docutils literal"><span class="pre">empty</span></tt> widget attribute to something else (e.g. for a date field you might set the widget value to <tt class="docutils literal"><span class="pre">datetime.date.today()</span></tt></td></tr>
</tbody>
</table>
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion docs/html/searchindex.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions formish.egg-info/SOURCES.txt
Expand Up @@ -10,6 +10,7 @@ TODO
functests
nose.sh
release.sh
run
setup.py
unittests
docs-build/Makefile
Expand Down
@@ -1,7 +1,7 @@
<%page args="field" />
<select id="${field.cssname}" name="${field.name}">
%if field.widget.none_option:
<option value="${field.widget.get_none_option(field.attr)[0]}">${field.widget.none_option[1]}</option>
<option value="${field.widget.get_none_option_value(field.attr)}">${field.widget.none_option[1]}</option>
%endif
%for option in field.widget.get_options(field.attr):
<option value="${option[0]}" ${field.widget.selected(option,field.value[0], field.attr)|n}>${option[1]}</option>
Expand Down
15 changes: 14 additions & 1 deletion formish/tests/testish/functest
@@ -1,2 +1,15 @@
# requires selenium
nosetests testish/lib/test_func.py:TestTogether
case "$1" in
one)
./run nosetests testish/lib/test_func.py:TestSeparately.test_$2
--daemon \
--pid-file=$GITDIR/formish/formish/tests/testish/log/live.pid \
--log-file=$GITDIR/formish/formish/tests/testish/log/live.log \
$GITDIR/formish/formish/tests/testish/live.ini \
start
;;
*)
./run nosetests testish/lib/test_func.py:TestTogether
;;
esac

2 changes: 1 addition & 1 deletion formish/tests/testish/run
Expand Up @@ -4,6 +4,6 @@ import os, sys, subprocess

args = sys.argv[1:]
env = dict(os.environ)
env['PYTHONPATH'] = '../../../../../git/restish:../../../../../git/schemaish:../../../../../git/formish:../../../../../git/secret:../../../../../git/notification:../../../../../git/pollen:../../../../../git/formishbuilder:../../../../../git/validatish:../../../../../git/convertish:../../../../../git/clevercss:../../../../../git/wsgiapptools'
env['PYTHONPATH'] = '../../../../../git/restish:../../../../../git/schemaish:../../../../../git/formish:../../../../../git/validatish:../../../../../git/convertish'
subprocess.call(args, env=env)

1 change: 0 additions & 1 deletion formish/tests/testish/run.sh

This file was deleted.

1 change: 0 additions & 1 deletion formish/tests/testish/serve.sh
Expand Up @@ -56,7 +56,6 @@ case "$1" in
;;
run-dev)
./run /home/tim/py/bin/paster serve --reload \
--log-file=$GITDIR/formish/formish/tests/testish/log/development.log \
$GITDIR/formish/formish/tests/testish/development.ini
;;
*)
Expand Down
114 changes: 114 additions & 0 deletions formish/tests/testish/testish/lib/forms.py
Expand Up @@ -84,6 +84,29 @@ def unittest_String(self):#{{{
self.assertIdHasValue(f, 'form-myStringField', '8')
self.assertRoundTrip(f, testdata)#}}}

def StringDifferentEmpty(request):
"""
Simple field but making an empty value equal the empty string (instead of None)
"""
schema = schemaish.Structure()
schema.add('myStringField', schemaish.String())
form = formish.Form(schema, 'form')
form['myStringField'].widget = formish.Input(empty='')
return form

def unittest_StringDifferentEmpty(self):#{{{
# Test None data
f = StringDifferentEmpty(None)
testdata = {'myStringField': ''}
f.defaults = testdata
self.assertIdHasValue(f, 'form-myStringField', '')
self.assertRoundTrip(f, testdata)
# Test sample data
f = String(None)
testdata = {'myStringField': '8'}
f.defaults = testdata
self.assertIdHasValue(f, 'form-myStringField', '8')
self.assertRoundTrip(f, testdata)#}}}

def Integer(request):
"""
Expand Down Expand Up @@ -140,6 +163,16 @@ def unittest_Integer(self):#{{{
self.assertIdHasValue(f, 'form-myIntegerField', '8')
self.assertRoundTrip(f, testdata)#}}}

def IntegerNoneDefault(request):
"""
An integer field defaulting to None
"""
schema = schemaish.Structure()
schema.add('myIntegerField', schemaish.Integer())
form = formish.Form(schema, 'form')
form.defaults = {'myIntegerField':None}
return form

def Date(request):
"""
A simple form with a single integer field
Expand Down Expand Up @@ -179,6 +212,26 @@ def functest_Date(self):#{{{

return#}}}

def DateDifferentEmpty(request):
"""
A simple date field but with the empty value set to todays date
"""
schema = schemaish.Structure()
schema.add('myDateField', schemaish.Date())
form = formish.Form(schema, 'form')
import datetime
form['myDateField'].widget = formish.Input(empty=datetime.date.today())
return form

def unittest_DateDifferentEmpty(self):#{{{
# Test None data
f = DateDifferentEmpty(None)
testdata = {'myDateField': ''}
f.defaults = testdata
self.assertIdHasValue(f, 'form-myStringField', '')
expected = {'myDateField': datetime.date.today()}
self.assertRoundTrip(f, expected)

def Float(request):
"""
A simple form with a single integer field
Expand Down Expand Up @@ -841,6 +894,67 @@ def RadioChoiceNoneOption(request):
form['myRadio'].widget = formish.RadioChoice(options,none_option=(None, '--select--'))
return form

def unittest_RadioChoiceNoneOption(self):#{{{
# Test no data
f = RadioChoiceNoneOption(None)
self.assertIdHasValue(f, 'form-myRadio-noneoption', '')
# Test None data
f = RadioChoiceNoneOption(None)
testdata = {'myRadio': None}
f.defaults = testdata
self.assertIdAttrHasNoValue(f, 'form-myRadio-noneoption','selected')
self.assertIdAttrHasNoValue(f, 'form-myRadio-0','selected')
self.assertIdAttrHasNoValue(f, 'form-myRadio-1','selected')
self.assertIdAttrHasNoValue(f, 'form-myRadio-2','selected')
self.assertRoundTrip(f, testdata)#}}}

def functest_RadioChoiceNoneOption(self):#{{{
sel = self.selenium
sel.open("/RadioChoiceNoneOption")

sel.click("form-action-submit")
sel.wait_for_page_to_load("30000")
try: self.failUnless(sel.is_text_present("{'myRadio': None}"))
except AssertionError, e: self.verificationErrors.append(str(e))
sel.click("form-myRadio-noneoption")
sel.click("form-action-submit")
sel.wait_for_page_to_load("30000")
try: self.failUnless(sel.is_text_present("{'myRadio': None}"))
except AssertionError, e: self.verificationErrors.append(str(e))
sel.click("form-myRadio-0")
sel.click("form-action-submit")
sel.wait_for_page_to_load("30000")
try: self.failUnless(sel.is_text_present("{'myRadio': 1}"))
except AssertionError, e: self.verificationErrors.append(str(e))

return#}}}

def RadioChoiceNoneOptionNoneDefault(request):
"""
Setting a None Option on the select choice element - default value of None
"""
schema = schemaish.Structure()
schema.add('myRadio', schemaish.Integer())
options = [(1,'a'),(2,'b'),(3,'c')]

form = formish.Form(schema, 'form')
form.defaults = {'myRadio':None}
form['myRadio'].widget = formish.RadioChoice(options,none_option=(None, '--select--'))
return form

def RadioChoiceNoneOptionWithDefault(request):
"""
Setting a None Option on the select choice element - default value of 1
"""
schema = schemaish.Structure()
schema.add('myRadio', schemaish.Integer())
options = [(1,'a'),(2,'b'),(3,'c')]

form = formish.Form(schema, 'form')
form.defaults = {'myRadio':1}
form['myRadio'].widget = formish.RadioChoice(options,none_option=(None, '--select--'))
return form

def RadioChoiceCallableOptions(request):
"""
Passing in a callable list of options
Expand Down
9 changes: 9 additions & 0 deletions formish/tests/testish/testish/lib/test_unittests.py
Expand Up @@ -38,7 +38,16 @@ def assertIdHasValue(self, f, id, v):
soup = BeautifulSoup(f())
self.assertEquals(soup.find(id=id)['value'],v)

def assertIdAttrHasValue(self, f, id, attr, v):
soup = BeautifulSoup(f())
s = soup.find(id=id)
assert 'attr' in s
self.assertEquals(s['attr'],v)

def assertIdAttrHasNoValue(self, f, id, attr):
soup = BeautifulSoup(f())
s = soup.find(id=id)
assert 'attr' not in s


if __name__ == '__main__':
Expand Down
14 changes: 13 additions & 1 deletion formish/tests/testish/testish/templates/root.html
Expand Up @@ -12,6 +12,12 @@ <h3>Simple Fields</h3>
links(ids)
%>

<h3>Simple Fields with some options</h3>
<%
ids = ['StringDifferentEmpty','DateDifferentEmpty']
links(ids)
%>

<h3>File Fields</h3>
<%
ids = ['File']
Expand All @@ -24,6 +30,12 @@ <h3>Simple Widgets</h3>
links(ids)
%>

<h3>Default Values</h3>
<%
ids = ['IntegerNoneDefault']
links(ids)
%>

<h3>Checkbox Widgets</h3>
<%
ids = ['Checkbox']
Expand All @@ -40,7 +52,7 @@ <h3>Validation Examples</h3>

<h3>Select Widgets</h3>
<%
ids = ['SelectChoice','SelectChoiceNoneOption','SelectChoiceCallableOptions','SelectWithOtherChoice','RadioChoice','RadioChoiceNoneOption','RadioChoiceCallableOptions']
ids = ['SelectChoice','SelectChoiceNoneOption','SelectChoiceCallableOptions','SelectWithOtherChoice','RadioChoice','RadioChoiceNoneOption','RadioChoiceNoneOptionNoneDefault','RadioChoiceCallableOptions']
links(ids)
%>

Expand Down
2 changes: 1 addition & 1 deletion formish/tests/testish/unittest
@@ -1 +1 @@
nosetests testish/lib/test_unittests.py
./run nosetests testish/lib/test_unittests.py -d

0 comments on commit 0475450

Please sign in to comment.