require "minitest_helper" module Hermod describe XmlSection do StringXml = XmlSection.build do |builder| builder.string_node :greeting builder.string_node :name, optional: true builder.string_node :title, matches: /\ASir|Dame\z/, attributes: {masculine: "Male"} builder.string_node :required builder.string_node :gender, input_mutator: (lambda do |value, attributes| [value == "Male" ? "M" : "F", attributes] end) builder.string_node :status, input_mutator: (lambda do |value, attributes, instance| adjective = case instance.nodes[:mood].first.value when "Happy" "joyously" when "Sad" "dejectedly" when "Hangry" "furiously" end ["#{value} #{adjective}", attributes] end) builder.string_node :mood, allowed_values: %w(Happy Sad Hangry) end describe "String nodes" do subject do StringXml.new do |string_xml| string_xml.greeting "Hello" end end it "should set node contents correctly" do value_of_node("Greeting").must_equal "Hello" end it "should allow values that pass the regex validation" do subject.title "Sir" value_of_node("Title").must_equal "Sir" end it "should raise an error when the regex validation fails" do ex = proc { subject.title "Laird" }.must_raise InvalidInputError ex.message.must_equal %(title "Laird" does not match /\\ASir|Dame\\z/) end it "should require all non-optional nodes to have content" do ex = proc { subject.required "" }.must_raise InvalidInputError ex.message.must_equal "required isn't optional but no value was provided" end it "should apply changes to the inputs if a input_mutator is provided" do subject.gender "Male" value_of_node("Gender").must_equal "M" end it "should allow input_mutators to access nodes the instance" do subject.mood "Hangry" subject.status "Eating cookies" value_of_node("Status").must_equal "Eating cookies furiously" end it "should restrict values to those in the list of allowed values if such a list is provided" do subject.mood "Hangry" value_of_node("Mood").must_equal "Hangry" end it "should raise an error if the value is not in the list of allowed values" do ex = proc { subject.mood "Jubilant" }.must_raise InvalidInputError ex.message.must_equal "mood must be one of Happy, Sad, or Hangry, not Jubilant" end it "should use the given keys for attributes" do subject.title "Sir", masculine: "no" attributes_for_node("Title").keys.first.must_equal "Male" attributes_for_node("Title")["Male"].value.must_equal "no" end it "should raise an error if given an attribute that isn't expected" do proc { subject.title "Sir", knight: "yes" }.must_raise InvalidInputError end it "should not include empty, optional nodes" do subject.name "" nodes("Name").must_be_empty end end end end