rdf-tabular 0.1.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.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/README.md +73 -0
- data/UNLICENSE +24 -0
- data/VERSION +1 -0
- data/etc/csvw.jsonld +1507 -0
- data/etc/doap.csv +5 -0
- data/etc/doap.csv-metadata.json +34 -0
- data/etc/doap.ttl +35 -0
- data/lib/rdf/tabular.rb +34 -0
- data/lib/rdf/tabular/csvw.rb +477 -0
- data/lib/rdf/tabular/format.rb +46 -0
- data/lib/rdf/tabular/json.rb +0 -0
- data/lib/rdf/tabular/literal.rb +38 -0
- data/lib/rdf/tabular/metadata.rb +2038 -0
- data/lib/rdf/tabular/reader.rb +591 -0
- data/lib/rdf/tabular/utils.rb +33 -0
- data/lib/rdf/tabular/version.rb +18 -0
- data/spec/format_spec.rb +30 -0
- data/spec/matchers.rb +134 -0
- data/spec/metadata_spec.rb +1716 -0
- data/spec/reader_spec.rb +221 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/suite_helper.rb +161 -0
- data/spec/suite_spec.rb +76 -0
- metadata +269 -0
data/spec/reader_spec.rb
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
require 'rdf/spec/reader'
|
4
|
+
|
5
|
+
describe RDF::Tabular::Reader do
|
6
|
+
let!(:doap) {File.expand_path("../../etc/doap.ttl", __FILE__)}
|
7
|
+
let!(:doap_count) {File.open(doap).each_line.to_a.length}
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
@reader = RDF::Tabular::Reader.new(StringIO.new(""), base_uri: "file:#{File.expand_path("..", __FILE__)}")
|
11
|
+
|
12
|
+
WebMock.stub_request(:any, %r(.*example.org.*)).
|
13
|
+
to_return(lambda {|request|
|
14
|
+
file = request.uri.to_s.split('/').last
|
15
|
+
content_type = case file
|
16
|
+
when /\.json/ then 'application/json'
|
17
|
+
when /\.csv/ then 'text/csv'
|
18
|
+
else 'text/plain'
|
19
|
+
end
|
20
|
+
|
21
|
+
case file
|
22
|
+
when "metadata.json", "country-codes-and-names.csv-metadata.json"
|
23
|
+
{status: 401}
|
24
|
+
else
|
25
|
+
{
|
26
|
+
body: File.read(File.expand_path("../data/#{file}", __FILE__)),
|
27
|
+
status: 200,
|
28
|
+
headers: {'Content-Type' => content_type}
|
29
|
+
}
|
30
|
+
end
|
31
|
+
})
|
32
|
+
|
33
|
+
@debug = []
|
34
|
+
end
|
35
|
+
|
36
|
+
# @see lib/rdf/spec/reader.rb in rdf-spec
|
37
|
+
#include RDF_Reader
|
38
|
+
|
39
|
+
it "should be discoverable" do
|
40
|
+
readers = [
|
41
|
+
RDF::Reader.for(:tabular),
|
42
|
+
RDF::Reader.for("etc/doap.csv"),
|
43
|
+
RDF::Reader.for(file_name: "etc/doap.csv"),
|
44
|
+
RDF::Reader.for(file_extension: "csv"),
|
45
|
+
RDF::Reader.for(content_type: "text/csv"),
|
46
|
+
]
|
47
|
+
readers.each { |reader| expect(reader).to eq RDF::Tabular::Reader }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "Test Files" do
|
51
|
+
test_files = {
|
52
|
+
"tree-ops.csv" => "tree-ops-standard.ttl",
|
53
|
+
"tree-ops.csv-metadata.json" => "tree-ops-standard.ttl",
|
54
|
+
"tree-ops-ext.json" => "tree-ops-ext-standard.ttl",
|
55
|
+
"tree-ops-virtual.json" => "tree-ops-virtual-standard.ttl",
|
56
|
+
"country-codes-and-names.csv" => "country-codes-and-names-standard.ttl",
|
57
|
+
"countries.json" => "countries-standard.ttl",
|
58
|
+
"countries.csv" => "countries.csv-standard.ttl",
|
59
|
+
"roles.json" => "roles-standard.ttl",
|
60
|
+
}
|
61
|
+
context "#each_statement" do
|
62
|
+
test_files.each do |csv, ttl|
|
63
|
+
context csv do
|
64
|
+
let(:about) {RDF::URI("http://example.org").join(csv)}
|
65
|
+
let(:input) {File.expand_path("../data/#{csv}", __FILE__)}
|
66
|
+
|
67
|
+
it "standard mode" do
|
68
|
+
expected = File.expand_path("../data/#{ttl}", __FILE__)
|
69
|
+
RDF::Reader.open(input, format: :tabular, base_uri: about, noProv: true, validate: true, debug: @debug) do |reader|
|
70
|
+
graph = RDF::Graph.new << reader
|
71
|
+
graph2 = RDF::Graph.load(expected, base_uri: about)
|
72
|
+
expect(graph).to be_equivalent_graph(graph2,
|
73
|
+
debug: @debug,
|
74
|
+
id: about,
|
75
|
+
action: about,
|
76
|
+
result: expected,
|
77
|
+
metadata: reader.metadata)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "minimal mode" do
|
82
|
+
ttl = ttl.sub("standard", "minimal")
|
83
|
+
expected = File.expand_path("../data/#{ttl}", __FILE__)
|
84
|
+
RDF::Reader.open(input, format: :tabular, base_uri: about, minimal: true, debug: @debug) do |reader|
|
85
|
+
graph = RDF::Graph.new << reader
|
86
|
+
graph2 = RDF::Graph.load(expected, base_uri: about)
|
87
|
+
expect(graph).to be_equivalent_graph(graph2,
|
88
|
+
debug: @debug,
|
89
|
+
id: about,
|
90
|
+
action: about,
|
91
|
+
result: expected,
|
92
|
+
metadata: reader.metadata)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#to_json" do
|
100
|
+
test_files.each do |csv, ttl|
|
101
|
+
context csv do
|
102
|
+
let(:about) {RDF::URI("http://example.org").join(csv)}
|
103
|
+
let(:input) {File.expand_path("../data/#{csv}", __FILE__)}
|
104
|
+
it "standard mode" do
|
105
|
+
json = ttl.sub("-standard.ttl", "-standard.json")
|
106
|
+
expected = File.expand_path("../data/#{json}", __FILE__)
|
107
|
+
|
108
|
+
RDF::Reader.open(input, format: :tabular, base_uri: about, noProv: true, debug: @debug) do |reader|
|
109
|
+
expect(JSON.parse(reader.to_json)).to produce(
|
110
|
+
JSON.parse(File.read(expected)),
|
111
|
+
debug: @debug,
|
112
|
+
id: about,
|
113
|
+
action: about,
|
114
|
+
result: expected,
|
115
|
+
noProv: true,
|
116
|
+
metadata: reader.metadata
|
117
|
+
)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
it "minimal mode" do
|
122
|
+
json = ttl.sub("-standard.ttl", "-minimal.json")
|
123
|
+
expected = File.expand_path("../data/#{json}", __FILE__)
|
124
|
+
|
125
|
+
RDF::Reader.open(input, format: :tabular, base_uri: about, minimal: true, debug: @debug) do |reader|
|
126
|
+
expect(JSON.parse(reader.to_json)).to produce(
|
127
|
+
JSON.parse(File.read(expected)),
|
128
|
+
debug: @debug,
|
129
|
+
id: about,
|
130
|
+
action: about,
|
131
|
+
result: expected,
|
132
|
+
minimal: true,
|
133
|
+
metadata: reader.metadata
|
134
|
+
)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it "ADT mode", skip: true do
|
139
|
+
json = ttl.sub("-standard.ttl", "-atd.json")
|
140
|
+
expected = File.expand_path("../data/#{json}", __FILE__)
|
141
|
+
|
142
|
+
RDF::Reader.open(input, format: :tabular, base_uri: about, noProv: true, debug: @debug) do |reader|
|
143
|
+
expect(JSON.parse(reader.to_json(atd: true))).to produce(
|
144
|
+
JSON.parse(File.read(expected)),
|
145
|
+
debug: @debug,
|
146
|
+
id: about,
|
147
|
+
action: about,
|
148
|
+
result: expected,
|
149
|
+
noProv: true,
|
150
|
+
metadata: reader.metadata
|
151
|
+
)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "Provenance" do
|
160
|
+
{
|
161
|
+
"country-codes-and-names.csv" => %(
|
162
|
+
PREFIX csvw: <http://www.w3.org/ns/csvw#>
|
163
|
+
PREFIX prov: <http://www.w3.org/ns/prov#>
|
164
|
+
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
165
|
+
ASK WHERE {
|
166
|
+
[ prov:wasGeneratedBy [
|
167
|
+
a prov:Activity;
|
168
|
+
prov:wasAssociatedWith <http://rubygems.org/gems/rdf-tabular>;
|
169
|
+
prov:startedAtTime ?start;
|
170
|
+
prov:endedAtTime ?end;
|
171
|
+
prov:qualifiedUsage [
|
172
|
+
a prov:Usage ;
|
173
|
+
prov:entity <http://example.org/country-codes-and-names.csv> ;
|
174
|
+
prov:hadRole csvw:csvEncodedTabularData
|
175
|
+
];
|
176
|
+
]
|
177
|
+
]
|
178
|
+
FILTER (
|
179
|
+
DATATYPE(?start) = xsd:dateTime &&
|
180
|
+
DATATYPE(?end) = xsd:dateTime
|
181
|
+
)
|
182
|
+
}
|
183
|
+
),
|
184
|
+
"countries.json" => %(
|
185
|
+
PREFIX csvw: <http://www.w3.org/ns/csvw#>
|
186
|
+
PREFIX prov: <http://www.w3.org/ns/prov#>
|
187
|
+
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
188
|
+
ASK WHERE {
|
189
|
+
[ prov:wasGeneratedBy [
|
190
|
+
a prov:Activity;
|
191
|
+
prov:wasAssociatedWith <http://rubygems.org/gems/rdf-tabular>;
|
192
|
+
prov:startedAtTime ?start;
|
193
|
+
prov:endedAtTime ?end;
|
194
|
+
prov:qualifiedUsage [
|
195
|
+
a prov:Usage ;
|
196
|
+
prov:entity <http://example.org/countries.csv>, <http://example.org/country_slice.csv>;
|
197
|
+
prov:hadRole csvw:csvEncodedTabularData
|
198
|
+
], [
|
199
|
+
a prov:Usage ;
|
200
|
+
prov:entity <http://example.org/countries.json> ;
|
201
|
+
prov:hadRole csvw:tabularMetadata
|
202
|
+
];
|
203
|
+
]
|
204
|
+
]
|
205
|
+
FILTER (
|
206
|
+
DATATYPE(?start) = xsd:dateTime &&
|
207
|
+
DATATYPE(?end) = xsd:dateTime
|
208
|
+
)
|
209
|
+
}
|
210
|
+
)
|
211
|
+
}.each do |file, query|
|
212
|
+
it file do
|
213
|
+
about = RDF::URI("http://example.org").join(file)
|
214
|
+
input = File.expand_path("../data/#{file}", __FILE__)
|
215
|
+
graph = RDF::Graph.load(input, format: :tabular, base_uri: about, debug: @debug)
|
216
|
+
|
217
|
+
expect(graph).to pass_query(query, debug: @debug, id: about, action: about)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$:.unshift File.dirname(__FILE__)
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require 'rspec'
|
6
|
+
require 'rspec/its'
|
7
|
+
require 'rdf/isomorphic'
|
8
|
+
require 'rdf/tabular'
|
9
|
+
require 'rdf/turtle'
|
10
|
+
require 'rdf/spec/matchers'
|
11
|
+
require 'json'
|
12
|
+
require 'webmock/rspec'
|
13
|
+
require 'matchers'
|
14
|
+
require 'suite_helper'
|
15
|
+
require 'simplecov'
|
16
|
+
SimpleCov.start
|
17
|
+
|
18
|
+
JSON_STATE = JSON::State.new(
|
19
|
+
:indent => " ",
|
20
|
+
:space => " ",
|
21
|
+
:space_before => "",
|
22
|
+
:object_nl => "\n",
|
23
|
+
:array_nl => "\n"
|
24
|
+
)
|
25
|
+
|
26
|
+
::RSpec.configure do |c|
|
27
|
+
c.filter_run focus: true
|
28
|
+
c.run_all_when_everything_filtered = true
|
29
|
+
c.include(RDF::Spec::Matchers)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Heuristically detect the input stream
|
33
|
+
def detect_format(stream)
|
34
|
+
# Got to look into the file to see
|
35
|
+
if stream.is_a?(IO) || stream.is_a?(StringIO)
|
36
|
+
stream.rewind
|
37
|
+
string = stream.read(1000)
|
38
|
+
stream.rewind
|
39
|
+
else
|
40
|
+
string = stream.to_s
|
41
|
+
end
|
42
|
+
case string
|
43
|
+
when /<html/i then RDF::Microdatea::Reader
|
44
|
+
when /@prefix/i then RDF::Turtle::Reader
|
45
|
+
else RDF::Turtle::Reader
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
$:.unshift "."
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'rdf/turtle'
|
4
|
+
require 'json/ld'
|
5
|
+
require 'open-uri'
|
6
|
+
|
7
|
+
# For now, override RDF::Utils::File.open_file to look for the file locally before attempting to retrieve it
|
8
|
+
module RDF::Util
|
9
|
+
module File
|
10
|
+
REMOTE_PATH = "http://w3c.github.io/csvw/"
|
11
|
+
LOCAL_PATH = ::File.expand_path("../w3c-csvw", __FILE__) + '/'
|
12
|
+
|
13
|
+
class << self
|
14
|
+
alias_method :original_open_file, :open_file
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Override to use Patron for http and https, Kernel.open otherwise.
|
19
|
+
#
|
20
|
+
# @param [String] filename_or_url to open
|
21
|
+
# @param [Hash{Symbol => Object}] options
|
22
|
+
# @option options [Array, String] :headers
|
23
|
+
# HTTP Request headers.
|
24
|
+
# @return [IO] File stream
|
25
|
+
# @yield [IO] File stream
|
26
|
+
def self.open_file(filename_or_url, options = {}, &block)
|
27
|
+
case filename_or_url.to_s
|
28
|
+
when /^file:/
|
29
|
+
path = filename_or_url.to_s[5..-1]
|
30
|
+
Kernel.open(path.to_s, &block)
|
31
|
+
when -> (k) {k =~ %r{^#{REMOTE_PATH}} && ::File.exist?(filename_or_url.to_s.sub(REMOTE_PATH, LOCAL_PATH))}
|
32
|
+
begin
|
33
|
+
#puts "attempt to open #{filename_or_url} locally"
|
34
|
+
localpath = filename_or_url.to_s.sub(REMOTE_PATH, LOCAL_PATH)
|
35
|
+
response = begin
|
36
|
+
::File.open(localpath)
|
37
|
+
rescue Errno::ENOENT
|
38
|
+
Kernel.open(filename_or_url.to_s, "r:utf-8", 'Accept' => "application/ld+json, application/json, text/csv")
|
39
|
+
end
|
40
|
+
document_options = {
|
41
|
+
base_uri: RDF::URI(filename_or_url),
|
42
|
+
charset: Encoding::UTF_8,
|
43
|
+
code: 200,
|
44
|
+
headers: {}
|
45
|
+
}
|
46
|
+
#puts "use #{filename_or_url} locally"
|
47
|
+
document_options[:headers][:content_type] = case filename_or_url.to_s
|
48
|
+
when /\.csv$/ then 'text/csv'
|
49
|
+
when /\.json$/ then 'application/json'
|
50
|
+
when /\.jsonld$/ then 'application/ld+json'
|
51
|
+
else 'unknown'
|
52
|
+
end
|
53
|
+
|
54
|
+
document_options[:headers][:content_type] = response.content_type if response.respond_to?(:content_type)
|
55
|
+
# For overriding content type from test data
|
56
|
+
document_options[:headers][:content_type] = options[:contentType] if options[:contentType]
|
57
|
+
|
58
|
+
# For overriding Link header from test data
|
59
|
+
document_options[:headers][:link] = options[:httpLink] if options[:httpLink]
|
60
|
+
|
61
|
+
remote_document = RDF::Util::File::RemoteDocument.new(response.read, document_options)
|
62
|
+
if block_given?
|
63
|
+
yield remote_document
|
64
|
+
else
|
65
|
+
remote_document
|
66
|
+
end
|
67
|
+
end
|
68
|
+
else
|
69
|
+
original_open_file(filename_or_url, options, &block)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
module Fixtures
|
76
|
+
module SuiteTest
|
77
|
+
BASE = "http://w3c.github.io/csvw/tests/"
|
78
|
+
class Manifest < JSON::LD::Resource
|
79
|
+
def self.open(file, base)
|
80
|
+
#puts "open: #{file}"
|
81
|
+
RDF::Util::File.open_file(file) do |file|
|
82
|
+
json = ::JSON.load(file.read)
|
83
|
+
yield Manifest.new(json, context: json['@context'].merge('@base' => base))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def entries
|
88
|
+
# Map entries to resources
|
89
|
+
attributes['entries'].map {|e| Entry.new(e, context: context)}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class Entry < JSON::LD::Resource
|
94
|
+
attr_accessor :debug
|
95
|
+
attr_accessor :metadata
|
96
|
+
|
97
|
+
def id
|
98
|
+
attributes['id']
|
99
|
+
end
|
100
|
+
|
101
|
+
def base
|
102
|
+
action
|
103
|
+
end
|
104
|
+
|
105
|
+
# Apply base to action and result
|
106
|
+
def action
|
107
|
+
RDF::URI(context['@base']).join(attributes["action"]).to_s
|
108
|
+
end
|
109
|
+
|
110
|
+
def result
|
111
|
+
RDF::URI(context['@base']).join(attributes["result"]).to_s
|
112
|
+
end
|
113
|
+
|
114
|
+
def input
|
115
|
+
@input ||= RDF::Util::File.open_file(action) {|f| f.read}
|
116
|
+
end
|
117
|
+
|
118
|
+
def expected
|
119
|
+
@expected ||= RDF::Util::File.open_file(result) {|f| f.read}
|
120
|
+
end
|
121
|
+
|
122
|
+
def evaluate?
|
123
|
+
type.include?("To")
|
124
|
+
end
|
125
|
+
|
126
|
+
def sparql?
|
127
|
+
type.include?("Sparql")
|
128
|
+
end
|
129
|
+
|
130
|
+
def rdf?
|
131
|
+
result.to_s.end_with?(".ttl")
|
132
|
+
end
|
133
|
+
|
134
|
+
def json?
|
135
|
+
result.to_s.end_with?(".json")
|
136
|
+
end
|
137
|
+
|
138
|
+
def validation?
|
139
|
+
type.include?("Validation")
|
140
|
+
end
|
141
|
+
|
142
|
+
def positive_test?
|
143
|
+
!negative_test?
|
144
|
+
end
|
145
|
+
|
146
|
+
def negative_test?
|
147
|
+
type.include?("Negative")
|
148
|
+
end
|
149
|
+
|
150
|
+
def reader_options
|
151
|
+
res = {}
|
152
|
+
res[:noProv] = option['noProv'] if option
|
153
|
+
res[:metadata] = RDF::URI(context['@base']).join(option['metadata']).to_s if option && option.has_key?('metadata')
|
154
|
+
res[:httpLink] = httpLink if attributes['httpLink']
|
155
|
+
res[:minimal] = option['minimal'] if option
|
156
|
+
res[:contentType] = contentType if attributes['contentType']
|
157
|
+
res
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
data/spec/suite_spec.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
$:.unshift "."
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
WebMock.allow_net_connect!(net_http_connect_on_start: true)
|
6
|
+
describe RDF::Tabular::Reader do
|
7
|
+
require 'suite_helper'
|
8
|
+
|
9
|
+
before(:all) {WebMock.allow_net_connect!(net_http_connect_on_start: true)}
|
10
|
+
after(:all) {WebMock.allow_net_connect!(net_http_connect_on_start: false)}
|
11
|
+
|
12
|
+
%w(rdf json validation).each do |variant|
|
13
|
+
describe "w3c csvw #{variant.upcase} tests" do
|
14
|
+
manifest = Fixtures::SuiteTest::BASE + "manifest-#{variant}.jsonld"
|
15
|
+
|
16
|
+
Fixtures::SuiteTest::Manifest.open(manifest, manifest[0..-8]) do |m|
|
17
|
+
describe m.comment do
|
18
|
+
m.entries.each do |t|
|
19
|
+
specify "#{t.id.split("/").last}: #{t.name} - #{t.comment}" do
|
20
|
+
t.debug = []
|
21
|
+
RDF::Tabular::Reader.open(t.action,
|
22
|
+
t.reader_options.merge(
|
23
|
+
base_uri: t.base,
|
24
|
+
validate: t.validation?,
|
25
|
+
debug: t.debug
|
26
|
+
)
|
27
|
+
) do |reader|
|
28
|
+
expect(reader).to be_a RDF::Reader
|
29
|
+
|
30
|
+
t.metadata = reader.metadata # for debug output
|
31
|
+
t.metadata = t.metadata.parent if t.metadata && t.metadata.parent
|
32
|
+
|
33
|
+
graph = RDF::Repository.new
|
34
|
+
|
35
|
+
if t.positive_test?
|
36
|
+
if t.json?
|
37
|
+
result = reader.to_json
|
38
|
+
if t.evaluate?
|
39
|
+
RDF::Util::File.open_file(t.result) do |res|
|
40
|
+
expect(::JSON.parse(result)).to produce(::JSON.parse(res.read), t)
|
41
|
+
end
|
42
|
+
else
|
43
|
+
expect(::JSON.parse(result)).to be_a(Hash)
|
44
|
+
end
|
45
|
+
else # RDF or Validation
|
46
|
+
begin
|
47
|
+
graph << reader
|
48
|
+
rescue Exception => e
|
49
|
+
expect(e.message).to produce("Not exception #{e.inspect}\n#{e.backtrace.join("\n")}", t.debug)
|
50
|
+
end
|
51
|
+
|
52
|
+
if t.sparql?
|
53
|
+
RDF::Util::File.open_file(t.result) do |query|
|
54
|
+
expect(graph).to pass_query(query, t)
|
55
|
+
end
|
56
|
+
elsif t.evaluate?
|
57
|
+
output_graph = RDF::Repository.load(t.result, format: :ttl, base_uri: t.base)
|
58
|
+
expect(graph).to be_equivalent_graph(output_graph, t)
|
59
|
+
else
|
60
|
+
expect(graph).to be_a(RDF::Enumerable)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
else
|
64
|
+
expect {
|
65
|
+
graph << reader
|
66
|
+
expect(graph.dump(:ntriples)).to produce("not this", t.debug)
|
67
|
+
}.to raise_error(RDF::Tabular::Error)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end unless ENV['CI'] # Skip for continuous integration
|