require File.join(File.dirname(__FILE__), 'spec_helper') include Reddy describe "N3 parser" do before(:each) { @parser = N3Parser.new(:strict => true) } describe "parse simple ntriples" do it "should parse simple triple" do n3_string = " \"Tom Morris\" . " @parser.parse(n3_string) @parser.graph[0].subject.to_s.should == "http://example.org/" @parser.graph[0].predicate.to_s.should == "http://xmlns.com/foaf/0.1/name" @parser.graph[0].object.to_s.should == "Tom Morris" @parser.graph.size.should == 1 end it "should parse simple triple from class method" do n3_string = " \"Tom Morris\" . " graph = N3Parser.new(:strict => true).parse(n3_string) graph[0].subject.to_s.should == "http://example.org/" graph[0].predicate.to_s.should == "http://xmlns.com/foaf/0.1/name" graph[0].object.to_s.should == "Tom Morris" graph.size.should == 1 end # NTriple tests from http://www.w3.org/2000/10/rdf-tests/rdfcore/ntriples/test.nt describe "recognize blank lines" do { "comment" => "# comment lines", "comment after whitespace" => " # comment after whitespace", "empty line" => "", "line with spaces" => " " }.each_pair do |name, statement| specify "test #{name}" do @parser.parse(statement) @parser.graph.size.should == 0 end end end it "should create named subject bnode" do @parser.parse("_:anon .") @parser.graph.should_not be_nil @parser.graph.size.should == 1 triple = @parser.graph[0] triple.subject.should be_a(BNode) triple.subject.identifier.should =~ /anon/ triple.predicate.should == "http://example.org/property" triple.object.should == "http://example.org/resource2" end it "should create named object bnode" do @parser.parse(" _:anon .") @parser.graph.should_not be_nil @parser.graph.size.should == 1 triple = @parser.graph[0] triple.subject.should == "http://example.org/resource2" triple.predicate.should == "http://example.org/property" triple.object.should be_a(BNode) triple.object.identifier.should =~ /anon/ end { "three uris" => " .", "spaces and tabs throughout" => " . ", "line ending with CR NL" => " .\r\n", "literal escapes (1)" => ' "simple literal" .', "literal escapes (2)" => ' "backslash:\\\\" .', "literal escapes (3)" => ' "dquote:\"" .', "literal escapes (4)" => ' "newline:\n" .', "literal escapes (5)" => ' "return:\r" .', "literal escapes (6)" => ' "tab:\t" .', "Space is optional before final . (1)" => [' .', ' .'], "Space is optional before final . (2)" => [' "x".', ' "x" .'], "XML Literals as Datatyped Literals (1)" => ' ""^^ .', "XML Literals as Datatyped Literals (2)" => ' " "^^ .', "XML Literals as Datatyped Literals (3)" => ' "x"^^ .', "XML Literals as Datatyped Literals (4)" => ' "\""^^ .', "XML Literals as Datatyped Literals (5)" => ' ""^^ .', "XML Literals as Datatyped Literals (6)" => ' "a "^^ .', "XML Literals as Datatyped Literals (7)" => ' "a c"^^ .', "XML Literals as Datatyped Literals (8)" => ' "a\n\nc"^^ .', "XML Literals as Datatyped Literals (9)" => ' "chat"^^ .', "Plain literals with languages (1)" => ' "chat"@fr .', "Plain literals with languages (2)" => ' "chat"@en .', "Typed Literals" => ' "abc"^^ .', }.each_pair do |name, statement| specify "test #{name}" do @parser.parse([statement].flatten.first) @parser.graph.should_not be_nil @parser.graph.size.should == 1 #puts @parser.graph[0].to_ntriples @parser.graph[0].to_ntriples.should == [statement].flatten.last.gsub(/\s+/, " ").strip end end end describe "literal encodings" do { 'Dürst' => '_:a "D\u00FCrst" .', 'simple literal' => ' "simple literal" .', 'backslash:\\' => ' "backslash:\\\\" .', 'dquote:"' => ' "dquote:\"" .', "newline:\n" => ' "newline:\n" .', "return\r" => ' "return\r" .', "tab:\t" => ' "tab:\t" .', "é" => ' "\u00E9" .', "€" => ' "\u20AC" .', }.each_pair do |contents, triple| specify "test #{contents}" do @parser.parse(triple) @parser.graph.should_not be_nil @parser.graph.size.should == 1 @parser.graph[0].object.contents.should == contents end end end # n3p tests taken from http://inamidst.com/n3p/test/ describe "parsing n3p test" do dir_name = File.join(File.dirname(__FILE__), '..', 'test', 'n3_tests', 'n3p', '*.n3') Dir.glob(dir_name).each do |n3| it n3 do test_file(n3) end end end describe "parsing real data tests" do dirs = [ 'misc', 'lcsh' ] dirs.each do |dir| dir_name = File.join(File.dirname(__FILE__), '..', 'test', 'n3_tests', dir, '*.n3') Dir.glob(dir_name).each do |n3| it "#{dir} #{n3}" do test_file(n3) end end end end it "should throw an exception when presented with a BNode as a predicate" do n3doc = "_:a _:b _:c ." lambda { @parser.parse(n3doc) }.should raise_error(Reddy::Triple::InvalidPredicate) end it "should create BNodes" do n3doc = "_:a a _:c ." @parser.parse(n3doc) @parser.graph[0].subject.class.should == Reddy::BNode @parser.graph[0].object.class.should == Reddy::BNode end it "should create URIRefs" do n3doc = " ." @parser.parse(n3doc) @parser.graph[0].subject.class.should == Reddy::URIRef @parser.graph[0].object.class.should == Reddy::URIRef end it "should create literals" do n3doc = " \"Joe\"." @parser.parse(n3doc) @parser.graph[0].object.class.should == Reddy::Literal end it "should create typed literals" do n3doc = " \"Joe\"^^ ." @parser.parse(n3doc) @parser.graph[0].object.class.should == Reddy::Literal end it "should map <#> to document uri" do n3doc = "@prefix : <#> ." @parser.parse(n3doc, "http://the.document.itself") @parser.graph.nsbinding.should == {"__local__", Namespace.new("http://the.document.itself", "__local__")} end it "should parse testcase" do sampledoc = <<-EOF; . . . . . "APPROVED" . . . EOF @parser.parse(sampledoc, "http://www.w3.org/2000/10/rdf-tests/rdfcore/amp-in-url/Manifest.rdf") ntriples = @parser.graph.to_ntriples ntriples = sort_ntriples(ntriples) nt_string = sort_ntriples(sampledoc) ntriples.should == nt_string end def test_file(filepath) anon = "a" anon_ctx = {} n3_string = File.read(filepath) @parser.parse(n3_string, "file:#{filepath}") ntriples = @parser.graph.to_ntriples ntriples.gsub!(/_:nbn\d+[a-z]+N/, "_:") # Normalize named BNodes ntriples.gsub!(/_:bn\d+[a-z]+/) do |bn| # Normalize anon BNodes if anon_ctx[bn] anon_ctx[bn] else anon_ctx[bn] = anon anon = anon.succ end "_:#{anon_ctx[bn]}" end ntriples = sort_ntriples(ntriples) nt_string = File.read(filepath.sub('.n3', '.nt')) nt_string = sort_ntriples(nt_string) ntriples.should == nt_string end def sort_ntriples(string) string.split("\n").sort.join("\n") end end