$:.unshift "." require File.join(File.dirname(__FILE__), 'spec_helper') describe RDF::N3::Writer do describe "simple tests" do it "should use full URIs without base" do input = %( .) serialize(input, nil, [%r(^ \.$)]) end it "should use relative URIs with base" do input = %( .) serialize(input, "http://a/", [ %r(^@base \.$), %r(^ \.$)] ) end it "should use qname URIs with prefix" do input = %( .) serialize(input, nil, [%r(^@prefix foaf: \.$), %r(^foaf:b foaf:c foaf:d \.$)], :prefixes => { :foaf => RDF::FOAF} ) end it "should use qname URIs with empty prefix" do input = %( .) serialize(input, nil, [%r(^@prefix : \.$), %r(^:b :c :d \.$)], :prefixes => { "" => RDF::FOAF} ) end # see example-files/arnau-registered-vocab.rb it "should use qname URIs with empty suffix" do input = %( .) serialize(input, nil, [%r(^@prefix foaf: \.$), %r(^foaf: foaf: foaf: \.$)], :prefixes => { "foaf" => RDF::FOAF} ) end it "should not use qname with illegal local part" do input = %( @prefix db: . @prefix dbo: . db:Michael_Jackson dbo:artistOf . ) serialize(input, nil, [%r(^@prefix db: \.$), %r(^db:Michael_Jackson dbo:artistOf \.$)], :prefixes => { "db" => RDF::URI("http://dbpedia.org/resource/"), "dbo" => RDF::URI("http://dbpedia.org/ontology/")} ) end it "should order properties" do input = %( @prefix : . @prefix dc: . @prefix rdfs: . :b :c :d . :b dc:title "title" . :b a :class . :b rdfs:label "label" . ) serialize(input, nil, [%r(^\s+a :class;$), %r(^\s+rdfs:label "label"), %r(^:b dc:title \"title\"), %r(^\s+:c :d)], :prefixes => { "" => RDF::FOAF, :dc => "http://purl.org/dc/elements/1.1/", :rdfs => RDF::RDFS} ) end it "should generate object list" do input = %(@prefix : . :b :c :d, :e .) serialize(input, nil, [%r(^@prefix : \.$), %r(^:b :c :d,$), %r(^\s+:e \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate property list" do input = %(@prefix : . :b :c :d; :e :f .) serialize(input, nil, [%r(^@prefix : \.$), %r(^:b :c :d;$), %r(^\s+:e :f \.$)], :prefixes => { "" => RDF::FOAF} ) end end describe "anons" do it "should generate bare anon" do input = %(@prefix : . [:a :b] .) serialize(input, nil, [%r(^\s*\[ :a :b\] \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate anon as subject" do input = %(@prefix : . [:a :b] :c :d .) serialize(input, nil, [%r(^\s*\[ :a :b;$), %r(^\s+:c :d\] \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate anon as object" do input = %(@prefix : . :a :b [:c :d] .) serialize(input, nil, [%r(^\s*\:a :b \[ :c :d\] \.$)], :prefixes => { "" => RDF::FOAF} ) end end describe "lists" do it "should generate bare list" do input = %(@prefix : . (:a :b) .) serialize(input, nil, [%r(^\(:a :b\) \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate literal list" do input = %(@prefix : . :a :b ( "apple" "banana" ) .) serialize(input, nil, [%r(^:a :b \("apple" "banana"\) \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate empty list" do input = %(@prefix : . :a :b () .) serialize(input, nil, [%r(^:a :b \(\) \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate empty list(2)" do input = %(@prefix : . :emptyList = () .) serialize(input, nil, [%r(^:emptyList (<.*sameAs>|owl:sameAs) \(\) \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate empty list as subject" do input = %(@prefix : . () :a :b .) serialize(input, nil, [%r(^\(\) :a :b \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate list as subject" do input = %(@prefix : . (:a) :b :c .) serialize(input, nil, [%r(^\(:a\) :b :c \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate list of empties" do input = %(@prefix : . :listOf2Empties = (() ()) .) serialize(input, nil, [%r(^:listOf2Empties (<.*sameAs>|owl:sameAs) \(\(\) \(\)\) \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate list anon" do input = %(@prefix : . :twoAnons = ([a :mother] [a :father]) .) serialize(input, nil, [%r(^:twoAnons (<.*sameAs>|owl:sameAs) \(\[\s*a :mother\] \[\s*a :father\]\) \.$)], :prefixes => { "" => RDF::FOAF} ) end it "should generate owl:unionOf list" do input = %( @prefix : . @prefix owl: . @prefix rdf: . @prefix rdfs: . :a rdfs:domain [ a owl:Class; owl:unionOf [ a owl:Class; rdf:first :b; rdf:rest [ a owl:Class; rdf:first :c; rdf:rest rdf:nil ] ] ] . ) #$verbose = true serialize(input, nil, [ %r(:a rdfs:domain \[\s*a owl:Class;\s+owl:unionOf\s+\(:b\s+:c\)\]\s*\.$)m, %r(@prefix : \.), %r(@prefix rdf: \.), ], :prefixes => { "" => RDF::FOAF, :rdfs => RDF::RDFS, :owl => RDF::OWL, :rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#"} ) #$verbose = false end end describe "literals" do describe "plain" do it "encodes embedded \"\"\"" do n3 = %(:a :b """testing string parsing in N3. """ .) serialize(n3, nil, [/testing string parsing in N3.\n/]) end it "encodes embedded \"" do n3 = %(:a :b """string with " escaped quote marks""" .) serialize(n3, nil, [/string with \\" escaped quote mark/]) end end describe "with language" do it "specifies language for literal with language" do ttl = %q(:a :b "string"@en .) serialize(ttl, nil, [%r("string"@en)]) end end describe "xsd:anyURI" do it "uses xsd namespace for datatype" do ttl = %q(@prefix xsd: . :a :b "http://foo/"^^xsd:anyURI .) serialize(ttl, nil, [ %r(@prefix xsd: \.), %r("http://foo/"\^\^xsd:anyURI \.), ]) end end describe "xsd:boolean" do [ [%q("true"^^xsd:boolean), /true ./], [%q("TrUe"^^xsd:boolean), /true ./], [%q("1"^^xsd:boolean), /true ./], [%q(true), /true ./], [%q("false"^^xsd:boolean), /false ./], [%q("FaLsE"^^xsd:boolean), /false ./], [%q("0"^^xsd:boolean), /false ./], [%q(false), /false ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do ttl = %(@prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, ], :canonicalize => true) end end end describe "xsd:integer" do [ [%q("1"^^xsd:integer), /1 ./], [%q(1), /1 ./], [%q("0"^^xsd:integer), /0 ./], [%q(0), /0 ./], [%q("10"^^xsd:integer), /10 ./], [%q(10), /10 ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do ttl = %(@prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, ], :canonicalize => true) end end end describe "xsd:int" do [ [%q("1"^^xsd:int), /"1"\^\^xsd:int ./], [%q("0"^^xsd:int), /"0"\^\^xsd:int ./], [%q("10"^^xsd:int), /"10"\^\^xsd:int ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do ttl = %(@prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, ], :canonicalize => true) end end end describe "xsd:decimal" do [ [%q("1.0"^^xsd:decimal), /1.0 ./], [%q(1.0), /1.0 ./], [%q("0.1"^^xsd:decimal), /0.1 ./], [%q(0.1), /0.1 ./], [%q("10.02"^^xsd:decimal), /10.02 ./], [%q(10.02), /10.02 ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do ttl = %(@prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, ], :canonicalize => true) end end end describe "xsd:double" do [ [%q("1.0e1"^^xsd:double), /1.0e1 ./], [%q(1.0e1), /1.0e1 ./], [%q("0.1e1"^^xsd:double), /1.0e0 ./], [%q(0.1e1), /1.0e0 ./], [%q("10.02e1"^^xsd:double), /1.002e2 ./], [%q(10.02e1), /1.002e2 ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do ttl = %(@prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, ], :canonicalize => true) end end end end # W3C Turtle Test suite from http://www.w3.org/2000/10/swap/test/regression.n3 describe "w3c turtle tests" do require 'turtle_test' Fixtures::TurtleTest::Good.each do |t| next unless t.comment #puts t.inspect #next unless t.name == "test-04" next if t.name == "test-29" # FIXME specify "#{t.name}: #{t.comment}" do @graph = parse(t.output, :base_uri => t.result, :format => :ntriples) n3 = serialize(t.output, t.result, [], :format => :n3) g2 = parse(n3, :base_uri => t.result) g2.should be_equivalent_graph(@graph, :trace => @debug.join("\n")) end end end def parse(input, options = {}) graph = RDF::Graph.new RDF::N3::Reader.new(input, options).each do |statement| graph << statement end graph end # Serialize ntstr to a string and compare against regexps def serialize(ntstr, base = nil, regexps = [], options = {}) prefixes = options[:prefixes] || {} g = parse(ntstr, :base_uri => base, :prefixes => prefixes) @debug = [] result = RDF::N3::Writer.buffer(options.merge(:debug => @debug, :base_uri => base, :prefixes => prefixes)) do |writer| writer << g end if $verbose require 'cgi' #puts CGI.escapeHTML(result) end regexps.each do |re| result.should match_re(re, :about => base, :trace => @debug, :inputDocument => ntstr) end result end end