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