# coding: utf-8 require File.join(File.dirname(__FILE__), 'spec_helper') require 'date' require 'time' require 'nokogiri' describe RDF::Literal do describe "an untyped string" do subject {RDF::Literal.new("gregg")} it "should be equal if they have the same contents" do should == RDF::Literal.new("gregg") end it "should not be equal if they do not have the same contents" do should_not == RDF::Literal.new("tim") end it "should match a string" do should == "gregg" end it "should return a string using to_s" do subject.to_s.should == %("gregg") end describe "should handle specific cases" do { '"Gregg"' => RDF::Literal.new("Gregg"), '"\u677E\u672C \u540E\u5B50"' => RDF::Literal.new("松本 后子"), '"D\u00FCrst"' => RDF::Literal.new("Dürst"), }.each_pair do |encoded, literal| it "should encode '#{literal.value}'" do literal.to_s.should == encoded end end # Ruby 1.9 only { '"\U00015678another"' => RDF::Literal.new("\u{15678}another"), }.each_pair do |encoded, literal| it "should encode '#{literal.value}'" do literal.to_s.should == encoded end end if defined?(::Encoding) end describe "encodings" do it "should return n3" do subject.to_s.should == "\"gregg\"" end end describe "with extended characters" do subject { RDF::Literal.new("松本 后子") } describe "encodings" do it "should return n3" do subject.to_s.should == '"\u677E\u672C \u540E\u5B50"' end end end describe "with a language" do subject { RDF::Literal.new("gregg", :language => "en") } it "should accept a language tag" do subject.language.should == :en end it "should be equal if they have the same contents and language" do should == RDF::Literal.new("gregg", :language => "en") end it "should not be equal if they do not have the same contents" do should_not == RDF::Literal.new("tim", :language => "en") end it "should not be equal if they do not have the same language" do should_not == RDF::Literal.new("gregg", :language => "fr") end describe "encodings" do it "should return n3" do subject.to_s.should == "\"gregg\"@en" end end it "should normalize language tags to lower case" do f = RDF::Literal.new("gregg", :language => "EN") f.language.should == :en end end end describe "a typed string" do subject { RDF::Literal.new("gregg", :datatype => RDF::XSD.string) } it "accepts an encoding" do subject.datatype.to_s.should == RDF::XSD.string.to_s end it "should be equal if they have the same contents and datatype" do should == RDF::Literal.new("gregg", :datatype => RDF::XSD.string) end it "should not be equal if they do not have the same contents" do should_not == RDF::Literal.new("tim", :datatype => RDF::XSD.string) end it "should not be equal if they do not have the same datatype" do should_not == RDF::Literal.new("gregg", :datatype => RDF::XSD.token) end describe "encodings" do it "should return n3" do subject.to_s.should == "\"gregg\"^^<http://www.w3.org/2001/XMLSchema#string>" end end end describe "a boolean" do subject { RDF::Literal.new(true, :datatype => RDF::XSD.boolean) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"true\"^^<http://www.w3.org/2001/XMLSchema#boolean>" end end it "should infer type" do int = RDF::Literal.new(true) int.datatype.should == RDF::XSD.boolean end it "should have string contents" do subject.value.should == "true" end it "should have native contents" do subject.object.should == true end end describe "an integer" do subject { RDF::Literal.new(5, :datatype => RDF::XSD.int) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"5\"^^<http://www.w3.org/2001/XMLSchema#int>" end end it "should infer type" do int = RDF::Literal.new(15) int.datatype.should == RDF::XSD.integer end it "should have string contents" do subject.value.should == "5" end it "should have native contents" do subject.object.should == 5 end end describe "a float" do subject { RDF::Literal.new(15.4, :datatype => RDF::XSD.float) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"15.4\"^^<http://www.w3.org/2001/XMLSchema#float>" end end it "should infer type" do float = RDF::Literal.new(15.4) float.datatype.should == RDF::XSD.double end it "should have string contents" do subject.value.should == "15.4" end it "should have native contents" do subject.object.should == 15.4 end end describe "a date" do before(:each) { @value = Date.parse("2010-01-02Z") } subject { RDF::Literal.new(@value, :datatype => RDF::XSD.date) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"2010-01-02Z\"^^<http://www.w3.org/2001/XMLSchema#date>" end end it "should infer type" do int = RDF::Literal.new(@value) int.datatype.should == RDF::XSD.date end it "should have string contents" do subject.value.should == "2010-01-02Z" end it "should have native contents" do subject.object.should == @value end end describe "a dateTime" do before(:each) { @value = DateTime.parse('2010-01-03T01:02:03Z') } subject { RDF::Literal.new(@value, :datatype => RDF::XSD.dateTime) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"2010-01-03T01:02:03Z\"^^<http://www.w3.org/2001/XMLSchema#dateTime>" end end it "should infer type" do int = RDF::Literal.new(@value) int.datatype.should == RDF::XSD.dateTime end it "should have string contents" do subject.value.should == "2010-01-03T01:02:03Z" end it "should have native contents" do subject.object.should == @value end end describe "a time" do before(:each) { @value = Time.parse('01:02:03Z') } subject { RDF::Literal.new(@value, :datatype => RDF::XSD.time) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"01:02:03Z\"^^<http://www.w3.org/2001/XMLSchema#time>" end end it "should infer type" do int = RDF::Literal.new(@value) int.datatype.should == RDF::XSD.time end it "should have string contents" do subject.value.should == "01:02:03Z" end it "should have native contents" do subject.object.should == @value end end describe "XML Literal" do describe "with no namespace" do subject { RDF::Literal.new("foo <sup>bar</sup> baz!", :datatype => RDF.XMLLiteral) } it "should indicate xmlliteral?" do subject.xmlliteral?.should == true end describe "encodings" do it "should return n3" do subject.to_s.should == "\"foo <sup>bar</sup> baz!\"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>" end end it "should be equal if they have the same contents" do should == RDF::Literal.new("foo <sup>bar</sup> baz!", :datatype => RDF.XMLLiteral) end it "should be a XMLLiteral encoding" do subject.datatype.should == RDF.XMLLiteral end end describe "with a namespace" do subject { RDF::Literal.new("foo <sup>bar</sup> baz!", :datatype => RDF.XMLLiteral, :namespaces => {"dc" => RDF::DC.to_s}) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"foo <sup>bar</sup> baz!\"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>" end end describe "and language" do subject { RDF::Literal.new("foo <sup>bar</sup> baz!", :datatype => RDF.XMLLiteral, :namespaces => {"dc" => RDF::DC.to_s}, :language => :fr) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"foo <sup xml:lang=\\\"fr\\\">bar</sup> baz!\"\^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>" end end end describe "and language with an existing language embedded" do subject { RDF::Literal.new("foo <sup>bar</sup><sub xml:lang=\"en\">baz</sub>", :datatype => RDF.XMLLiteral, :language => :fr) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"foo <sup xml:lang=\\\"fr\\\">bar</sup><sub xml:lang=\\\"en\\\">baz</sub>\"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>" end end end describe "with a default namespace" do subject { RDF::Literal.new("foo <sup>bar</sup> baz!", :datatype => RDF.XMLLiteral, :namespaces => {"" => RDF::DC.to_s}) } describe "encodings" do it "should return n3" do subject.to_s.should == "\"foo <sup xmlns=\\\"http://purl.org/dc/terms/\\\">bar</sup> baz!\"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>" end end end describe "with multiple namespaces" do subject { RDF::Literal.new("foo <sup xmlns:dc=\"http://purl.org/dc/terms/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">bar</sup> baz!", :datatype => RDF.XMLLiteral) } it "should ignore namespace order" do g = RDF::Literal.new("foo <sup xmlns:dc=\"http://purl.org/dc/terms/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">bar</sup> baz!", :datatype => RDF.XMLLiteral) should == g end end end describe "an n3 literal" do { "Gregg" => 'Gregg', "Dürst" => 'D\u00FCrst', "simple literal" => 'simple literal', "backslash:\\" => 'backslash:\\\\', "dquote:\"" => 'dquote:\\"', "newline:\n" => 'newline:\\n', "return:\r" => 'return:\\r', "tab:\t" => 'tab:\\t', }.each_pair do |name, value| specify "test #{name}" do RDF::Literal.new(value.rdf_unescape).value.should == name end end end describe "valid content" do { "true" => %("true"^^<http://www.w3.org/2001/XMLSchema#boolean>), "false" => %("false"^^<http://www.w3.org/2001/XMLSchema#boolean>), "tRuE" => %("true"^^<http://www.w3.org/2001/XMLSchema#boolean>), "FaLsE" => %("false"^^<http://www.w3.org/2001/XMLSchema#boolean>), "1" => %("true"^^<http://www.w3.org/2001/XMLSchema#boolean>), "0" => %("false"^^<http://www.w3.org/2001/XMLSchema#boolean>), }.each_pair do |lit, n3| it "should validate boolean '#{lit}'" do RDF::Literal.new(lit, :datatype => RDF::XSD.boolean).valid?.should be_true end it "should normalize boolean '#{lit}'" do RDF::Literal.new(lit, :datatype => RDF::XSD.boolean).to_s.should == n3 end end { "01" => %("1"^^<http://www.w3.org/2001/XMLSchema#integer>), "1" => %("1"^^<http://www.w3.org/2001/XMLSchema#integer>), "-1" => %("-1"^^<http://www.w3.org/2001/XMLSchema#integer>), "+1" => %("1"^^<http://www.w3.org/2001/XMLSchema#integer>), }.each_pair do |lit, n3| it "should validate integer '#{lit}'" do RDF::Literal.new(lit, :datatype => RDF::XSD.integer).valid?.should be_true end it "should normalize integer '#{lit}'" do RDF::Literal.new(lit, :datatype => RDF::XSD.integer).to_s.should == n3 end end { "1" => %("1.0"^^<http://www.w3.org/2001/XMLSchema#decimal>), "-1" => %("-1.0"^^<http://www.w3.org/2001/XMLSchema#decimal>), "1." => %("1.0"^^<http://www.w3.org/2001/XMLSchema#decimal>), "1.0" => %("1.0"^^<http://www.w3.org/2001/XMLSchema#decimal>), "1.00" => %("1.0"^^<http://www.w3.org/2001/XMLSchema#decimal>), "+001.00" => %("1.0"^^<http://www.w3.org/2001/XMLSchema#decimal>), "123.456" => %("123.456"^^<http://www.w3.org/2001/XMLSchema#decimal>), "2.345" => %("2.345"^^<http://www.w3.org/2001/XMLSchema#decimal>), "1.000000000" => %("1.0"^^<http://www.w3.org/2001/XMLSchema#decimal>), "2.3" => %("2.3"^^<http://www.w3.org/2001/XMLSchema#decimal>), "2.234000005" => %("2.234000005"^^<http://www.w3.org/2001/XMLSchema#decimal>), "2.2340000000000005" => %("2.2340000000000005"^^<http://www.w3.org/2001/XMLSchema#decimal>), "2.23400000000000005" => %("2.234"^^<http://www.w3.org/2001/XMLSchema#decimal>), "2.23400000000000000000005" => %("2.234"^^<http://www.w3.org/2001/XMLSchema#decimal>), "1.2345678901234567890123457890" => %("1.2345678901234567"^^<http://www.w3.org/2001/XMLSchema#decimal>), }.each_pair do |lit, n3| it "should validate decimal '#{lit}'" do RDF::Literal.new(lit, :datatype => RDF::XSD.decimal).valid?.should be_true end it "should normalize decimal '#{lit}'" do RDF::Literal.new(lit, :datatype => RDF::XSD.decimal).to_s.should == n3 end end { "1" => %("1.0E0"^^<http://www.w3.org/2001/XMLSchema#double>), "-1" => %("-1.0E0"^^<http://www.w3.org/2001/XMLSchema#double>), "+01.000" => %("1.0E0"^^<http://www.w3.org/2001/XMLSchema#double>), "1." => %("1.0E0"^^<http://www.w3.org/2001/XMLSchema#double>), "1.0" => %("1.0E0"^^<http://www.w3.org/2001/XMLSchema#double>), "123.456" => %("1.23456E2"^^<http://www.w3.org/2001/XMLSchema#double>), "1.0e+1" => %("1.0E1"^^<http://www.w3.org/2001/XMLSchema#double>), "1.0e-10" => %("1.0E-10"^^<http://www.w3.org/2001/XMLSchema#double>), "123.456e4" => %("1.23456E6"^^<http://www.w3.org/2001/XMLSchema#double>), }.each_pair do |lit, n3| it "should validate double '#{lit}'" do RDF::Literal.new(lit, :datatype => RDF::XSD.double).valid?.should be_true end it "should normalize double '#{lit}'" do RDF::Literal.new(lit, :datatype => RDF::XSD.double).to_s.should == n3 end end end describe "invalid content" do [ RDF::Literal.new("foo", :datatype => RDF::XSD.boolean), RDF::Literal.new("xyz", :datatype => RDF::XSD.integer), RDF::Literal.new("12xyz", :datatype => RDF::XSD.integer), RDF::Literal.new("12.xyz", :datatype => RDF::XSD.decimal), RDF::Literal.new("xy.z", :datatype => RDF::XSD.double), RDF::Literal.new("+1.0z", :datatype => RDF::XSD.double), ].each do |lit| it "should detect invalid encoding for '#{lit.to_s}'" do lit.valid?.should be_false end end end end