What is the correct way to manually raise a deform.exception.ValidationFailure from a view, to set a particular field as having an invalid value? I don't want to create a custom validator because there are many situations where you want the application logic to be in the view not in a form validation function.
I can set up the errors directly on the form itself, which gets the error messages to render to the form html.
form.error = colander.Invalid(None, 'Error message on form')
form['some_field'].error = colander.Invalid(None, 'Error message on field')
raise deform.exception.ValidationFailure(form, None, form.error)
But the problem is that I can't unit test this manually-thrown ValidationFailure in the same way as the ones thrown by deform. In other situations I can make assertions like the following
assert len(e.error.children) == 1
assert e.error.children[0].asdict()['some_field'] == 'Error message on field'
But in the above case 'e.error.children' is an empty list. How do I raise the ValidationFailure consistently with ones thrown by deform?
I can do it like the following, and everything gets set up identical to when deform does it (including populating the 'pos' attribute on colander.Invalid. However, now the errors aren't getting rendered to the form html.
e = colander.Invalid(form.schema, 'Error message on form')
e['some_field'] = 'Error message on field'
raise deform.exception.ValidationFailure(form, None, e)
The only way I can get it to work is like the following, now the object gets created correctly and it renders properly on the page. Here I am assigning the Invalid errors to the schema then re-assigning them to the correct place in the form. But this is not DRY and seems quite hack-ish. (Especially the 4th line, were I can't retrieve the created child Invalid by doing e.children['some_field'] but have to get it using the numerical index.) This tells me I'm probably not raising this ValidationFailure properly.
What is the correct way to be doing this in a DRY way?
e = colander.Invalid(form.schema, 'Error message on form')
e['some_field'] = 'Error message on field'
form.error = e
form['some_field'].error = e.children[0]
raise deform.exception.ValidationFailure(form, None, form.error)