# coding: utf-8
require 'rdf'
require 'rdf/spec'
share_as :RDF_Literal do
XSD = RDF::XSD
before :each do
raise '+@new+ must be defined in a before(:each) block' unless instance_variable_get('@new')
end
context "plain literals" do
before :each do
@empty = @new.call('')
@hello = @new.call('Hello')
@all = [@empty, @hello]
end
it "should be instantiable" do
lambda { @new.call('') }.should_not raise_error
@all.each do |literal|
literal.plain?.should be_true
end
end
it "should not have a language" do
@all.each do |literal|
literal.language.should be_nil
end
end
it "should not have a datatype" do
@all.each do |literal|
literal.typed?.should be_false
literal.datatype.should be_nil
end
end
it "should support equality comparisons" do
@all.each do |literal|
copy = @new.call(literal.value)
literal.should eql(copy)
literal.should == copy
literal.should_not eql(literal.value)
literal.should == literal.value # FIXME
end
end
it "should have a string representation" do
@empty.to_s.should eql("")
@hello.to_s.should eql("Hello")
end
it "should not be #anonymous?" do
@hello.should_not be_anonymous
end
end
context "languaged-tagged literals" do
before :each do
@empty = @new.call('', :language => :en)
@hello = @new.call('Hello', :language => :en)
@all = [@empty, @hello]
end
it "should be instantiable" do
lambda { @new.call('', :language => :en) }.should_not raise_error
end
it "should have a language" do
@all.each do |literal|
literal.language.should_not be_nil
literal.language.should == :en
end
end
it "should not have a datatype" do
@all.each do |literal|
literal.typed?.should be_false
literal.datatype.should be_nil
end
end
it "should support equality comparisons" do
@all.each do |literal|
copy = @new.call(literal.value, :language => literal.language)
literal.should eql(copy)
literal.should == copy
end
end
it "should have a string representation" do
@empty.to_s.should eql("")
@hello.to_s.should eql("Hello")
end
context "c18n" do
it "should normalize language to lower-case" do
@new.call('Upper', :language => :EN, :canonicalize => true).language.should == :en
end
it "should support sub-taged language specification" do
@new.call('Hi', :language => :"en-us", :canonicalize => true).language.should == :"en-us"
end
end
end
context "datatyped literals" do
require 'date'
before :each do
@string = @new.call('')
@false = @new.call(false)
@true = @new.call(true)
@int = @new.call(123)
@long = @new.call(9223372036854775807)
@double = @new.call(3.1415)
@date = @new.call(Date.new(2010))
@datetime = @new.call(DateTime.new(2010))
@time = @new.call(Time.parse('01:02:03Z'))
@all = [@false, @true, @int, @long, @double, @time, @date, @datetime]
end
it "should be instantiable" do
lambda { @new.call(123) }.should_not raise_error
lambda { @new.call(123, :datatype => XSD.int) }.should_not raise_error
end
it "should not have a language" do
@all.each do |literal|
literal.language.should be_nil
end
end
it "should have a datatype" do
@all.each do |literal|
literal.typed?.should be_true
literal.datatype.should_not be_nil
end
end
it "should support implicit datatyping" do
@string.datatype.should == nil
@false.datatype.should == XSD.boolean
@true.datatype.should == XSD.boolean
@int.datatype.should == XSD.integer
@long.datatype.should == XSD.integer
@double.datatype.should == XSD.double
@date.datatype.should == XSD.date
@datetime.datatype.should == XSD.dateTime
@time.datatype.should == XSD.time
end
it "should support equality comparisons" do
@all.each do |literal|
copy = @new.call(literal.value, :datatype => literal.datatype)
literal.should eql(copy)
literal.should == copy
end
end
it "should have a string representation" do
@false.to_s.should eql("false")
@true.to_s.should eql("true")
@int.to_s.should eql("123")
@long.to_s.should eql("9223372036854775807")
@double.to_s.should eql("3.1415")
@date.to_s.should eql("2010-01-01Z")
@datetime.to_s.should eql("2010-01-01T00:00:00Z")
@time.to_s.should eql("01:02:03Z")
end
it "should have an object representation" do
@false.object.should eql(false)
@true.object.should eql(true)
@int.object.should eql(123)
@long.object.should eql(9223372036854775807)
@double.object.should eql(3.1415)
@date.object.should eql(Date.new(2010))
@datetime.object.should eql(DateTime.new(2010))
@time.object.should eql(Time.parse('01:02:03Z'))
end
end
#require 'nokogiri' rescue nil
describe "XML Literal" do
describe "with no namespace" do
subject { @new.call("foo bar 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 bar baz!\"^^" end
end
it "should be equal if they have the same contents" do
should == @new.call("foo bar 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 {
@new.call("foo bar baz!", :datatype => RDF.XMLLiteral,
:namespaces => {"dc" => RDF::DC.to_s})
}
describe "encodings" do
it "should return n3" do subject.to_s.should == "\"foo bar baz!\"^^" end
end
describe "and language" do
subject {
@new.call("foo bar 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 bar baz!\"\^^" end
end
end
describe "and language with an existing language embedded" do
subject {
@new.call("foo barbaz",
:datatype => RDF.XMLLiteral,
:language => :fr)
}
describe "encodings" do
it "should return n3" do subject.to_s.should == "\"foo barbaz\"^^" end
end
end
end
describe "with a default namespace" do
subject {
R@new.call("foo bar baz!", :datatype => RDF.XMLLiteral,
:namespaces => {"" => RDF::DC.to_s})
}
describe "encodings" do
it "should return n3" do subject.to_s.should == "\"foo bar baz!\"^^" end
end
end
describe "with multiple namespaces" do
subject {
@new.call("foo bar baz!", :datatype => RDF.XMLLiteral)
}
it "should ignore namespace order" do
g = @new.call("foo bar baz!", :datatype => RDF.XMLLiteral)
should == g
end
end
end if defined?(::Nokogiri)
context "validation and c18n" do
{
"true" => "true",
"false" => "false",
"tRuE" => "true",
"FaLsE" => "false",
"1" => "true",
"0" => "false",
}.each_pair do |lit, str|
it "should validate boolean '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.boolean).valid?.should be_true
end
it "should not canonicalize boolean '#{lit}' by default" do
@new.call(lit, :datatype => RDF::XSD.boolean, :canonicalize => false).to_s.should == lit
end
it "should canonicalize boolean '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.boolean, :canonicalize => true).to_s.should == str
end
end
{
"01" => "1",
"1" => "1",
"-1" => "-1",
"+1" => "1",
}.each_pair do |lit, str|
it "should validate integer '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.integer).valid?.should be_true
end
it "should not canonicalize integer '#{lit}' by default" do
@new.call(lit, :datatype => RDF::XSD.integer, :canonicalize => false).to_s.should == lit
end
it "should canonicalize integer '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.integer, :canonicalize => true).to_s.should == str
end
end
{
"1" => "1.0",
"-1" => "-1.0",
"1." => "1.0",
"1.0" => "1.0",
"1.00" => "1.0",
"+001.00" => "1.0",
"123.456" => "123.456",
"2.345" => "2.345",
"1.000000000" => "1.0",
"2.3" => "2.3",
"2.234000005" => "2.234000005",
"2.2340000000000005" => "2.2340000000000005",
"2.23400000000000005" => "2.234",
"2.23400000000000000000005" => "2.234",
"1.2345678901234567890123457890" => "1.2345678901234567",
}.each_pair do |lit, str|
it "should validate decimal '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.decimal).valid?.should be_true
end
it "should not canonicalize decimal '#{lit}' by default" do
@new.call(lit, :datatype => RDF::XSD.decimal, :canonicalize => false).to_s.should == lit
end
it "should canonicalize decimal '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.decimal, :canonicalize => true).to_s.should == str
end
end
{
"1" => "1.0E0",
"-1" => "-1.0E0",
"+01.000" => "1.0E0",
#"1." => "1.0E0",
"1.0" => "1.0E0",
"123.456" => "1.23456E2",
"1.0e+1" => "1.0E1",
"1.0e-10" => "1.0E-10",
"123.456e4" => "1.23456E6",
}.each_pair do |lit, str|
it "should validate double '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.double).valid?.should be_true
end
it "should not canonicalize double '#{lit}' by default" do
@new.call(lit, :datatype => RDF::XSD.double, :canonicalize => false).to_s.should == lit
end
it "should canonicalize double '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.double, :canonicalize => true).to_s.should == str
end
end
# DateTime
{
"2010-01-01T00:00:00Z" => "2010-01-01T00:00:00Z",
"2010-01-01T00:00:00.0000Z" => "2010-01-01T00:00:00Z",
"2010-01-01T00:00:00" => "2010-01-01T00:00:00Z",
"2010-01-01T00:00:00+00:00" => "2010-01-01T00:00:00Z",
"2010-01-01T01:00:00+01:00" => "2010-01-01T01:00:00+01:00",
"2009-12-31T23:00:00-01:00" => "2009-12-31T23:00:00-01:00",
"-2010-01-01T00:00:00Z" => "-2010-01-01T00:00:00Z",
}.each_pair do |lit, str|
it "should validate dateTime '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.dateTime).valid?.should be_true
end
it "should not canonicalize dateTime '#{lit}' by default" do
@new.call(lit, :datatype => RDF::XSD.dateTime, :canonicalize => false).to_s.should == lit
end
it "should canonicalize dateTime '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.dateTime, :canonicalize => true).to_s.should == str
end
end
# Date
{
"2010-01-01Z" => "2010-01-01Z",
"2010-01-01" => "2010-01-01Z",
"2010-01-01+00:00" => "2010-01-01Z",
"2010-01-01+01:00" => "2010-01-01Z",
"2009-12-31-01:00" => "2009-12-31Z",
"-2010-01-01Z" => "-2010-01-01Z",
}.each_pair do |lit, str|
it "should validate date '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.date).valid?.should be_true
end
it "should not canonicalize date '#{lit}' by default" do
@new.call(lit, :datatype => RDF::XSD.date, :canonicalize => false).to_s.should == lit
end
it "should canonicalize date '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.date, :canonicalize => true).to_s.should == str
end
end
# Time
{
"00:00:00Z" => "00:00:00Z",
"00:00:00.0000Z" => "00:00:00Z",
"00:00:00" => "00:00:00Z",
"00:00:00+00:00" => "00:00:00Z",
"01:00:00+01:00" => "00:00:00Z",
"23:00:00-01:00" => "00:00:00Z",
}.each_pair do |lit, str|
it "should validate time '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.time).valid?.should be_true
end
it "should not canonicalize dateTime '#{lit}' by default" do
@new.call(lit, :datatype => RDF::XSD.time, :canonicalize => false).to_s.should == lit
end
it "should canonicalize dateTime '#{lit}'" do
@new.call(lit, :datatype => RDF::XSD.time, :canonicalize => true).to_s.should == str
end
end
# Invalid
{
"foo" => RDF::XSD.boolean,
"xyz" => RDF::XSD.integer,
"12xyz" => RDF::XSD.integer,
"12.xyz" => RDF::XSD.decimal,
"xy.z" => RDF::XSD.double,
"+1.0z" => RDF::XSD.double,
"+2010-01-01T00:00:00Z" => RDF::XSD.dateTime,
"2010-01-01T00:00:00FOO" => RDF::XSD.dateTime,
"02010-01-01T00:00:00" => RDF::XSD.dateTime,
"2010-01-01" => RDF::XSD.dateTime,
"2010-1-1T00:00:00" => RDF::XSD.dateTime,
"0000-01-01T00:00:00" => RDF::XSD.dateTime,
"+2010-01-01Z" => RDF::XSD.date,
"2010-01-01TFOO" => RDF::XSD.date,
"02010-01-01" => RDF::XSD.date,
"2010-1-1" => RDF::XSD.date,
"0000-01-01" => RDF::XSD.date,
"+00:00:00Z" => RDF::XSD.time,
"-00:00:00Z" => RDF::XSD.time,
}.each_pair do |value, datatype|
it "should detect invalid encoding for '#{value}'" do
@new.call(value, :datatype => datatype).valid?.should be_false
end
end
end
end