rdf-tabular 3.1.0 → 3.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.
@@ -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'