# Copyright (c) 2004 Divmod.
# See LICENSE for details.
from zope.interface import implementer
from twisted.python import components
from nevow import tags
from nevow import inevow
from nevow import context
from nevow import util
import formless
from formless import webform
from formless import iformless
from formless import configurable
from nevow.test import test_flatstan
@implementer(iformless.IConfigurableFactory)
class Base(test_flatstan.Base):
synchronousLocateConfigurable = False
def locateConfigurable(self, *args, **kw):
r = iformless.IConfigurable(self.conf)
if not self.synchronousLocateConfigurable:
r = util.succeed(r)
return r
def setupContext(self, *args, **kw):
ctx = test_flatstan.Base.setupContext(self, *args, **kw)
return context.PageContext(tag=tags.html(), parent=ctx)
def render(self, tag, setupContext=lambda c:c):
return test_flatstan.Base.render(
self, tag, setupContext=setupContext,
wantDeferred=True)
def renderForms(self, configurable, ctx=None, *args, **kwargs):
self.conf = configurable
if ctx is None:
ctx = self.setupContext(False)
ctx.remember(self, iformless.IConfigurableFactory)
return self.render(
webform.renderForms(*args, **kwargs),
setupContext=lambda c: ctx)
def postForm(self, ctx, obj, bindingName, args):
self.conf = obj
ctx.remember(self, iformless.IConfigurableFactory)
def trapValidate(f):
f.trap(formless.ValidateError)
e = f.value
errors = ctx.locate(iformless.IFormErrors)
## Set the overall error for this form
errors.setError(bindingName, e.formErrorMessage)
errors.updateErrors(bindingName, e.errors)
ctx.locate(iformless.IFormDefaults).getAllDefaults(bindingName).update(e.partialForm)
return util.maybeDeferred(self.locateConfigurable,obj).addCallback(lambda x: x.postForm(
ctx, bindingName, args
)).addErrback(trapValidate)
class Complete(Base):
def test_configureProperty(self):
class IStupid(formless.TypedInterface):
foo = formless.String()
@implementer(IStupid)
class StupidThing(configurable.Configurable):
def __init__(self):
configurable.Configurable.__init__(self, None)
self.foo = 'foo'
dumb = StupidThing()
def doasserts(val):
self.assertSubstring('freeform_post!!foo', val)
self.assertSubstring('foo', val)
self.assertSubstring('type="text"', val)
self.assertSubstring('', val)
self.failIfSubstring('', val)
self.assertIn('accept-charset="utf-8"', val)
return self.renderForms(impl, ctx).addCallback(later)
def test_group(self):
class ITest(formless.TypedInterface):
class Group(formless.TypedInterface):
foo = formless.String()
@implementer(ITest)
class Impl:
pass
impl = Impl()
ctx = self.setupContext()
def later(val):
self.assertIn('', val)
self.assertIn('accept-charset="utf-8"', val)
return self.renderForms(impl, ctx).addCallback(later)
def test_method(self):
class ITest(formless.TypedInterface):
def foo(foo = formless.String()):
pass
foo = formless.autocallable(foo)
@implementer(ITest)
class Impl:
pass
impl = Impl()
ctx = self.setupContext()
def later(val):
self.assertIn('', val)
self.assertIn('accept-charset="utf-8"', val)
return self.renderForms(impl, ctx).addCallback(later)
class TestUnicode(Base):
def test_property(self):
class IThing(formless.TypedInterface):
aString = formless.String(str=True)
@implementer(IThing)
class Impl(object):
aString = None
inst = Impl()
ctx = self.setupContext()
D = self.postForm(ctx, inst, 'aString', {'aString':['\xc2\xa3']})
return D.addCallback(lambda result: self.assertEqual(inst.aString, '\xa3'))
class TestChoice(Base):
"""Test various behaviors of submitting values to a Choice Typed.
"""
def test_reject_missing(self):
# Ensure that if a Choice is not specified, the form is not submitted.
self.called = []
class IFormyThing(formless.TypedInterface):
def choiceyFunc(arg = formless.Choice(["one", "two"], required=True)):
pass
choiceyFunc = formless.autocallable(choiceyFunc)
@implementer(IFormyThing)
class Impl(object):
pass
def choiceyFunc(innerSelf, arg):
self.called.append(arg)
inst = Impl()
ctx = self.setupContext()
D = self.postForm(ctx, inst, 'choiceyFunc', {})
return D.addCallback(lambda result: self.assertEqual(self.called, []))
class mg(Base):
def test_leakyForms(self):
class ITest(formless.TypedInterface):
"""Test that a property value on one form does not 'leak' into
a property of the same name on another form.
"""
foo = formless.String()
def meth(foo = formless.String()):
pass
meth = formless.autocallable(meth)
@implementer(ITest)
class Impl:
foo = 'fooFOOfoo'
impl = Impl()
ctx = self.setupContext()
def later(val):
self.assertEqual(val.count('fooFOOfoo'), 1)
return self.renderForms(impl, ctx)
# What the *hell* is this?!?
#DeferredTestCases = type(Base)(
# 'DeferredTestCases',
# tuple([v for v in locals().values()
# if isinstance(v, type(Base)) and issubclass(v, Base)]),
# {'synchronousLocateConfigurable': True})