rdf-tabular 3.1.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -22,7 +22,7 @@ module RDF::Tabular
22
22
  # @example Obtaining serialization format file extension mappings
23
23
  # RDF::Format.file_extensions #=> {:csv => "text/csv"}
24
24
  #
25
- # @see http://www.w3.org/TR/rdf-testcases/#ntriples
25
+ # @see https://www.w3.org/TR/rdf-testcases/#ntriples
26
26
  class Format < RDF::Format
27
27
  content_type 'text/csv;q=0.4',
28
28
  extensions: [:csv, :tsv],
@@ -62,7 +62,7 @@ module RDF::Tabular
62
62
  raise ArgumentError, "Outputting Tabular JSON only allowed when input format is tabular." unless opts[:format] == :tabular
63
63
  out = opts[:output] || $stdout
64
64
  out.set_encoding(Encoding::UTF_8) if RUBY_PLATFORM == "java"
65
- RDF::CLI.parse(argv, opts) do |reader|
65
+ RDF::CLI.parse(argv, **opts) do |reader|
66
66
  out.puts reader.to_json
67
67
  end
68
68
  end
@@ -16,7 +16,7 @@ require 'yaml' # used by BCP47, which should have required it.
16
16
  # * Return Column-level annotations
17
17
  # * Return row iterator with column information
18
18
  #
19
- # @author [Gregg Kellogg](http://greggkellogg.net/)
19
+ # @author [Gregg Kellogg](https://greggkellogg.net/)
20
20
  module RDF::Tabular
21
21
  class Metadata
22
22
  include RDF::Util::Logger
@@ -142,7 +142,7 @@ module RDF::Tabular
142
142
  'Accept' => 'application/ld+json, application/json'
143
143
  }
144
144
  )
145
- path = "file:" + path unless path =~ /^\w+:/
145
+ path = "file:#{path}" if RDF::URI(path).relative?
146
146
  RDF::Util::File.open_file(path, **options) do |file|
147
147
  self.new(file, **options.merge(base: path, filenames: path))
148
148
  end
@@ -209,7 +209,9 @@ module RDF::Tabular
209
209
  log_debug("for_input", **options) {"templates: #{templates.map(&:to_s).inspect}"}
210
210
  locs = templates.map do |template|
211
211
  t = Addressable::Template.new(template)
212
- RDF::URI(base).join(t.expand(url: base).to_s)
212
+ mapped = t.expand(url: base).to_s
213
+ mapped = RDF::URI.decode(mapped) if options[:decode_uri]
214
+ RDF::URI(base).join(mapped)
213
215
  end
214
216
  log_debug("for_input", **options) {"locs: #{locs.map(&:to_s).inspect}"}
215
217
 
@@ -314,6 +316,8 @@ module RDF::Tabular
314
316
  # Context used for this metadata. Taken from input if not provided
315
317
  # @option options [RDF::URI] :base
316
318
  # The Base URL to use when expanding the document. This overrides the value of `input` if it is a URL. If not specified and `input` is not an URL, the base URL defaults to the current document URL if in a browser context, or the empty string if there is no document context.
319
+ # @option options [Boolean] :decode_uri
320
+ # Decode %-encodings in the result of a URI Template operation.
317
321
  # @option options [Boolean] :normalize normalize the object
318
322
  # @option options [Boolean] :validate Strict metadata validation
319
323
  # @raise [Error]
@@ -1947,13 +1951,14 @@ module RDF::Tabular
1947
1951
  class Row
1948
1952
  # Class for returning values
1949
1953
  Cell = Struct.new(:table, :column, :row, :stringValue, :aboutUrl, :propertyUrl, :valueUrl, :value, :errors) do
1950
- def set_urls(mapped_values)
1954
+ def set_urls(mapped_values, decode_uri)
1951
1955
  %w(aboutUrl propertyUrl valueUrl).each do |prop|
1952
1956
  # If the cell value is nil, and it is not a virtual column
1953
1957
  next if prop == "valueUrl" && value.nil? && !column.virtual
1954
1958
  if v = column.send(prop.to_sym)
1955
1959
  t = Addressable::Template.new(v)
1956
1960
  mapped = t.expand(mapped_values).to_s
1961
+ mapped = RDF::URI.decode(mapped) if decode_uri
1957
1962
  # FIXME: don't expand here, do it in CSV2RDF
1958
1963
  url = row.context.expand_iri(mapped, documentRelative: true)
1959
1964
  self.send("#{prop}=".to_sym, url)
@@ -2114,7 +2119,7 @@ module RDF::Tabular
2114
2119
  "_column" => cell.column.number,
2115
2120
  "_sourceColumn" => cell.column.sourceNumber
2116
2121
  )
2117
- cell.set_urls(mapped_values)
2122
+ cell.set_urls(mapped_values, options[:decode_uri])
2118
2123
  end
2119
2124
  end
2120
2125
 
@@ -5,7 +5,7 @@ module RDF::Tabular
5
5
  ##
6
6
  # A Tabular Data to RDF parser in Ruby.
7
7
  #
8
- # @author [Gregg Kellogg](http://greggkellogg.net/)
8
+ # @author [Gregg Kellogg](https://greggkellogg.net/)
9
9
  class Reader < RDF::Reader
10
10
  format Format
11
11
  include RDF::Util::Logger
@@ -22,7 +22,7 @@ module RDF::Tabular
22
22
 
23
23
  ##
24
24
  # Writer options
25
- # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Writer#options-class_method
25
+ # @see https://ruby-rdf.github.io/rdf/RDF/Writer#options-class_method
26
26
  def self.options
27
27
  super + [
28
28
  RDF::CLI::Option.new(
@@ -43,6 +43,13 @@ module RDF::Tabular
43
43
  control: :checkbox,
44
44
  on: ["--no-prov"],
45
45
  description: "do not output optional provenance information.") {true},
46
+ RDF::CLI::Option.new(
47
+ symbol: :decode_uri,
48
+ datatype: TrueClass,
49
+ control: :checkbox,
50
+ on: ["--decode-uri"],
51
+ description: "decode %-encodings in the result of a URI Template operation."
52
+ )
46
53
  ]
47
54
  end
48
55
 
@@ -54,11 +61,13 @@ module RDF::Tabular
54
61
  # or an Array used as an internalized array of arrays
55
62
  # @param [Hash{Symbol => Object}] options
56
63
  # any additional options (see `RDF::Reader#initialize`)
64
+ # @option options [Boolean] :decode_uri
65
+ # Decode %-encodings in the result of a URI Template operation.
66
+ # @option options [Array<Hash>] :fks_referencing_table
67
+ # When called with Table metadata, a list of the foreign keys referencing this table
57
68
  # @option options [Metadata, Hash, String, RDF::URI] :metadata user supplied metadata, merged on top of extracted metadata. If provided as a URL, Metadata is loade from that location
58
69
  # @option options [Boolean] :minimal includes only the information gleaned from the cells of the tabular data
59
70
  # @option options [Boolean] :noProv do not output optional provenance information
60
- # @option optinons [Array<Hash>] :fks_referencing_table
61
- # When called with Table metadata, a list of the foreign keys referencing this table
62
71
  # @yield [reader] `self`
63
72
  # @yieldparam [RDF::Reader] reader
64
73
  # @yieldreturn [void] ignored
@@ -71,7 +80,8 @@ module RDF::Tabular
71
80
  @options[:base] ||= input.path if input.respond_to?(:path)
72
81
  @options[:base] ||= input.filename if input.respond_to?(:filename)
73
82
  if RDF::URI(@options[:base]).relative? && File.exist?(@options[:base].to_s)
74
- @options[:base] = "file:/#{File.expand_path(@options[:base])}"
83
+ file_uri = "file:" + File.expand_path(@options[:base])
84
+ @options[:base] = RDF::URI(file_uri.to_s).normalize
75
85
  end
76
86
 
77
87
  log_debug("Reader#initialize") {"input: #{input.inspect}, base: #{@options[:base]}"}
@@ -225,7 +235,7 @@ module RDF::Tabular
225
235
  activity = RDF::Node.new
226
236
  add_statement(0, table_group, RDF::Vocab::PROV.wasGeneratedBy, activity)
227
237
  add_statement(0, activity, RDF.type, RDF::Vocab::PROV.Activity)
228
- add_statement(0, activity, RDF::Vocab::PROV.wasAssociatedWith, RDF::URI("http://rubygems.org/gems/rdf-tabular"))
238
+ add_statement(0, activity, RDF::Vocab::PROV.wasAssociatedWith, RDF::URI("https://rubygems.org/gems/rdf-tabular"))
229
239
  add_statement(0, activity, RDF::Vocab::PROV.startedAtTime, RDF::Literal::DateTime.new(start_time))
230
240
  add_statement(0, activity, RDF::Vocab::PROV.endedAtTime, RDF::Literal::DateTime.new(Time.now))
231
241
 
@@ -3,7 +3,7 @@ module RDF::Tabular
3
3
  ##
4
4
  # Utilities for parsing UAX35 dates and numbers.
5
5
  #
6
- # @see http://www.unicode.org/reports/tr35
6
+ # @see https://www.unicode.org/reports/tr35
7
7
  module UAX35
8
8
 
9
9
  ##
data/lib/rdf/tabular.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  $:.unshift(File.expand_path("..", __FILE__))
2
- require 'rdf' # @see http://rubygems.org/gems/rdf
2
+ require 'rdf' # @see https://rubygems.org/gems/rdf
3
3
  require 'csv'
4
4
 
5
5
  module RDF
6
6
  ##
7
7
  # **`RDF::Tabular`** is a Tabular/CSV extension for RDF.rb.
8
8
  #
9
- # @see http://w3c.github.io/csvw/
9
+ # @see https://w3c.github.io/csvw/
10
10
  #
11
- # @author [Gregg Kellogg](http://greggkellogg.net/)
11
+ # @author [Gregg Kellogg](https://greggkellogg.net/)
12
12
  module Tabular
13
13
  require 'rdf/tabular/format'
14
14
  autoload :Column, 'rdf/tabular/metadata'
@@ -1082,6 +1082,89 @@ describe RDF::Tabular::Metadata do
1082
1082
  end
1083
1083
  end
1084
1084
  end
1085
+
1086
+ context "virtual columns" do
1087
+ subject {
1088
+ described_class.new(JSON.parse(%({
1089
+ "@context": "http://www.w3.org/ns/csvw",
1090
+ "url": "https://example.org/countries.csv",
1091
+ "aboutUrl": "https://example.org/countries",
1092
+ "@type": "Table",
1093
+ "tableSchema": {
1094
+ "@type": "Schema",
1095
+ "columns": [{
1096
+ "name": "countryCode",
1097
+ "titles": "countryCode",
1098
+ "propertyUrl": "https://example.org/countries.csv#countryCode"
1099
+ }, {
1100
+ "name": "latitude",
1101
+ "titles": "latitude",
1102
+ "propertyUrl": "https://example.org/countries.csv#latitude"
1103
+ }, {
1104
+ "name": "longitude",
1105
+ "titles": "longitude",
1106
+ "propertyUrl": "https://example.org/countries.csv#longitude"
1107
+ }, {
1108
+ "name": "name",
1109
+ "titles": "name",
1110
+ "propertyUrl": "https://example.org/countries.csv#name"
1111
+ }, {
1112
+ "virtual": true,
1113
+ "propertyUrl": "https://example.org/countries.csv#virt1",
1114
+ "valueUrl": "https://example.org/countries.csv#virt1"
1115
+ }, {
1116
+ "virtual": true,
1117
+ "propertyUrl": "https://example.org/countries.csv#virt2",
1118
+ "default": "default",
1119
+ "datatype": "string"
1120
+ }]
1121
+ }
1122
+ })), base: RDF::URI("http://example.org/base"), logger: logger)
1123
+ }
1124
+ let(:input) {RDF::Util::File.open_file("https://example.org/countries.csv")}
1125
+ let(:rows) {subject.to_enum(:each_row, input).to_a}
1126
+
1127
+ it "has expected aboutUrls" do
1128
+ subject.each_row(input) do |row|
1129
+ expect(row.values[0].aboutUrl).to eq "https://example.org/countries"
1130
+ expect(row.values[1].aboutUrl).to eq "https://example.org/countries"
1131
+ expect(row.values[2].aboutUrl).to eq "https://example.org/countries"
1132
+ expect(row.values[3].aboutUrl).to eq "https://example.org/countries"
1133
+ expect(row.values[4].aboutUrl).to eq "https://example.org/countries"
1134
+ expect(row.values[5].aboutUrl).to eq "https://example.org/countries"
1135
+ end
1136
+ end
1137
+
1138
+ it "has expected propertyUrls" do
1139
+ subject.each_row(input) do |row|
1140
+ expect(row.values[0].propertyUrl).to eq "https://example.org/countries.csv#countryCode"
1141
+ expect(row.values[1].propertyUrl).to eq "https://example.org/countries.csv#latitude"
1142
+ expect(row.values[2].propertyUrl).to eq "https://example.org/countries.csv#longitude"
1143
+ expect(row.values[3].propertyUrl).to eq "https://example.org/countries.csv#name"
1144
+ expect(row.values[4].propertyUrl).to eq "https://example.org/countries.csv#virt1"
1145
+ expect(row.values[5].propertyUrl).to eq "https://example.org/countries.csv#virt2"
1146
+ end
1147
+ end
1148
+
1149
+ it "has expected valueUrls" do
1150
+ subject.each_row(input) do |row|
1151
+ expect(row.values[0].valueUrl).to be_nil
1152
+ expect(row.values[1].valueUrl).to be_nil
1153
+ expect(row.values[2].valueUrl).to be_nil
1154
+ expect(row.values[3].valueUrl).to be_nil
1155
+ expect(row.values[4].valueUrl).to eq "https://example.org/countries.csv#virt1"
1156
+ expect(row.values[5].valueUrl).to be_nil
1157
+ end
1158
+ end
1159
+
1160
+ it "has expected values" do
1161
+ rows = subject.to_enum(:each_row, input).to_a
1162
+ expect(rows[0].values.map(&:to_s)).to produce(%w(AD 42.546245 1.601554 Andorra).push("", "default"), logger)
1163
+ expect(rows[1].values.map(&:to_s)).to produce((%w(AE 23.424076 53.847818).push("United Arab Emirates", "", "default")), logger)
1164
+ expect(rows[2].values.map(&:to_s)).to produce(%w(AF 33.93911 67.709953 Afghanistan).push("", "default"), logger)
1165
+ end
1166
+ end
1167
+
1085
1168
  end
1086
1169
 
1087
1170
  context "datatypes" do
data/spec/reader_spec.rb CHANGED
@@ -308,7 +308,7 @@ describe RDF::Tabular::Reader do
308
308
  ASK WHERE {
309
309
  [ prov:wasGeneratedBy [
310
310
  a prov:Activity;
311
- prov:wasAssociatedWith <http://rubygems.org/gems/rdf-tabular>;
311
+ prov:wasAssociatedWith <https://rubygems.org/gems/rdf-tabular>;
312
312
  prov:startedAtTime ?start;
313
313
  prov:endedAtTime ?end;
314
314
  prov:qualifiedUsage [
@@ -331,7 +331,7 @@ describe RDF::Tabular::Reader do
331
331
  ASK WHERE {
332
332
  [ prov:wasGeneratedBy [
333
333
  a prov:Activity;
334
- prov:wasAssociatedWith <http://rubygems.org/gems/rdf-tabular>;
334
+ prov:wasAssociatedWith <https://rubygems.org/gems/rdf-tabular>;
335
335
  prov:startedAtTime ?start;
336
336
  prov:endedAtTime ?end;
337
337
  prov:qualifiedUsage [
data/spec/spec_helper.rb CHANGED
@@ -13,14 +13,26 @@ require 'json'
13
13
  require 'webmock/rspec'
14
14
  require 'matchers'
15
15
  require 'suite_helper'
16
- require 'simplecov'
17
- require 'coveralls'
18
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
19
- SimpleCov::Formatter::HTMLFormatter,
20
- Coveralls::SimpleCov::Formatter
21
- ])
22
- SimpleCov.start do
23
- add_filter "/spec/"
16
+
17
+ begin
18
+ require 'simplecov'
19
+ require 'simplecov-lcov'
20
+
21
+ SimpleCov::Formatter::LcovFormatter.config do |config|
22
+ #Coveralls is coverage by default/lcov. Send info results
23
+ config.report_with_single_file = true
24
+ config.single_report_path = 'coverage/lcov.info'
25
+ end
26
+
27
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
28
+ SimpleCov::Formatter::HTMLFormatter,
29
+ SimpleCov::Formatter::LcovFormatter
30
+ ])
31
+ SimpleCov.start do
32
+ add_filter "/spec/"
33
+ end
34
+ rescue LoadError => e
35
+ STDERR.puts "Coverage Skipped: #{e.message}"
24
36
  end
25
37
 
26
38
  require 'rdf/tabular'