spec/metadata_spec.rb in rdf-tabular-0.1.2 vs spec/metadata_spec.rb in rdf-tabular-0.1.3
- old
+ new
@@ -27,52 +27,56 @@
@debug = []
end
shared_examples "inherited properties" do |allowed = true|
{
- null: {
- valid: ["foo", %w(foo bar)],
- invalid: [1, true, {}]
+ aboutUrl: {
+ valid: ["http://example.org/example.csv#row={_row}", "http://example.org/tree/{on%2Dstreet}/{GID}", "#row.{_row}"],
+ invalid: [1, true, nil, %w(foo bar)]
},
+ datatype: {
+ valid: (%w(anyAtomicType string token language Name NCName boolean gYear number binary datetime any xml html json) +
+ [{"base" => "string"}]
+ ),
+ invalid: [1, true, "foo", "anyType", "anySimpleType", "IDREFS"]
+ },
+ default: {
+ valid: ["foo"],
+ invalid: [1, %w(foo bar), true, nil]
+ },
lang: {
valid: %w(en en-US),
invalid: %w(1 foo)
},
- "textDirection" => {
- valid: %w(rtl ltr),
- invalid: %w(foo default)
+ null: {
+ valid: ["foo", %w(foo bar)],
+ invalid: [1, true, {}]
},
- separator: {
- valid: %w(, a | :) + [nil],
- invalid: [1, false] + %w(foo ::)
- },
ordered: {
valid: [true, false],
invalid: [nil, "foo", 1, 0, "true", "false", "TrUe", "fAlSe", "1", "0"],
},
- default: {
- valid: ["foo"],
- invalid: [1, %w(foo bar), true, nil]
- },
- datatype: {
- valid: (%w(anyAtomicType string token language Name NCName boolean gYear number binary datetime any xml html json) +
- [{"base" => "string"}]
- ),
- invalid: [1, true, "foo", "anyType", "anySimpleType", "IDREFS"]
- },
- aboutUrl: {
- valid: ["http://example.org/example.csv#row={_row}", "http://example.org/tree/{on%2Dstreet}/{GID}", "#row.{_row}"],
- invalid: [1, true, nil, %w(foo bar)]
- },
propertyUrl: {
valid: [
"http://example.org/example.csv#col={_name}",
"http://example.org/tree/{on%2Dstreet}/{GID}",
"#row.{_row}"
],
invalid: [1, true, %w(foo bar)]
},
+ required: {
+ valid: [true, false],
+ invalid: [nil, "foo", 1, 0, "true", "false", "TrUe", "fAlSe", "1", "0"],
+ },
+ separator: {
+ valid: %w(, a | :) + [nil],
+ invalid: [1, false] + %w(foo ::)
+ },
+ "textDirection" => {
+ valid: %w(rtl ltr),
+ invalid: %w(foo default)
+ },
valueUrl: {
valid: [
"http://example.org/example.csv#row={_row}",
"http://example.org/tree/{on%2Dstreet}/{GID}",
"#row.{_row}"
@@ -176,11 +180,11 @@
end
end
end
describe RDF::Tabular::Column do
- subject {described_class.new({"name" => "foo"}, base: RDF::URI("http://example.org/base"), debug: @debug)}
+ subject {described_class.new({"name" => "foo"}, context: "http://www.w3.org/ns/csvw", base: RDF::URI("http://example.org/base"), debug: @debug)}
specify {is_expected.to be_valid}
it_behaves_like("inherited properties")
it_behaves_like("common properties")
it "allows valid name" do
@@ -188,11 +192,14 @@
name abc.123 _col.1
).each {|v| expect(described_class.new("name" => v)).to be_valid}
end
it "detects invalid names" do
- [1, true, nil, "_foo", "_col=1"].each {|v| expect(described_class.new("name" => v)).not_to be_valid}
+ [1, true, nil, "_foo", "_col=1"].each do |v|
+ md = described_class.new("name" => v)
+ expect(md.warnings).not_to be_empty
+ end
end
it "allows absence of name" do
expect(described_class.new("@type" => "Column")).to be_valid
expect(described_class.new("@type" => "Column").name).to eql '_col.0'
@@ -201,16 +208,12 @@
its(:type) {is_expected.to eql :Column}
{
titles: {
valid: ["foo", %w(foo bar), {"en" => "foo", "de" => "bar"}],
- invalid: [1, true, nil]
+ warning: [1, true, nil]
},
- required: {
- valid: [true, false],
- warning: [nil, "foo", 1, 0, "true", "false", "TrUe", "fAlSe", "1", "0"],
- },
suppressOutput: {
valid: [true, false],
warning: [nil, "foo", 1, 0, "true", "false", "TrUe", "fAlSe", "1", "0"],
},
virtual: {
@@ -245,18 +248,18 @@
{
string: ["foo", {"und" => ["foo"]}],
}.each do |name, (input, output)|
it name do
subject.titles = input
- expect(subject.titles).to produce(output)
+ expect(subject.normalize!.titles).to produce(output)
end
end
end
end
describe RDF::Tabular::Schema do
- subject {described_class.new({}, base: RDF::URI("http://example.org/base"), debug: @debug)}
+ subject {described_class.new({}, context: "http://www.w3.org/ns/csvw", base: RDF::URI("http://example.org/base"), debug: @debug)}
specify {is_expected.to be_valid}
it_behaves_like("inherited properties")
it_behaves_like("common properties")
its(:type) {is_expected.to eql :Schema}
@@ -272,11 +275,11 @@
expect(v.errors).to be_empty
end
it "is invalid with an invalid column" do
v = described_class.new({"columns" => [{"name" => "_invalid"}]}, base: RDF::URI("http://example.org/base"), debug: @debug)
- expect(v.errors).not_to be_empty
+ expect(v.warnings).not_to be_empty
end
it "is invalid with an non-unique columns" do
v = described_class.new({"columns" => [column, column]}, base: RDF::URI("http://example.org/base"), debug: @debug)
expect(v.errors).not_to be_empty
@@ -423,33 +426,41 @@
end
describe RDF::Tabular::Transformation do
let(:targetFormat) {"http://example.org/targetFormat"}
let(:scriptFormat) {"http://example.org/scriptFormat"}
- subject {described_class.new({"url" => "http://example/", "targetFormat" => targetFormat, "scriptFormat" => scriptFormat}, base: RDF::URI("http://example.org/base"), debug: @debug)}
+ subject {
+ described_class.new({
+ "url" => "http://example/",
+ "targetFormat" => targetFormat,
+ "scriptFormat" => scriptFormat},
+ context: "http://www.w3.org/ns/csvw",
+ base: RDF::URI("http://example.org/base"),
+ debug: @debug)
+ }
specify {is_expected.to be_valid}
it_behaves_like("inherited properties", false)
it_behaves_like("common properties")
its(:type) {is_expected.to eql :Transformation}
{
source: {
valid: %w(json rdf) + [nil],
- invalid: [1, true, {}]
+ warning: [1, true, {}]
},
}.each do |prop, params|
context prop.to_s do
it "validates" do
params[:valid].each do |v|
subject.send("#{prop}=".to_sym, v)
expect(subject).to be_valid
end
end
- it "invalidates" do
- params[:invalid].each do |v|
+ it "warnings" do
+ params[:warning].each do |v|
subject.send("#{prop}=".to_sym, v)
- expect(subject).not_to be_valid
+ expect(subject.warnings).not_to be_empty
end
end
end
end
@@ -457,24 +468,24 @@
{
string: ["foo", {"und" => ["foo"]}],
}.each do |name, (input, output)|
it name do
subject.titles = input
- expect(subject.titles).to produce(output)
+ expect(subject.normalize!.titles).to produce(output)
end
end
end
end
describe RDF::Tabular::Dialect do
- subject {described_class.new({}, base: RDF::URI("http://example.org/base"), debug: @debug)}
+ subject {described_class.new({}, context: "http://www.w3.org/ns/csvw", base: RDF::URI("http://example.org/base"), debug: @debug)}
specify {is_expected.to be_valid}
it_behaves_like("inherited properties", false)
it_behaves_like("common properties", false)
its(:type) {is_expected.to eql :Dialect}
- described_class.const_get(:DIALECT_DEFAULTS).each do |p, v|
+ described_class.const_get(:DEFAULTS).each do |p, v|
context "#{p}" do
it "retrieves #{v.inspect} by default" do
expect(subject.send(p)).to eql v
end
@@ -543,50 +554,53 @@
})
},
}.each do |name, props|
it name do
dialect = if props[:dialect]
- described_class.new(props[:dialect], base: RDF::URI("http://example.org/base"), debug: @debug)
+ described_class.new(props[:dialect], debug: @debug)
else
subject
end
- result = dialect.embedded_metadata(props[:input])
+ result = dialect.embedded_metadata(props[:input], nil, base: RDF::URI("http://example.org/base"))
expect(::JSON.parse(result.to_json(JSON_STATE))).to produce(::JSON.parse(props[:result]), @debug)
end
end
end
end
describe RDF::Tabular::Table do
- subject {described_class.new({"url" => "http://example.org/table.csv"}, base: RDF::URI("http://example.org/base"), debug: @debug)}
+ subject {described_class.new({"url" => "http://example.org/table.csv"}, context: "http://www.w3.org/ns/csvw", base: RDF::URI("http://example.org/base"), debug: @debug)}
specify {is_expected.to be_valid}
it_behaves_like("inherited properties")
it_behaves_like("common properties")
its(:type) {is_expected.to eql :Table}
+ describe "#to_table_group" do
+ end
+
{
tableSchema: {
valid: [RDF::Tabular::Schema.new({})],
- invalid: [1, true, nil]
+ warning: [1, true, nil]
},
notes: {
valid: [{}, [{}]],
invalid: [1, true, nil]
},
tableDirection: {
valid: %w(rtl ltr default),
- invalid: %w(foo true 1)
+ warning: %w(foo true 1)
},
transformations: {
valid: [[RDF::Tabular::Transformation.new(url: "http://example", targetFormat: "http://example", scriptFormat: "http://example/")]],
- invalid: [RDF::Tabular::Transformation.new(url: "http://example", targetFormat: "http://example", scriptFormat: "http://example/")] +
+ warning: [RDF::Tabular::Transformation.new(url: "http://example", targetFormat: "http://example", scriptFormat: "http://example/")] +
%w(foo true 1)
},
dialect: {
valid: [{skipRows: 1}],
- invalid: ["http://location-of-dialect", "foo"]
+ warning: [1]
},
suppressOutput: {
valid: [true, false],
warning: [nil, "foo", 1, 0, "true", "false", "TrUe", "fAlSe", "1", "0"],
},
@@ -615,34 +629,32 @@
end
end
describe RDF::Tabular::TableGroup do
let(:table) {{"url" => "http://example.org/table.csv"}}
- subject {described_class.new({"tables" => [table]}, base: RDF::URI("http://example.org/base"), debug: @debug)}
+ subject {described_class.new({"tables" => [table]}, context: "http://www.w3.org/ns/csvw", base: RDF::URI("http://example.org/base"), debug: @debug)}
specify {is_expected.to be_valid}
it_behaves_like("inherited properties")
it_behaves_like("common properties")
its(:type) {is_expected.to eql :TableGroup}
-
-
{
tableSchema: {
valid: [RDF::Tabular::Schema.new({})],
- invalid: [1, true, nil]
+ warning: [1, true, nil]
},
tableDirection: {
valid: %w(rtl ltr default),
- invalid: %w(foo true 1)
+ warning: %w(foo true 1)
},
dialect: {
valid: [{skipRows: 1}],
- invalid: ["http://location-of-dialect", "foo"]
+ warning: [1]
},
transformations: {
valid: [[RDF::Tabular::Transformation.new(url: "http://example", targetFormat: "http://example", scriptFormat: "http://example/")]],
- invalid: [RDF::Tabular::Transformation.new(url: "http://example", targetFormat: "http://example", scriptFormat: "http://example/")] +
+ warning: [RDF::Tabular::Transformation.new(url: "http://example", targetFormat: "http://example", scriptFormat: "http://example/")] +
%w(foo true 1)
},
notes: {
valid: [{}, [{}]],
invalid: [1, true, nil]
@@ -658,11 +670,18 @@
it "invalidates" do
params[:invalid].each do |v|
subject.send("#{prop}=".to_sym, v)
expect(subject).not_to be_valid
end
- end
+ end if params[:invalid]
+ it "warnings" do
+ params[:warning].each do |v|
+ subject.send("#{prop}=".to_sym, v)
+ expect(subject).to be_valid
+ expect(subject.warnings).not_to be_empty
+ end
+ end if params[:warning]
end
end
end
context "parses example metadata" do
@@ -757,11 +776,10 @@
"scriptFormat Transformation" => [{"scriptFormat" => "foo"}, RDF::Tabular::Transformation],
"source Transformation" => [{"source" => "foo"}, RDF::Tabular::Transformation],
"columns Schema" => [{"columns" => []}, RDF::Tabular::Schema],
"primaryKey Schema" => [{"primaryKey" => "foo"}, RDF::Tabular::Schema],
"foreignKeys Schema" => [{"foreignKeys" => []}, RDF::Tabular::Schema],
- "urlTemplate Schema" => [{"urlTemplate" => "foo"}, RDF::Tabular::Schema],
"commentPrefix Dialect" => [{"commentPrefix" => "#"}, RDF::Tabular::Dialect],
"delimiter Dialect" => [{"delimiter" => ","}, RDF::Tabular::Dialect],
"doubleQuote Dialect" => [{"doubleQuote" => true}, RDF::Tabular::Dialect],
"encoding Dialect" => [{"encoding" => "utf-8"}, RDF::Tabular::Dialect],
"header Dialect" => [{"header" => true}, RDF::Tabular::Dialect],
@@ -860,80 +878,54 @@
expect(rows[2].values.map(&:to_s)).to produce(%w(AF 33.93911 67.709953 Afghanistan), @debug)
end
context "URL expansion" do
subject {
- described_class.new(JSON.parse(%({
+ JSON.parse(%({
"url": "https://example.org/countries.csv",
"tableSchema": {
"columns": [
{"titles": "addressCountry"},
{"titles": "latitude"},
{"titles": "longitude"},
{"titles": "name"}
]
}
- })), base: RDF::URI("http://example.org/base"), debug: @debug)
+ }))
}
let(:input) {RDF::Util::File.open_file("https://example.org/countries.csv")}
{
"default titles" => {
aboutUrl: [RDF::Node, RDF::Node, RDF::Node, RDF::Node],
propertyUrl: [nil, nil, nil, nil],
valueUrl: [nil, nil, nil, nil],
- md: {"url" => "https://example.org/countries.csv", "tableSchema" => {
- "columns" => [
- {"titles" => "addressCountry"},
- {"titles" => "latitude"},
- {"titles" => "longitude"},
- {"titles" => "name"}
- ]
- }
- }
+ md: {}
},
"schema transformations" => {
aboutUrl: %w(#addressCountry #latitude #longitude #name),
propertyUrl: %w(?_name=addressCountry ?_name=latitude ?_name=longitude ?_name=name),
valueUrl: %w(addressCountry latitude longitude name),
md: {
- "url" => "https://example.org/countries.csv",
- "tableSchema" => {
- "aboutUrl" => "{#_name}",
- "propertyUrl" => '{?_name}',
- "valueUrl" => '{_name}',
- "columns" => [
- {"titles" => "addressCountry"},
- {"titles" => "latitude"},
- {"titles" => "longitude"},
- {"titles" => "name"}
- ]
- }
+ "aboutUrl" => "{#_name}",
+ "propertyUrl" => '{?_name}',
+ "valueUrl" => '{_name}'
}
},
"PNames" => {
aboutUrl: [RDF::SCHEMA.addressCountry, RDF::SCHEMA.latitude, RDF::SCHEMA.longitude, RDF::SCHEMA.name],
propertyUrl: [RDF::SCHEMA.addressCountry, RDF::SCHEMA.latitude, RDF::SCHEMA.longitude, RDF::SCHEMA.name],
valueUrl: [RDF::SCHEMA.addressCountry, RDF::SCHEMA.latitude, RDF::SCHEMA.longitude, RDF::SCHEMA.name],
md: {
- "url" => "https://example.org/countries.csv",
- "tableSchema" => {
- "aboutUrl" => 'http://schema.org/{_name}',
- "propertyUrl" => 'schema:{_name}',
- "valueUrl" => 'schema:{_name}',
- "columns" => [
- {"titles" => "addressCountry"},
- {"titles" => "latitude"},
- {"titles" => "longitude"},
- {"titles" => "name"}
- ]
- }
+ "aboutUrl" => "http://schema.org/{_name}",
+ "propertyUrl" => 'schema:{_name}',
+ "valueUrl" => 'schema:{_name}'
}
},
}.each do |name, props|
context name do
- let(:md) {RDF::Tabular::Table.new(props[:md]).merge(subject).tables.first}
+ let(:md) {RDF::Tabular::Table.new(subject.merge(props[:md]), base: RDF::URI("http://example.org/base")).normalize!}
let(:cells) {md.to_enum(:each_row, input).to_a.first.values}
let(:aboutUrls) {props[:aboutUrl].map {|u| u.is_a?(String) ? md.url.join(u) : u}}
let(:propertyUrls) {props[:propertyUrl].map {|u| u.is_a?(String) ? md.url.join(u) : u}}
let(:valueUrls) {props[:valueUrl].map {|u| u.is_a?(String) ? md.url.join(u) : u}}
it "aboutUrl is #{props[:aboutUrl]}" do
@@ -1046,40 +1038,40 @@
base: "decimal",
value: "4"
},
"decimal with matching pattern" => {
base: "decimal",
- pattern: '\d{3}',
+ format: {pattern: '\d{3}'},
value: "123"
},
"decimal with wrong pattern" => {
base: "decimal",
- pattern: '\d{4}',
+ format: {pattern: '\d{4}'},
value: "123",
errors: [/123 does not match pattern/]
},
"decimal with implicit groupChar" => {
base: "decimal",
value: %("123,456.789"),
result: "123456.789"
},
"decimal with explicit groupChar" => {
base: "decimal",
- groupChar: ";",
+ format: {groupChar: ";"},
value: "123;456.789",
result: "123456.789"
},
"decimal with repeated groupChar" => {
base: "decimal",
- groupChar: ";",
+ format: {groupChar: ";"},
value: "123;;456.789",
result: "123;;456.789",
errors: [/has repeating/]
},
"decimal with explicit decimalChar" => {
base: "decimal",
- decimalChar: ";",
+ format: {decimalChar: ";"},
value: "123456;789",
result: "123456.789"
},
"invalid decimal" => {
base: "decimal",
@@ -1147,11 +1139,11 @@
"validate date yyyy-MM-dd" => {base: "date", value: "2015-03-22", format: "yyyy-MM-dd", result: "2015-03-22"},
"validate date yyyyMMdd" => {base: "date", value: "20150322", format: "yyyyMMdd", result: "2015-03-22"},
"validate date dd-MM-yyyy" => {base: "date", value: "22-03-2015", format: "dd-MM-yyyy", result: "2015-03-22"},
"validate date d-M-yyyy" => {base: "date", value: "22-3-2015", format: "d-M-yyyy", result: "2015-03-22"},
"validate date MM-dd-yyyy" => {base: "date", value: "03-22-2015", format: "MM-dd-yyyy", result: "2015-03-22"},
- "validate date M/d/yyyy" => {base: "date", value: "3/22/2015", format: "M-d-yyyy", result: "2015-03-22"},
+ "validate date M-d-yyyy" => {base: "date", value: "3-22-2015", format: "M-d-yyyy", result: "2015-03-22"},
"validate date dd/MM/yyyy" => {base: "date", value: "22/03/2015", format: "dd/MM/yyyy", result: "2015-03-22"},
"validate date d/M/yyyy" => {base: "date", value: "22/3/2015", format: "d/M/yyyy", result: "2015-03-22"},
"validate date MM/dd/yyyy" => {base: "date", value: "03/22/2015", format: "MM/dd/yyyy", result: "2015-03-22"},
"validate date M/d/yyyy" => {base: "date", value: "3/22/2015", format: "M/d/yyyy", result: "2015-03-22"},
"validate date dd.MM.yyyy" => {base: "date", value: "22.03.2015", format: "dd.MM.yyyy", result: "2015-03-22"},
@@ -1354,359 +1346,182 @@
context "transformation" do
it "FIXME"
end
end
- describe "#merge" do
+ describe "#verify_compatible!" do
{
"two tables with same id" => {
A: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.org/table"
+ "url": "http://example.org/table",
+ "tableSchema": {"columns": []}
}),
- B: [%({
+ B: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.org/table"
- })],
- R: %({
- "@type": "TableGroup",
- "tables": [{
- "@type": "Table",
- "url": "http://example.org/table"
- }],
- "@context": "http://www.w3.org/ns/csvw"
- })
+ "url": "http://example.org/table",
+ "tableSchema": {"columns": []}
+ }),
+ R: true
},
"two tables with different id" => {
A: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.org/table1"
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": []}
}),
- B: [%({
+ B: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.org/table2"
- })],
- R: %({
- "@type": "TableGroup",
- "tables": [{
- "@type": "Table",
- "url": "http://example.org/table1"
- }, {
- "@type": "Table",
- "url": "http://example.org/table2"
- }],
- "@context": "http://www.w3.org/ns/csvw"
- })
- },
- "table and table-group" => {
- A: %({
- "@type": "Table",
- "url": "http://example.org/table1"
+ "url": "http://example.org/table2",
+ "tableSchema": {"columns": []}
}),
- B: [%({
- "@type": "TableGroup",
- "tables": [{
- "@type": "Table",
- "url": "http://example.org/table2"
- }]
- })],
- R: %({
- "@type": "TableGroup",
- "tables": [{
- "@type": "Table",
- "url": "http://example.org/table1"
- }, {
- "@type": "Table",
- "url": "http://example.org/table2"
- }],
- "@context": "http://www.w3.org/ns/csvw"
- })
+ R: false
},
- "table-group and table" => {
+ "table-group and table with same url" => {
A: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "TableGroup",
"tables": [{
"@type": "Table",
- "url": "http://example.org/table1"
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": []}
}]
}),
- B: [%({
+ B: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.org/table2"
- })],
- R: %({
- "@type": "TableGroup",
- "tables": [{
- "@type": "Table",
- "url": "http://example.org/table1"
- }, {
- "@type": "Table",
- "url": "http://example.org/table2"
- }],
- "@context": "http://www.w3.org/ns/csvw"
- })
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": []}
+ }),
+ R: true
},
- "table-group and two tables" => {
+ "table-group and table with different url" => {
A: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "TableGroup",
"tables": [{
"@type": "Table",
- "url": "http://example.org/table1"
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": []}
}]
}),
- B: [%({
+ B: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
"url": "http://example.org/table2",
- "dc:label": "foo"
- }), %({
- "@type": "Table",
- "url": "http://example.org/table2",
- "dc:label": "bar"
- })],
- R: %({
+ "tableSchema": {"columns": []}
+ }),
+ R: false
+ },
+ "table-group with two tables" => {
+ A: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "TableGroup",
"tables": [{
"@type": "Table",
- "url": "http://example.org/table1"
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": []}
}, {
"@type": "Table",
"url": "http://example.org/table2",
- "dc:label": {"@value": "foo"}
- }],
- "@context": "http://www.w3.org/ns/csvw"
- })
- },
- }.each do |name, props|
- it name do
- a = described_class.new(::JSON.parse(props[:A]))
- b = props[:B].map {|md| described_class.new(::JSON.parse(md))}
- r = described_class.new(::JSON.parse(props[:R]))
- expect(a.merge(*b)).to produce(r, @debug)
- end
- end
-
- %w(Transformation Schema Transformation Column Dialect).each do |t|
- it "does not merge into a #{t}" do
- a = described_class.new({}, type: t.to_sym)
- b = described_class.new({}, type: :TableGroup)
- expect {a.merge(b)}.to raise_error
- end
-
- it "does not merge from a #{t}" do
- a = described_class.new({}, type: :TableGroup)
- b = described_class.new({}, type: t.to_sym)
- expect {a.merge(b)}.to raise_error
- end
- end
- end
-
- describe "#merge!" do
- {
- "TableGroup with and without @id" => {
- A: %({"@id": "http://example.org/foo", "tables": [], "@type": "TableGroup"}),
- B: %({"tables": [], "@type": "TableGroup"}),
- R: %({"@id": "http://example.org/foo", "tables": [], "@type": "TableGroup"})
- },
- "TableGroup with and without @type" => {
- A: %({"tables": []}),
- B: %({"tables": [], "@type": "TableGroup"}),
- R: %({"tables": [], "@type": "TableGroup"})
- },
- "TableGroup with matching tables" => {
- A: %({"tables": [{"url": "http://example.org/foo", "dc:title": "foo"}]}),
- B: %({"tables": [{"url": "http://example.org/foo", "dc:description": "bar"}]}),
- R: %({"tables": [{
- "url": "http://example.org/foo",
- "dc:title": {"@value": "foo"},
- "dc:description": {"@value": "bar"}
- }]})
- },
- "TableGroup with differing tables" => {
- A: %({"tables": [{"url": "http://example.org/foo", "dc:title": "foo"}]}),
- B: %({"tables": [{"url": "http://example.org/bar", "dc:description": "bar"}]}),
- R: %({
- "tables": [
- {"url": "http://example.org/foo", "dc:title": {"@value": "foo"}},
- {"url": "http://example.org/bar", "dc:description": {"@value": "bar"}}
- ]})
- },
- "Table with tableDirection always takes A" => {
- A: %({"@type": "Table", "url": "http://example.com/foo", "tableDirection": "ltr"}),
- B: %({"@type": "Table", "url": "http://example.com/foo", "tableDirection": "rtl"}),
- R: %({"@type": "Table", "url": "http://example.com/foo", "tableDirection": "ltr"}),
- },
- "Table with dialect merges A and B" => {
- A: %({"@type": "Table", "url": "http://example.com/foo", "dialect": {"encoding": "utf-8"}}),
- B: %({"@type": "Table", "url": "http://example.com/foo", "dialect": {"skipRows": 0}}),
- R: %({"@type": "Table", "url": "http://example.com/foo", "dialect": {"encoding": "utf-8", "skipRows": 0}}),
- },
- "Table with equivalent transformations uses A" => {
- A: %({
- "@type": "Table",
- "url": "http://example.com/foo",
- "transformations": [{
- "url": "http://example.com/foo",
- "targetFormat": "http://example.com/target",
- "scriptFormat": "http://example.com/template",
- "source": "json"
+ "tableSchema": {"columns": []}
}]
}),
B: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "transformations": [{
- "url": "http://example.com/foo",
- "targetFormat": "http://example.com/target",
- "scriptFormat": "http://example.com/template",
- "source": "html"
- }]
+ "url": "http://example.org/table2",
+ "tableSchema": {"columns": []}
}),
- R: %({
- "@type": "Table",
- "url": "http://example.com/foo",
- "transformations": [{
- "url": "http://example.com/foo",
- "targetFormat": "http://example.com/target",
- "scriptFormat": "http://example.com/template",
- "source": "json"
- }]
- }),
+ R: true
},
- "Table with differing transformations appends B to A" => {
+ "tables with matching columns" => {
A: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "transformations": [{
- "url": "http://example.com/foo",
- "targetFormat": "http://example.com/target",
- "scriptFormat": "http://example.com/template"
- }]
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"name": "foo"}]}
}),
B: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "transformations": [{
- "url": "http://example.com/bar",
- "targetFormat": "http://example.com/targetb",
- "scriptFormat": "http://example.com/templateb"
- }]
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"name": "foo"}]}
}),
- R: %({
+ R: true
+ },
+ "tables with virtual columns otherwise matching" => {
+ A: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "transformations": [{
- "url": "http://example.com/foo",
- "targetFormat": "http://example.com/target",
- "scriptFormat": "http://example.com/template"
- }, {
- "url": "http://example.com/bar",
- "targetFormat": "http://example.com/targetb",
- "scriptFormat": "http://example.com/templateb"
- }]
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"name": "foo"}, {"virtual": true}]}
}),
- },
- "Table with common properties keeps A" => {
- A: %({"@type": "Table", "url": "http://example.com/foo", "rdfs:label": "foo"}),
- B: %({"@type": "Table", "url": "http://example.com/foo", "rdfs:label": "bar"}),
- R: %({
+ B: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "rdfs:label": {"@value": "foo"}
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"name": "foo"}]}
}),
+ R: true
},
- "Table with common properties in different languages keeps A" => {
+ "tables with differing columns" => {
A: %({
- "@context": {"@language": "en"},
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "rdfs:label": "foo"
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"name": "foo"}]}
}),
B: %({
- "@context": {"@language": "fr"},
- "@type": "Table",
- "url": "http://example.com/foo",
- "rdfs:label": "foo"
- }),
- R: %({
"@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "rdfs:label": {"@value": "foo", "@language": "en"}
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"name": "bar"}]}
}),
+ R: false
},
- "Table with different languages merges A and B" => {
+ "tables with different column count" => {
A: %({
- "@context": {"@language": "en"},
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "tableSchema": {
- "columns": [{"titles": "foo"}]
- }
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"name": "foo"}, {"name": "bar"}]}
}),
B: %({
+ "@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "tableSchema": {
- "columns": [{"titles": "foo"}]
- }
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"name": "bar"}]}
}),
- R: %({
+ R: false
+ },
+ "tables with matching columns on name/titles" => {
+ A: %({
"@context": "http://www.w3.org/ns/csvw",
"@type": "Table",
- "url": "http://example.com/foo",
- "tableSchema": {
- "columns": [{"titles": {"en": ["foo"]}}]
- }
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"name": "foo"}]}
}),
+ B: %({
+ "@context": "http://www.w3.org/ns/csvw",
+ "@type": "Table",
+ "url": "http://example.org/table1",
+ "tableSchema": {"columns": [{"titles": "foo"}]}
+ }),
+ R: true
},
- "Schema with matching columns merges A and B" => {
- A: %({"@type": "Schema", "columns": [{"name": "foo", "required": true}]}),
- B: %({"@type": "Schema", "columns": [{"name": "foo", "required": false}]}),
- R: %({"@type": "Schema", "columns": [{"name": "foo", "required": true}]}),
- },
- "Schema with matching column titles" => {
- A: %({"@type": "Schema", "columns": [{"titles": "Foo"}]}),
- B: %({"@type": "Schema", "columns": [{"name": "foo", "titles": "Foo"}]}),
- R: %({"@type": "Schema", "columns": [{"name": "foo", "titles": {"und": ["Foo"]}}]}),
- },
- "Schema with primaryKey always takes A" => {
- A: %({"@type": "Schema", "primaryKey": "foo"}),
- B: %({"@type": "Schema", "primaryKey": "bar"}),
- R: %({"@type": "Schema", "primaryKey": "foo"}),
- },
- "Schema with matching foreignKey uses A" => {
- A: %({"@type": "Schema", "columns": [{"name": "foo"}], "foreignKeys": [{"columnReference": "foo", "reference": {"columnReference": "foo"}}]}),
- B: %({"@type": "Schema", "columns": [{"name": "foo"}], "foreignKeys": [{"columnReference": "foo", "reference": {"columnReference": "foo"}}]}),
- R: %({"@type": "Schema", "columns": [{"name": "foo"}], "foreignKeys": [{"columnReference": "foo", "reference": {"columnReference": "foo"}}]}),
- },
- "Schema with differing foreignKey uses A and B" => {
- A: %({"@type": "Schema", "columns": [{"name": "foo"}, {"name": "bar"}], "foreignKeys": [{"columnReference": "foo", "reference": {"columnReference": "foo"}}]}),
- B: %({"@type": "Schema", "columns": [{"name": "foo"}, {"name": "bar"}], "foreignKeys": [{"columnReference": "bar", "reference": {"columnReference": "bar"}}]}),
- R: %({"@type": "Schema", "columns": [{"name": "foo"}, {"name": "bar"}], "foreignKeys": [{"columnReference": "foo", "reference": {"columnReference": "foo"}}, {"columnReference": "bar", "reference": {"columnReference": "bar"}}]}),
- },
- "Schema with urlTemplate always takes A" => {
- A: %({"@type": "Schema", "urlTemplate": "foo"}),
- B: %({"@type": "Schema", "urlTemplate": "bar"}),
- R: %({"@type": "Schema", "urlTemplate": "foo"}),
- },
}.each do |name, props|
it name do
- a = described_class.new(::JSON.parse(props[:A]), debug: @debug)
+ a = described_class.new(::JSON.parse(props[:A]))
b = described_class.new(::JSON.parse(props[:B]))
- r = described_class.new(::JSON.parse(props[:R]))
- m = a.merge!(b)
- expect(m).to produce(r, @debug)
- expect(a).to equal m
- end
- end
-
- %w(TableGroup Table Transformation Schema Transformation Column Dialect).each do |ta|
- %w(TableGroup Table Transformation Schema Transformation Column Dialect).each do |tb|
- next if ta == tb
- it "does not merge #{tb} into #{ta}" do
- a = described_class.new({}, type: ta.to_sym)
- b = described_class.new({}, type: tb.to_sym)
- expect {a.merge!(b)}.to raise_error
+ if props[:R]
+ expect {a.verify_compatible!(b)}.not_to raise_error
+ else
+ expect {a.verify_compatible!(b)}.to raise_error(RDF::Tabular::Error)
end
end
end
end
end