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