rdf-n3 0.0.3 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +3 -0
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/lib/rdf/n3/patches/literal_normalization.rb +126 -99
- data/lib/rdf/n3/reader.rb +10 -9
- data/lib/rdf/n3/version.rb +2 -2
- data/lib/rdf/n3/writer.rb +1 -1
- data/lib/rdf/n3.rb +0 -2
- data/rdf-n3.gemspec +13 -17
- data/spec/literal_spec.rb +22 -343
- data/spec/n3reader_spec.rb +19 -19
- data/spec/spec_helper.rb +1 -0
- metadata +12 -33
- data/lib/rdf/n3/patches/literal_hacks.rb +0 -23
- data/lib/rdf/n3/patches/rdf_escape.rb +0 -131
- data/spec/turtle_serializer_spec.rb +0 -226
@@ -1,131 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
require 'iconv'
|
3
|
-
|
4
|
-
class String
|
5
|
-
#private
|
6
|
-
# "Borrowed" from JSON utf8_to_json
|
7
|
-
RDF_MAP = {
|
8
|
-
"\x0" => '\u0000',
|
9
|
-
"\x1" => '\u0001',
|
10
|
-
"\x2" => '\u0002',
|
11
|
-
"\x3" => '\u0003',
|
12
|
-
"\x4" => '\u0004',
|
13
|
-
"\x5" => '\u0005',
|
14
|
-
"\x6" => '\u0006',
|
15
|
-
"\x7" => '\u0007',
|
16
|
-
"\b" => '\b',
|
17
|
-
"\t" => '\t',
|
18
|
-
"\n" => '\n',
|
19
|
-
"\xb" => '\u000B',
|
20
|
-
"\f" => '\f',
|
21
|
-
"\r" => '\r',
|
22
|
-
"\xe" => '\u000E',
|
23
|
-
"\xf" => '\u000F',
|
24
|
-
"\x10" => '\u0010',
|
25
|
-
"\x11" => '\u0011',
|
26
|
-
"\x12" => '\u0012',
|
27
|
-
"\x13" => '\u0013',
|
28
|
-
"\x14" => '\u0014',
|
29
|
-
"\x15" => '\u0015',
|
30
|
-
"\x16" => '\u0016',
|
31
|
-
"\x17" => '\u0017',
|
32
|
-
"\x18" => '\u0018',
|
33
|
-
"\x19" => '\u0019',
|
34
|
-
"\x1a" => '\u001A',
|
35
|
-
"\x1b" => '\u001B',
|
36
|
-
"\x1c" => '\u001C',
|
37
|
-
"\x1d" => '\u001D',
|
38
|
-
"\x1e" => '\u001E',
|
39
|
-
"\x1f" => '\u001F',
|
40
|
-
'"' => '\"',
|
41
|
-
'\\' => '\\\\',
|
42
|
-
'/' => '/',
|
43
|
-
} # :nodoc:
|
44
|
-
|
45
|
-
if defined?(::Encoding)
|
46
|
-
# Funky way to define constant, but if parsed in 1.8 it generates an 'invalid regular expression' error otherwise
|
47
|
-
eval %(ESCAPE_RE = %r([\u{80}-\u{10ffff}]))
|
48
|
-
else
|
49
|
-
ESCAPE_RE = %r(
|
50
|
-
[\xc2-\xdf][\x80-\xbf] |
|
51
|
-
[\xe0-\xef][\x80-\xbf]{2} |
|
52
|
-
[\xf0-\xf4][\x80-\xbf]{3}
|
53
|
-
)nx
|
54
|
-
end
|
55
|
-
|
56
|
-
# Convert a UTF8 encoded Ruby string _string_ to an escaped string, encoded with
|
57
|
-
# UTF16 big endian characters as \U????, and return it.
|
58
|
-
#
|
59
|
-
# \\:: Backslash
|
60
|
-
# \':: Single quote
|
61
|
-
# \":: Double quot
|
62
|
-
# \n:: ASCII Linefeed
|
63
|
-
# \r:: ASCII Carriage Return
|
64
|
-
# \t:: ASCCII Horizontal Tab
|
65
|
-
# \uhhhh:: character in BMP with Unicode value U+hhhh
|
66
|
-
# \U00hhhhhh:: character in plane 1-16 with Unicode value U+hhhhhh
|
67
|
-
def rdf_escape
|
68
|
-
string = self + '' # XXX workaround: avoid buffer sharing
|
69
|
-
string.gsub!(/["\\\/\x0-\x1f]/) { RDF_MAP[$&] }
|
70
|
-
if defined?(::Encoding)
|
71
|
-
string.force_encoding(Encoding::UTF_8)
|
72
|
-
string.gsub!(ESCAPE_RE) { |c|
|
73
|
-
s = c.dump.sub(/\"\\u\{(.+)\}\"/, '\1').upcase
|
74
|
-
(s.length <= 4 ? "\\u0000"[0,6-s.length] : "\\U00000000"[0,10-s.length]) + s
|
75
|
-
}
|
76
|
-
string.force_encoding(Encoding::ASCII_8BIT)
|
77
|
-
else
|
78
|
-
string.gsub!(ESCAPE_RE) { |c|
|
79
|
-
s = Iconv.new('utf-16be', 'utf-8').iconv(c).unpack('H*').first.upcase
|
80
|
-
"\\u" + s
|
81
|
-
}
|
82
|
-
end
|
83
|
-
string
|
84
|
-
end
|
85
|
-
|
86
|
-
# Unescape characters in strings.
|
87
|
-
RDF_UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
|
88
|
-
RDF_UNESCAPE_MAP.update({
|
89
|
-
?" => '"',
|
90
|
-
?\\ => '\\',
|
91
|
-
?/ => '/',
|
92
|
-
?b => "\b",
|
93
|
-
?f => "\f",
|
94
|
-
?n => "\n",
|
95
|
-
?r => "\r",
|
96
|
-
?t => "\t",
|
97
|
-
?u => nil,
|
98
|
-
})
|
99
|
-
|
100
|
-
if defined?(::Encoding)
|
101
|
-
UNESCAPE_RE = %r(
|
102
|
-
(?:\\[\\bfnrt"/]) # Escaped control characters, " and /
|
103
|
-
|(?:\\U00\h{6}) # 6 byte escaped Unicode
|
104
|
-
|(?:\\u\h{4}) # 4 byte escaped Unicode
|
105
|
-
)x
|
106
|
-
else
|
107
|
-
UNESCAPE_RE = %r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n
|
108
|
-
end
|
109
|
-
|
110
|
-
# Reverse operation of escape
|
111
|
-
# From JSON parser
|
112
|
-
def rdf_unescape
|
113
|
-
return '' if self.empty?
|
114
|
-
string = self.gsub(UNESCAPE_RE) do |c|
|
115
|
-
case c[1,1]
|
116
|
-
when 'U'
|
117
|
-
raise RDF::ReaderError, "Long Unicode escapes no supported in Ruby 1.8" unless defined?(::Encoding)
|
118
|
-
eval(c.sub(/\\U00(\h+)/, '"\u{\1}"'))
|
119
|
-
when 'u'
|
120
|
-
bytes = [c[2, 2].to_i(16), c[4, 2].to_i(16)]
|
121
|
-
Iconv.new('utf-8', 'utf-16').iconv(bytes.pack("C*"))
|
122
|
-
else
|
123
|
-
RDF_UNESCAPE_MAP[c[1]]
|
124
|
-
end
|
125
|
-
end
|
126
|
-
string.force_encoding(Encoding::UTF_8) if defined?(::Encoding)
|
127
|
-
string
|
128
|
-
rescue Iconv::Failure => e
|
129
|
-
raise RDF::ReaderError, "Caught #{e.class}: #{e}"
|
130
|
-
end
|
131
|
-
end unless String.method_defined?(:rdf_escape)
|
@@ -1,226 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
include RdfContext
|
3
|
-
|
4
|
-
describe "Turtle Serializer" do
|
5
|
-
describe "simple tests" do
|
6
|
-
it "should use full URIs without base" do
|
7
|
-
input = %(<http://a/b> <http://a/c> <http://a/d> .)
|
8
|
-
serialize(input, nil, %r(^<http://a/b> <http://a/c> <http://a/d> \.$))
|
9
|
-
end
|
10
|
-
|
11
|
-
it "should use relative URIs with base" do
|
12
|
-
input = %(<http://a/b> <http://a/c> <http://a/d> .)
|
13
|
-
serialize(input, "http://a/",
|
14
|
-
%r(^@base <http://a/> \.$),
|
15
|
-
%r(^<b> <c> <d> \.$)
|
16
|
-
)
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should use qname URIs with prefix" do
|
20
|
-
input = %(@prefix a: <http://a/> . <http://a/b> <http://a/c> <http://a/d> .)
|
21
|
-
serialize(input, nil,
|
22
|
-
%r(^@prefix a: <http://a/> \.$),
|
23
|
-
%r(^a:b a:c a:d \.$)
|
24
|
-
)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should use qname URIs with empty prefix" do
|
28
|
-
input = %(@prefix : <http://a/> . <http://a/b> <http://a/c> <http://a/d> .)
|
29
|
-
serialize(input, nil,
|
30
|
-
%r(^@prefix : <http://a/> \.$),
|
31
|
-
%r(^:b :c :d \.$)
|
32
|
-
)
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should order properties" do
|
36
|
-
input = %(
|
37
|
-
@prefix : <http://a/> .
|
38
|
-
@prefix dc: <http://purl.org/dc/elements/1.1/> .
|
39
|
-
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
40
|
-
:b :c :d .
|
41
|
-
:b dc:title "title" .
|
42
|
-
:b a :class .
|
43
|
-
:b rdfs:label "label" .
|
44
|
-
)
|
45
|
-
serialize(input, nil,
|
46
|
-
%r(^:b a :class;$),
|
47
|
-
%r(^\s+rdfs:label "label"),
|
48
|
-
%r(^\s+dc:title \"title\"),
|
49
|
-
%r(^\s+:c :d)
|
50
|
-
)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should generate object list" do
|
54
|
-
input = %(@prefix : <http://a/> . :b :c :d, :e .)
|
55
|
-
serialize(input, nil,
|
56
|
-
%r(^@prefix : <http://a/> \.$),
|
57
|
-
%r(^:b :c :d,$),
|
58
|
-
%r(^\s+:e \.$)
|
59
|
-
)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should generate property list" do
|
63
|
-
input = %(@prefix : <http://a/> . :b :c :d; :e :f .)
|
64
|
-
serialize(input, nil,
|
65
|
-
%r(^@prefix : <http://a/> \.$),
|
66
|
-
%r(^:b :c :d;$),
|
67
|
-
%r(^\s+:e :f \.$)
|
68
|
-
)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "anons" do
|
73
|
-
it "should generate bare anon" do
|
74
|
-
input = %(@prefix : <http://a/> . [:a :b] .)
|
75
|
-
serialize(input, nil,
|
76
|
-
%r(^\s*\[ :a :b\] \.$)
|
77
|
-
)
|
78
|
-
end
|
79
|
-
|
80
|
-
it "should generate anon as subject" do
|
81
|
-
input = %(@prefix : <http://a/> . [:a :b] :c :d .)
|
82
|
-
serialize(input, nil,
|
83
|
-
%r(^\s*\[ :a :b;$),
|
84
|
-
%r(^\s+:c :d\] \.$)
|
85
|
-
)
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should generate anon as object" do
|
89
|
-
input = %(@prefix : <http://a/> . :a :b [:c :d] .)
|
90
|
-
serialize(input, nil,
|
91
|
-
%r(^\s*\:a :b \[ :c :d\] \.$)
|
92
|
-
)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
describe "lists" do
|
97
|
-
it "should generate bare list" do
|
98
|
-
input = %(@prefix : <http://a/> . (:a :b) .)
|
99
|
-
serialize(input, nil,
|
100
|
-
%r(^\(:a :b\) \.$)
|
101
|
-
)
|
102
|
-
end
|
103
|
-
|
104
|
-
it "should generate literal list" do
|
105
|
-
input = %(@prefix : <http://a/> . :a :b ( "apple" "banana" ) .)
|
106
|
-
serialize(input, nil,
|
107
|
-
%r(^:a :b \("apple" "banana"\) \.$)
|
108
|
-
)
|
109
|
-
end
|
110
|
-
|
111
|
-
it "should generate empty list" do
|
112
|
-
input = %(@prefix : <http://a/> . :a :b () .)
|
113
|
-
serialize(input, nil,
|
114
|
-
%r(^:a :b \(\) \.$)
|
115
|
-
)
|
116
|
-
end
|
117
|
-
|
118
|
-
it "should generate empty list(2)" do
|
119
|
-
input = %(@prefix : <http://a/> . :emptyList = () .)
|
120
|
-
serialize(input, nil,
|
121
|
-
%r(^:emptyList (<.*sameAs>|owl:sameAs) \(\) \.$)
|
122
|
-
)
|
123
|
-
end
|
124
|
-
|
125
|
-
it "should generate empty list as subject" do
|
126
|
-
input = %(@prefix : <http://a/> . () :a :b .)
|
127
|
-
serialize(input, nil,
|
128
|
-
%r(^\(\) :a :b \.$)
|
129
|
-
)
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should generate list as subject" do
|
133
|
-
input = %(@prefix : <http://a/> . (:a) :b :c .)
|
134
|
-
serialize(input, nil,
|
135
|
-
%r(^\(:a\) :b :c \.$)
|
136
|
-
)
|
137
|
-
end
|
138
|
-
|
139
|
-
it "should generate list of empties" do
|
140
|
-
input = %(@prefix : <http://a/> . :listOf2Empties = (() ()) .)
|
141
|
-
serialize(input, nil,
|
142
|
-
%r(^:listOf2Empties (<.*sameAs>|owl:sameAs) \(\(\) \(\)\) \.$)
|
143
|
-
)
|
144
|
-
end
|
145
|
-
|
146
|
-
it "should generate list anon" do
|
147
|
-
input = %(@prefix : <http://a/> . :twoAnons = ([a :mother] [a :father]) .)
|
148
|
-
serialize(input, nil,
|
149
|
-
%r(^:twoAnons (<.*sameAs>|owl:sameAs) \(\[\s*a :mother\] \[\s*a :father\]\) \.$)
|
150
|
-
)
|
151
|
-
end
|
152
|
-
|
153
|
-
it "should generate owl:unionOf list" do
|
154
|
-
input = %(
|
155
|
-
@prefix : <http://a/> .
|
156
|
-
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
157
|
-
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
158
|
-
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
159
|
-
:a rdfs:domain [
|
160
|
-
a owl:Class;
|
161
|
-
owl:unionOf [
|
162
|
-
a owl:Class;
|
163
|
-
rdf:first :b;
|
164
|
-
rdf:rest [
|
165
|
-
a owl:Class;
|
166
|
-
rdf:first :c;
|
167
|
-
rdf:rest rdf:nil
|
168
|
-
]
|
169
|
-
]
|
170
|
-
] .
|
171
|
-
)
|
172
|
-
serialize(input, nil,
|
173
|
-
%r(:a rdfs:domain \[\s*a owl:Class;\s+owl:unionOf\s+\(:b\s+:c\)\]\s*\.$)m
|
174
|
-
)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
# W3C Turtle Test suite from http://www.w3.org/2000/10/swap/test/regression.n3
|
179
|
-
describe "w3c turtle tests" do
|
180
|
-
require 'rdf_helper'
|
181
|
-
|
182
|
-
def self.positive_tests
|
183
|
-
RdfHelper::TestCase.test_cases(TURTLE_TEST, TURTLE_DIR) rescue []
|
184
|
-
end
|
185
|
-
|
186
|
-
positive_tests.each do |t|
|
187
|
-
#puts t.inspect
|
188
|
-
#next unless t.name == "test-04"
|
189
|
-
|
190
|
-
specify "#{t.name}: " + (t.description || "#{t.inputDocument}") do
|
191
|
-
# Skip tests for very long files, too long
|
192
|
-
if %w(test-14 test-15 test-16 rdfq-results).include?(t.name)
|
193
|
-
pending("Skip very long input file")
|
194
|
-
elsif !defined?(::Encoding) && %w(test-18).include?(t.name)
|
195
|
-
pending("Not supported in Ruby 1.8")
|
196
|
-
elsif %w(test-29).include?(t.name)
|
197
|
-
pending("Silly test")
|
198
|
-
else
|
199
|
-
begin
|
200
|
-
t.run_test do |rdf_string, parser|
|
201
|
-
parser.parse(rdf_string, t.about.uri.to_s, :strict => true, :debug => [])
|
202
|
-
parser.graph.serialize(:format => :ttl, :base => t.about.uri.to_s)
|
203
|
-
t.compare = :none
|
204
|
-
end
|
205
|
-
#rescue #Spec::Expectations::ExpectationNotMetError => e
|
206
|
-
# pending() { raise }
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
# Serialize ntstr to a string and compare against regexps
|
214
|
-
def serialize(ntstr, base = nil, *regexps)
|
215
|
-
g = Graph.new
|
216
|
-
g.parse(ntstr, base)
|
217
|
-
result = g.serialize(:format => :ttl, :base => base)
|
218
|
-
puts result if $verbose
|
219
|
-
|
220
|
-
regexps.each do |re|
|
221
|
-
result.should =~ re
|
222
|
-
end
|
223
|
-
|
224
|
-
result
|
225
|
-
end
|
226
|
-
end
|