# Copyright (c) 2004 Divmod. # See LICENSE for details. from zope.interface import implements 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 class Base(test_flatstan.Base): implements(iformless.IConfigurableFactory) 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() class StupidThing(configurable.Configurable): implements(IStupid) 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() class Impl: implements(ITest) 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) class Impl: implements(ITest) 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(unicode=True) class Impl(object): implements(IThing) aString = None inst = Impl() ctx = self.setupContext() D = self.postForm(ctx, inst, 'aString', {'aString':['\xc2\xa3']}) return D.addCallback(lambda result: self.assertEquals(inst.aString, u'\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) class Impl(object): implements(IFormyThing) 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.assertEquals(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) class Impl: implements(ITest) foo = 'fooFOOfoo' impl = Impl() ctx = self.setupContext() def later(val): self.assertEquals(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})