rdf-n3 0.2.3.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/.gitignore +1 -0
  2. data/.yardopts +4 -3
  3. data/{History.txt → History.md} +30 -6
  4. data/{README.rdoc → README.md} +56 -19
  5. data/Rakefile +15 -29
  6. data/VERSION +1 -1
  7. data/example-files/sp2b.n3 +50177 -0
  8. data/lib/rdf/n3.rb +2 -2
  9. data/lib/rdf/n3/reader.rb +560 -367
  10. data/lib/rdf/n3/reader/meta.rb +640 -0
  11. data/lib/rdf/n3/reader/n3-selectors.n3 +0 -0
  12. data/lib/rdf/n3/reader/parser.rb +229 -0
  13. data/lib/rdf/n3/vocab.rb +1 -0
  14. data/lib/rdf/n3/writer.rb +324 -265
  15. data/rdf-n3.gemspec +24 -26
  16. data/script/build_meta +242 -0
  17. data/script/parse +62 -13
  18. data/script/tc +4 -4
  19. data/spec/cwm_spec.rb +11 -3
  20. data/spec/n3reader_spec.rb +233 -63
  21. data/spec/rdf_helper.rb +15 -15
  22. data/spec/spec_helper.rb +10 -4
  23. data/spec/swap_spec.rb +11 -35
  24. data/spec/swap_test/n3parser.tests +14 -14
  25. data/spec/swap_test/n3parser.yml +0 -19
  26. data/spec/swap_test/nodeID/classes.ref.rdf +1 -1
  27. data/spec/swap_test/ref/contexts-1.n3 +12 -0
  28. data/spec/swap_test/ref/prefix2.rdf +33 -0
  29. data/spec/swap_test/ref/strquot.n3 +0 -1
  30. data/spec/swap_test/ref/xml-syntax-basic-serialization.rdf +1 -1
  31. data/spec/swap_test/regression.n3 +5 -5
  32. data/spec/swap_test/regression.yml +53 -23
  33. data/spec/turtle/manifest-bad.yml +91 -0
  34. data/spec/turtle/manifest.yml +187 -0
  35. data/spec/turtle_spec.rb +12 -20
  36. data/spec/writer_spec.rb +39 -37
  37. metadata +43 -48
  38. data/lib/rdf/n3/patches/qname_hacks.rb +0 -57
  39. data/lib/rdf/n3/patches/seq.rb +0 -34
  40. data/lib/rdf/n3/reader/n3_grammar.rb +0 -3764
  41. data/lib/rdf/n3/reader/n3_grammar.treetop +0 -227
  42. data/lib/rdf/n3/reader/n3_grammar_18.rb +0 -3764
  43. data/lib/rdf/n3/reader/n3_grammar_18.treetop +0 -227
  44. data/spec/literal_spec.rb +0 -245
data/script/tc CHANGED
@@ -2,12 +2,12 @@
2
2
  require 'rubygems'
3
3
  $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", 'lib')))
4
4
  require 'rdf/n3'
5
- require 'spec/rdf_helper'
5
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", 'spec', 'rdfa_helper'))
6
6
  require 'getoptlong'
7
7
 
8
8
  def run_tc(tc)
9
9
  puts "run #{tc.name}"
10
- puts RDF::Writer.for($format.to_sym).buffer { |writer|
10
+ puts RDF::Writer.for($output_format.to_sym).buffer { |writer|
11
11
  RDF::N3::Reader.new(tc.input, :base_uri => tc.about, :strict => $strict).each do |statement|
12
12
  writer << statement
13
13
  end
@@ -15,7 +15,7 @@ def run_tc(tc)
15
15
  end
16
16
 
17
17
  $verbose = false
18
- $format = :ntriples
18
+ $output_format = :ntriples
19
19
  $strict = false
20
20
  suite = "turtle"
21
21
  opts = GetoptLong.new(
@@ -31,7 +31,7 @@ opts.each do |opt, arg|
31
31
  when '--verbose' then $verbose = true
32
32
  when '--quiet' then $quiet = true
33
33
  when '--debug' then ::RDF::N3::debug = true
34
- when '--format' then $format = arg
34
+ when '--format' then $output_format = arg
35
35
  when '--suite' then suite = arg
36
36
  when '--strict' then $strict = true
37
37
  end
@@ -12,11 +12,19 @@ describe RDF::N3::Reader do
12
12
 
13
13
  # Negative parser tests should raise errors.
14
14
  test_cases.each do |t|
15
+ next unless t.about.to_s =~ /n3$/
15
16
  #next unless t.about.uri.to_s =~ /rdfms-rdf-names-use/
16
- #next unless t.name =~ /11/
17
+ #next unless t.name =~ /1018/
17
18
  #puts t.inspect
18
- specify "test #{t.name}: " + (t.description || "#{t.inputDocument} against #{t.outputDocument}") do
19
+ specify "test #{t.name}: #{t.description}: #{t.inputDocument} against #{t.outputDocument}" do
19
20
  begin
21
+ if t.name =~ /1018/
22
+ pending("matcher does not stop")
23
+ next
24
+ elsif t.rdf_type == "CwmProofTest"
25
+ pending("proofs not supported")
26
+ next
27
+ end
20
28
  t.run_test do |rdf_string|
21
29
  t.debug = []
22
30
  g = RDF::Graph.new
@@ -28,7 +36,7 @@ describe RDF::N3::Reader do
28
36
  end
29
37
  g
30
38
  end
31
- rescue #Spec::Expectations::ExpectationNotMetError => e
39
+ rescue RSpec::Expectations::ExpectationNotMetError => e
32
40
  if t.status == "pending"
33
41
  pending("Formulae not supported") { raise }
34
42
  else
@@ -264,7 +264,7 @@ describe "RDF::N3::Reader" do
264
264
  it "should allow mixed-case language" do
265
265
  n3doc = %(:x2 :p "xyz"@EN .)
266
266
  statement = parse(n3doc).statements.first
267
- statement.object.to_ntriples.should == %("xyz"@en)
267
+ statement.object.to_ntriples.should == %("xyz"@EN)
268
268
  end
269
269
 
270
270
  it "should create typed literals" do
@@ -343,32 +343,13 @@ describe "RDF::N3::Reader" do
343
343
  end
344
344
  end
345
345
 
346
- # describe "with illegal syntax" do
347
- # {
348
- # %(:y :p1 "xyz"^^xsd:integer .) => %r(Typed literal has an invalid lexical value: .* "xyz"),
349
- # %(:y :p1 "12xyz"^^xsd:integer .) => %r(Typed literal has an invalid lexical value: .* "12xyz"),
350
- # %(:y :p1 "xy.z"^^xsd:double .) => %r(Typed literal has an invalid lexical value: .* "xy\.z"),
351
- # %(:y :p1 "+1.0z"^^xsd:double .) => %r(Typed literal has an invalid lexical value: .* "\+1.0z"),
352
- # %(:a :b .) => %r(Illegal statment: ".*" missing object),
353
- # %(:a :b 'single quote' .) => RDF::ReaderError,
354
- # %(:a "literal value" :b .) => RDF::ReaderError,
355
- # %(@keywords prefix. :e prefix :f .) => %r(Keyword ".*" used as expression)
356
- # }.each_pair do |n3, error|
357
- # it "should raise error for '#{n3}'" do
358
- # lambda {
359
- # parse("@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{n3}", :base_uri => "http://a/b")
360
- # }.should raise_error(error)
361
- # end
362
- # end
363
- # end
364
-
365
- describe "with n3 grammer" do
346
+ describe "with n3 grammar" do
366
347
  describe "syntactic expressions" do
367
348
  it "should create typed literals with qname" do
368
349
  n3doc = %(
369
- @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
370
- @prefix foaf: <http://xmlns.com/foaf/0.1/>
371
- @prefix xsd: <http://www.w3.org/2001/XMLSchema#>
350
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
351
+ @prefix foaf: <http://xmlns.com/foaf/0.1/> .
352
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
372
353
  <http://example.org/joe> foaf:name \"Joe\"^^xsd:string .
373
354
  )
374
355
  statement = parse(n3doc).statements.first
@@ -482,16 +463,50 @@ describe "RDF::N3::Reader" do
482
463
  parse(n3, :base_uri => "http://a/b").should be_equivalent_graph(nt, :about => "http://a/b", :trace => @debug)
483
464
  end
484
465
 
485
- it "should do something for @forAll" do
486
- pending
466
+ it "substitutes variable for URI with @forAll" do
467
+ n3 = %(@forAll :x . :x :y :z .)
468
+ g = parse(n3, :base_uri => "http://a/b")
469
+ statement = g.statements.first
470
+ statement.subject.should be_a(RDF::Query::Variable)
471
+ statement.predicate.to_s.should == "http://a/b#y"
472
+ statement.object.to_s.should == "http://a/b#z"
473
+ end
474
+
475
+ it "substitutes variable for URIs with @forAll" do
476
+ n3 = %(@forAll :x, :y, :z . :x :y :z .)
477
+ g = parse(n3, :base_uri => "http://a/b")
478
+ statement = g.statements.first
479
+ statement.subject.should be_a(RDF::Query::Variable)
480
+ statement.predicate.should be_a(RDF::Query::Variable)
481
+ statement.object.should be_a(RDF::Query::Variable)
482
+ statement.subject.should_not == statement.predicate
483
+ statement.object.should_not == statement.predicate
484
+ statement.predicate.should_not == statement.object
487
485
  end
488
486
 
489
- it "should do something for @forSome" do
490
- pending
487
+ it "substitutes node for URI with @forEach" do
488
+ n3 = %(@forSome :x . :x :y :z .)
489
+ g = parse(n3, :base_uri => "http://a/b")
490
+ statement = g.statements.first
491
+ statement.subject.should be_a(RDF::Node)
492
+ statement.predicate.to_s.should == "http://a/b#y"
493
+ statement.object.to_s.should == "http://a/b#z"
494
+ end
495
+
496
+ it "substitutes node for URIs with @forEach" do
497
+ n3 = %(@forSome :x, :y, :z . :x :y :z .)
498
+ g = parse(n3, :base_uri => "http://a/b")
499
+ statement = g.statements.first
500
+ statement.subject.should be_a(RDF::Node)
501
+ statement.predicate.should be_a(RDF::Node)
502
+ statement.object.should be_a(RDF::Node)
503
+ statement.subject.should_not == statement.predicate
504
+ statement.object.should_not == statement.predicate
505
+ statement.predicate.should_not == statement.object
491
506
  end
492
507
  end
493
508
 
494
- describe "namespaces" do
509
+ describe "prefixes" do
495
510
  it "should not append # for http://foo/bar" do
496
511
  n3 = %(@prefix : <http://foo/bar> . :a : :b .)
497
512
  nt = %(
@@ -562,11 +577,27 @@ describe "RDF::N3::Reader" do
562
577
  )
563
578
  parse(n3, :base_uri => "http://a/b").should be_equivalent_graph(nt, :about => "http://a/b", :trace => @debug)
564
579
  end
580
+
581
+ it "returns defined prefixes" do
582
+ n3 = %(
583
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
584
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
585
+ @prefix : <http://test/> .
586
+ :foo a rdfs:Class.
587
+ :bar :d :c.
588
+ :a :d :c.
589
+ )
590
+ reader = RDF::N3::Reader.new(n3)
591
+ reader.each {|statement|}
592
+ reader.prefixes.should == {
593
+ :rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
594
+ :rdfs => "http://www.w3.org/2000/01/rdf-schema#",
595
+ nil => "http://test/"}
596
+ end
565
597
  end
566
598
 
567
599
  describe "keywords" do
568
600
  [
569
- %(prefix :<>.),
570
601
  %(base <>.),
571
602
  %(keywords a.),
572
603
  %(:a is :b of :c.),
@@ -577,10 +608,19 @@ describe "RDF::N3::Reader" do
577
608
  it "should require @ if keywords set to empty for '#{n3}'" do
578
609
  lambda do
579
610
  parse("@keywords . #{n3}", :base_uri => "http://a/b")
580
- end.should raise_error(/unqualified keyword '\w+' used without @keyword directive/)
611
+ end.should raise_error(RDF::ReaderError)
581
612
  end
582
613
  end
583
614
 
615
+ [
616
+ %(prefix :<>.),
617
+ ].each do |n3|
618
+ it "parses as local name if keywords set to empty for '#{n3}'" do
619
+ lambda do
620
+ parse("@keywords . #{n3}", :base_uri => "http://a/b")
621
+ end.should_not raise_error(RDF::ReaderError)
622
+ end
623
+ end
584
624
  {
585
625
  %(:a a :b) => %(<http://a/b#a> <http://a/b#a> <http://a/b#b> .),
586
626
  %(:a :b true) => %(<http://a/b#a> <http://a/b#b> <http://a/b#true> .),
@@ -611,7 +651,7 @@ describe "RDF::N3::Reader" do
611
651
  n3 = %(@keywords foo.)
612
652
  lambda do
613
653
  parse(n3, :base_uri => "http://a/b")
614
- end.should raise_error(RDF::ReaderError, "undefined keywords used: foo")
654
+ end.should raise_error(RDF::ReaderError, /Undefined keywords used: foo/)
615
655
  end
616
656
  end
617
657
 
@@ -744,12 +784,6 @@ describe "RDF::N3::Reader" do
744
784
  end
745
785
 
746
786
  describe "from paths" do
747
- it "should create bnode for path x.p" do
748
- n3 = %(:x2.:y2 :p2 "3" .)
749
- nt = %(:x2 :y2 _:bnode0 . _:bnode0 :p2 "3" .)
750
- parse(n3, :base_uri => "http://a/b").should be_equivalent_graph(nt, :about => "http://a/b", :trace => @debug)
751
- end
752
-
753
787
  it "should create bnode for path x!p" do
754
788
  n3 = %(:x2!:y2 :p2 "3" .)
755
789
  nt = %(:x2 :y2 _:bnode0 . _:bnode0 :p2 "3" .)
@@ -794,7 +828,7 @@ describe "RDF::N3::Reader" do
794
828
  it "should decode path with property list." do
795
829
  n3 = %(
796
830
  @prefix a: <http://a/ns#>.
797
- :a2.a:b2.a:c2 :q1 "3" ; :q2 "4" , "5" .
831
+ :a2!a:b2!a:c2 :q1 "3" ; :q2 "4" , "5" .
798
832
  )
799
833
  nt = %(
800
834
  :a2 <http://a/ns#b2> _:bnode0 .
@@ -816,7 +850,7 @@ describe "RDF::N3::Reader" do
816
850
  end
817
851
 
818
852
  it "should decode path as object(2)" do
819
- n3 = %(@prefix a: <http://a/ns#>. :r :p :o.a:p1.a:p2 .)
853
+ n3 = %(@prefix a: <http://a/ns#>. :r :p :o!a:p1!a:p2 .)
820
854
  nt = %(
821
855
  :o <http://a/ns#p1> _:bnode0 .
822
856
  _:bnode0 <http://a/ns#p2> _:bnode1 .
@@ -828,12 +862,67 @@ describe "RDF::N3::Reader" do
828
862
  end
829
863
 
830
864
  describe "formulae" do
831
- it "should require that graph be formula_aware when encountering a formlua" do
832
- pending
865
+ before(:each) { @repo = RDF::Repository.new }
866
+
867
+ it "creates an RDF::Graph instance for formula" do
868
+ n3 = %(:a :b {})
869
+ parse(n3, :graph => @repo, :base_uri => "http://a/b")
870
+ statement = @repo.statements.first
871
+ statement.object.should be_a(RDF::Node)
872
+ end
873
+
874
+ it "adds statements with context" do
875
+
876
+ end
877
+
878
+ it "creates variables with ?" do
879
+
833
880
  end
834
881
 
835
- it "should separate triples between specified and quoted graphs" do
836
- pending
882
+ context "contexts" do
883
+ before(:each) do
884
+ n3 = %(
885
+ # Test data in notation3 http://www.w3.org/DesignIssues/Notation3.html
886
+ #
887
+ @prefix u: <http://www.example.org/utilities#> .
888
+ @prefix : <#> .
889
+
890
+ :assumption = { :fred u:knows :john .
891
+ :john u:knows :mary .} .
892
+
893
+ :conclusion = { :fred u:knows :mary . } .
894
+
895
+ # The empty context is trivially true.
896
+ # Check that we can input it and output it!
897
+
898
+ :trivialTruth = { }.
899
+
900
+ # ENDS
901
+ )
902
+ @repo = RDF::Repository.new
903
+ parse(n3, :graph => @repo, :base_uri => "http://a/b")
904
+ end
905
+
906
+ it "assumption graph has 2 statements" do
907
+ tt = @repo.first(:subject => RDF::URI.new("http://a/b#assumption"), :predicate => RDF::OWL.sameAs)
908
+ tt.object.should be_a(RDF::Node)
909
+ @repo.query(:context => tt.object).to_a.length.should == 2
910
+ end
911
+
912
+ it "conclusion graph has 1 statements" do
913
+ tt = @repo.first(:subject => RDF::URI.new("http://a/b#conclusion"), :predicate => RDF::OWL.sameAs)
914
+ tt.object.should be_a(RDF::Node)
915
+ @repo.query(:context => tt.object).to_a.length.should == 1
916
+ end
917
+
918
+ it "trivialTruth equivalent to empty graph" do
919
+ tt = @repo.first(:subject => RDF::URI.new("http://a/b#trivialTruth"), :predicate => RDF::OWL.sameAs)
920
+ tt.object.should be_a(RDF::Node)
921
+ @repo.query(:context => tt.object) do |s|
922
+ puts "statement: #{s}"
923
+ end
924
+ end
925
+
837
926
  end
838
927
  end
839
928
 
@@ -919,34 +1008,43 @@ describe "RDF::N3::Reader" do
919
1008
  nt = %(<http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> <http://foo/a#prop> "nilProp" .)
920
1009
  parse(n3, :base_uri => "http://a/b").should be_equivalent_graph(nt, :about => "http://a/b", :trace => @debug)
921
1010
  end
1011
+
922
1012
  it "should parse with compound items" do
923
1013
  n3 = %(
924
- @prefix a: <http://foo/a#> .
925
-
926
- a:a a:p ( [ a:p2 "v1" ]
927
- <http://resource1>
928
- <http://resource2>
929
- ("inner list") ) .
930
-
931
- <http://resource1> a:p "value" .
1014
+ @prefix a: <http://foo/a#> .
1015
+ a:a a:p (
1016
+ [ a:p2 "v1" ]
1017
+ <http://resource1>
1018
+ <http://resource2>
1019
+ ("inner list")
1020
+ ) .
1021
+ <http://resource1> a:p "value" .
932
1022
  )
933
1023
  nt = %(
934
- <http://foo/a#a> <http://foo/a#p> _:bnode5 .
935
- _:bnode5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:bnode4 .
936
- _:bnode5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:bnode2 .
937
- _:bnode4 <http://foo/a#p2> "v1" .
938
- _:bnode2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://resource1> .
1024
+ <http://foo/a#a> <http://foo/a#p> _:bnode3 .
939
1025
  <http://resource1> <http://foo/a#p> "value" .
1026
+ _:bnode3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:bnode5 .
1027
+ _:bnode3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:bnode2 .
1028
+ _:bnode5 <http://foo/a#p2> "v1" .
1029
+ _:bnode2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://resource1> .
940
1030
  _:bnode2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:bnode1 .
941
1031
  _:bnode1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://resource2> .
942
1032
  _:bnode1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:bnode0 .
943
- _:bnode0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:bnode3 .
1033
+ _:bnode0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:bnode4 .
944
1034
  _:bnode0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
945
- _:bnode3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "inner list" .
946
- _:bnode3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
1035
+ _:bnode4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "inner list" .
1036
+ _:bnode4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
947
1037
  )
948
1038
  g = parse(n3, :base_uri => "http://a/b")
949
- normalize_bnodes(g, "bnode0").should be_equivalent_graph(nt, :about => "http://a/b", :trace => @debug, :compare => :array)
1039
+ g.subjects.to_a.length.should == 8
1040
+ n = g.first_object(:subject => RDF::URI.new("http://foo/a#a"), :predicate => RDF::URI.new("http://foo/a#p"))
1041
+ n.should be_a(RDF::Node)
1042
+ seq = RDF::List.new(n, g)
1043
+ seq.to_a.length.should == 4
1044
+ seq.first.should be_a(RDF::Node)
1045
+ seq.second.should == RDF::URI.new("http://resource1")
1046
+ seq.third.should == RDF::URI.new("http://resource2")
1047
+ seq.fourth.should be_a(RDF::Node)
950
1048
  end
951
1049
 
952
1050
  end
@@ -1031,6 +1129,78 @@ describe "RDF::N3::Reader" do
1031
1129
  end
1032
1130
  end
1033
1131
 
1132
+ describe "canonicalization" do
1133
+ # {
1134
+ # "<http://foo>" => "<http://foo>",
1135
+ # "<http://foo/a>" => "<http://foo/a>",
1136
+ # "<http://foo#a>" => "<http://foo#a>",
1137
+ #
1138
+ # "<http://foo/>" => "<http://foo/>",
1139
+ # "<http://foo/#a>" => "<http://foo/#a>",
1140
+ #
1141
+ # "<http://foo#>" => "<http://foo#>",
1142
+ # "<http://foo#a>" => "<http://foo/a>",
1143
+ # "<http://foo#/a>" => "<http://foo/a>",
1144
+ # "<http://foo##a>" => "<http://foo#a>",
1145
+ #
1146
+ # "<http://foo/bar>" => "<http://foo/bar>",
1147
+ # "<http://foo/bar>" => "<http://foo/a>",
1148
+ # "<http://foo/bar/a>" => "<http://foo/a>",
1149
+ # "<http://foo/bar#a>" => "<http://foo/bar#a>",
1150
+ #
1151
+ # "<http://foo/bar/>" => "<http://foo/bar/>",
1152
+ # "<http://foo/bar/a>" => "<http://foo/bar/a>",
1153
+ # "<http://foo/bar//a>" => "<http://foo/a>",
1154
+ # "<http://foo/bar/#a>" => "<http://foo/bar/#a>",
1155
+ #
1156
+ # "<http://foo/bar#>" => "<http://foo/bar#>",
1157
+ # "<http://foo/bar#a>" => "<http://foo/a>",
1158
+ # "<http://foo/bar#/a>" => "<http://foo/a>",
1159
+ # "<http://foo/bar##a>" => "<http://foo/bar#a>",
1160
+ #
1161
+ # "<http://foo/bar##D%C3%BCrst>" => "<http://foo/bar#D%C3%BCrst>",
1162
+ # "<http://foo/bar##Dürst>" => "<http://foo/bar#D\\u00FCrst>",
1163
+ # }.each_pair do |input, result|
1164
+ # it "returns subject #{result} given #{input}" do
1165
+ # n3 = %(#{input} a :b)
1166
+ # nt = %(#{result} <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://a/b#b> .)
1167
+ # parse(n3, :base_uri => "http://a/b", :canonicalize => true).should be_equivalent_graph(nt, :about => "http://a/b", :trace => @debug)
1168
+ # end
1169
+ # end
1170
+
1171
+ {
1172
+ %("+1"^^xsd:integer) => %("1"^^<http://www.w3.org/2001/XMLSchema#integer>),
1173
+ %(+1) => %("1"^^<http://www.w3.org/2001/XMLSchema#integer>),
1174
+ %(true) => %("true"^^<http://www.w3.org/2001/XMLSchema#boolean>),
1175
+ %("lang"@EN) => %("lang"@en),
1176
+ }.each_pair do |input, result|
1177
+ it "returns object #{result} given #{input}" do
1178
+ n3 = %(@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . :a :b #{input} .)
1179
+ nt = %(<http://a/b#a> <http://a/b#b> #{result} .)
1180
+ parse(n3, :base_uri => "http://a/b", :canonicalize => true).should be_equivalent_graph(nt, :about => "http://a/b", :trace => @debug)
1181
+ end
1182
+ end
1183
+ end
1184
+
1185
+ describe "validation" do
1186
+ {
1187
+ %(:y :p1 "xyz"^^xsd:integer .) => %r("xyz" is not a valid .*),
1188
+ %(:y :p1 "12xyz"^^xsd:integer .) => %r("12xyz" is not a valid .*),
1189
+ %(:y :p1 "xy.z"^^xsd:double .) => %r("xy\.z" is not a valid .*),
1190
+ %(:y :p1 "+1.0z"^^xsd:double .) => %r("\+1.0z" is not a valid .*),
1191
+ %(:a :b .) =>RDF::ReaderError,
1192
+ %(:a :b 'single quote' .) => RDF::ReaderError,
1193
+ %(:a "literal value" :b .) => RDF::ReaderError,
1194
+ %(@keywords prefix. :e prefix :f .) => RDF::ReaderError
1195
+ }.each_pair do |n3, error|
1196
+ it "should raise '#{error}' for '#{n3}'" do
1197
+ lambda {
1198
+ parse("@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . #{n3}", :base_uri => "http://a/b", :validate => true)
1199
+ }.should raise_error(error)
1200
+ end
1201
+ end
1202
+ end
1203
+
1034
1204
  it "should parse rdf_core testcase" do
1035
1205
  sampledoc = <<-EOF;
1036
1206
  <http://www.w3.org/2000/10/rdf-tests/rdfcore/xmlbase/Manifest.rdf#test001> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/10/rdf-tests/rdfcore/testSchema#PositiveParserTest> .
@@ -1052,8 +1222,8 @@ EOF
1052
1222
 
1053
1223
  def parse(input, options = {})
1054
1224
  @debug = []
1055
- graph = RDF::Graph.new
1056
- RDF::N3::Reader.new(input, options.merge(:debug => @debug, :strict => true)).each do |statement|
1225
+ graph = options[:graph] || RDF::Graph.new
1226
+ RDF::N3::Reader.new(input, {:debug => @debug, :validate => true, :canonicalize => false}.merge(options)).each do |statement|
1057
1227
  graph << statement
1058
1228
  end
1059
1229
  graph