require "spec_helper" describe Nori do describe "PARSERS" do it "should return a Hash of parser details" do expect(Nori::PARSERS).to eq({ :rexml => "REXML", :nokogiri => "Nokogiri" }) end end context ".new" do it "defaults to not strip any namespace identifiers" do xml = <<-XML a_case XML expect(nori.parse(xml)["history"]["ns10:case"]).to eq("a_case") end it "defaults to not change XML tags" do xml = 'active' expect(nori.parse(xml)).to eq({ "userResponse" => { "@id" => "1", "accountStatus" => "active" } }) end it "raises when passed unknown global options" do expect { Nori.new(:invalid => true) }. to raise_error(ArgumentError, /Spurious options: \[:invalid\]/) end end context ".new with :strip_namespaces" do it "strips the namespace identifiers when set to true" do xml = '' expect(nori(:strip_namespaces => true).parse(xml)).to have_key("Envelope") end it "still converts namespaced entries to array elements" do xml = <<-XML a_name another_name XML expected = [{ "name" => "a_name" }, { "name" => "another_name" }] expect(nori(:strip_namespaces => true).parse(xml)["history"]["case"]).to eq(expected) end end context ".new with :convert_tags_to" do it "converts all tags by a given formula" do xml = 'active' snakecase_symbols = lambda { |tag| tag.snakecase.to_sym } nori = nori(:convert_tags_to => snakecase_symbols) expect(nori.parse(xml)).to eq({ :user_response => { :@id => "1", :account_status => "active" } }) end end context '#find' do before do upcase = lambda { |tag| tag.upcase } @nori = nori(:convert_tags_to => upcase) xml = 'active' @hash = @nori.parse(xml) end it 'returns the Hash when the path is empty' do result = @nori.find(@hash) expect(result).to eq("USERRESPONSE" => { "ACCOUNTSTATUS" => "active", "@ID" => "1" }) end it 'returns the result for a single key' do result = @nori.find(@hash, 'userResponse') expect(result).to eq("ACCOUNTSTATUS" => "active", "@ID" => "1") end it 'returns the result for nested keys' do result = @nori.find(@hash, 'userResponse', 'accountStatus') expect(result).to eq("active") end it 'strips the namespaces from Hash keys' do xml = 'active' hash = @nori.parse(xml) result = @nori.find(hash, 'userResponse', 'accountStatus') expect(result).to eq("active") end end context "#parse" do it "defaults to use advanced typecasting" do hash = nori.parse("true") expect(hash["value"]).to eq(true) end it "defaults to use the Nokogiri parser" do # parsers are loaded lazily by default require "nori/parser/nokogiri" expect(Nori::Parser::Nokogiri).to receive(:parse).and_return({}) nori.parse("thing") end it "strips the XML" do xml = double("xml") expect(xml).to receive(:strip).and_return("thing") expect(nori.parse(xml)).to eq({ "any" => "thing" }) end end context "#parse without :advanced_typecasting" do it "can be changed to not typecast too much" do hash = nori(:advanced_typecasting => false).parse("true") expect(hash["value"]).to eq("true") end end context "#parse with :parser" do it "can be configured to use the REXML parser" do # parsers are loaded lazily by default require "nori/parser/rexml" expect(Nori::Parser::REXML).to receive(:parse).and_return({}) nori(:parser => :rexml).parse("thing") end end context "#parse without :delete_namespace_attributes" do it "can be changed to not delete xmlns attributes" do xml = 'active' hash = nori(:delete_namespace_attributes => false).parse(xml) expect(hash).to eq({"userResponse" => {"@xmlns" => "http://schema.company.com/some/path/to/namespace/v1", "accountStatus" => "active"}}) end it "can be changed to not delete xsi attributes" do xml = 'active' hash = nori(:delete_namespace_attributes => false).parse(xml) expect(hash).to eq({"userResponse" => {"@xsi" => "abc:myType", "accountStatus" => "active"}}) end end context "#parse with :delete_namespace_attributes" do it "can be changed to delete xmlns attributes" do xml = 'active' hash = nori(:delete_namespace_attributes => true).parse(xml) expect(hash).to eq({"userResponse" => {"accountStatus" => "active"}}) end it "can be changed to delete xsi attributes" do xml = 'active' hash = nori(:delete_namespace_attributes => true).parse(xml) expect(hash).to eq({"userResponse" => {"accountStatus" => "active"}}) end end context "#parse with :convert_dashes_to_underscores" do it "can be configured to skip dash to underscope conversion" do xml = 'foo bar false).parse(xml) expect(hash).to eq({'any-tag' => 'foo bar'}) end end context "#parse with :empty_tag_value set to empty string" do it "can be configured to convert empty tags to given value" do xml = "" hash = nori(:empty_tag_value => "").parse(xml) expect(hash).to eq("parentTag" => { "tag" => "" }) end end def nori(options = {}) Nori.new(options) end end