@@ 48,8 48,30 @@ class FormTemplate
@__form.instructions = s
end
- def field(**kwargs)
- @__form.fields = @__form.fields + [kwargs]
+ def validate(f, datatype: nil, **kwargs)
+ Nokogiri::XML::Builder.with(f) do |x|
+ x.validate(
+ xmlns: "http://jabber.org/protocol/xdata-validate",
+ datatype: datatype || "xs:string"
+ ) do
+ x.basic unless validation_type(x, **kwargs)
+ end
+ end
+ end
+
+ def validation_type(x, open: false, regex: nil, range: nil)
+ x.open if open
+ x.range(min: range.first, max: range.last) if range
+ x.regex(regex.source) if regex
+ open || regex || range
+ end
+
+ def field(datatype: nil, open: false, regex: nil, range: nil, **kwargs)
+ f = Blather::Stanza::X::Field.new(kwargs)
+ if datatype || open || regex || range
+ validate(f, datatype: datatype, open: open, regex: regex, range: range)
+ end
+ @__form.fields += [f]
end
def xml
@@ 46,6 46,74 @@ class FormTemplateTest < Minitest::Test
assert_equal "INSTRUCTIONS", form.instructions
end
+ def test_form_validate_basic
+ template = FormTemplate.new(<<~TEMPLATE)
+ form!
+ field(var: "thevar", label: "thelabel", datatype: "xs:integer")
+ TEMPLATE
+ form = template.render
+ assert_equal 1, form.fields.length
+ assert_equal "thevar", form.fields[0].var
+ assert_equal "thelabel", form.fields[0].label
+ validate = form.fields[0].find(
+ "ns:validate",
+ ns: "http://jabber.org/protocol/xdata-validate"
+ ).first
+ assert_equal "xs:integer", validate[:datatype]
+ assert_equal "basic", validate.children.first.name
+ end
+
+ def test_form_validate_open
+ template = FormTemplate.new(<<~TEMPLATE)
+ form!
+ field(var: "thevar", label: "thelabel", open: true)
+ TEMPLATE
+ form = template.render
+ assert_equal 1, form.fields.length
+ assert_equal "thevar", form.fields[0].var
+ assert_equal "thelabel", form.fields[0].label
+ validate = form.fields[0].find(
+ "ns:validate",
+ ns: "http://jabber.org/protocol/xdata-validate"
+ ).first
+ assert_equal ["open"], validate.children.map(&:name)
+ end
+
+ def test_form_validate_regex
+ template = FormTemplate.new(<<~TEMPLATE)
+ form!
+ field(var: "thevar", label: "thelabel", regex: /[A-Z]/)
+ TEMPLATE
+ form = template.render
+ assert_equal 1, form.fields.length
+ assert_equal "thevar", form.fields[0].var
+ assert_equal "thelabel", form.fields[0].label
+ validate = form.fields[0].find(
+ "ns:validate",
+ ns: "http://jabber.org/protocol/xdata-validate"
+ ).first
+ assert_equal ["regex"], validate.children.map(&:name)
+ assert_equal "[A-Z]", validate.children.first.content
+ end
+
+ def test_form_validate_range
+ template = FormTemplate.new(<<~TEMPLATE)
+ form!
+ field(var: "thevar", label: "thelabel", range: (10..22))
+ TEMPLATE
+ form = template.render
+ assert_equal 1, form.fields.length
+ assert_equal "thevar", form.fields[0].var
+ assert_equal "thelabel", form.fields[0].label
+ validate = form.fields[0].find(
+ "ns:validate",
+ ns: "http://jabber.org/protocol/xdata-validate"
+ ).first
+ assert_equal ["range"], validate.children.map(&:name)
+ assert_equal "10", validate.children.first[:min]
+ assert_equal "22", validate.children.first[:max]
+ end
+
def test_no_type
template = FormTemplate.new(<<~TEMPLATE)
title "TITLE"