csvlint 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +7 -1
  3. data/CHANGELOG.md +19 -1
  4. data/README.md +93 -36
  5. data/bin/csvlint +68 -27
  6. data/csvlint.gemspec +2 -0
  7. data/features/csvw_schema_validation.feature +127 -0
  8. data/features/fixtures/spreadsheet.xlsx +0 -0
  9. data/features/sources.feature +3 -4
  10. data/features/step_definitions/parse_csv_steps.rb +13 -1
  11. data/features/step_definitions/schema_validation_steps.rb +27 -1
  12. data/features/step_definitions/sources_steps.rb +1 -1
  13. data/features/step_definitions/validation_errors_steps.rb +48 -1
  14. data/features/step_definitions/validation_info_steps.rb +5 -1
  15. data/features/step_definitions/validation_warnings_steps.rb +15 -1
  16. data/features/support/load_tests.rb +114 -0
  17. data/features/validation_errors.feature +12 -24
  18. data/features/validation_warnings.feature +18 -6
  19. data/lib/csvlint.rb +10 -0
  20. data/lib/csvlint/csvw/column.rb +359 -0
  21. data/lib/csvlint/csvw/date_format.rb +182 -0
  22. data/lib/csvlint/csvw/metadata_error.rb +13 -0
  23. data/lib/csvlint/csvw/number_format.rb +211 -0
  24. data/lib/csvlint/csvw/property_checker.rb +761 -0
  25. data/lib/csvlint/csvw/table.rb +204 -0
  26. data/lib/csvlint/csvw/table_group.rb +165 -0
  27. data/lib/csvlint/schema.rb +40 -23
  28. data/lib/csvlint/validate.rb +142 -19
  29. data/lib/csvlint/version.rb +1 -1
  30. data/spec/csvw/column_spec.rb +112 -0
  31. data/spec/csvw/date_format_spec.rb +49 -0
  32. data/spec/csvw/number_format_spec.rb +403 -0
  33. data/spec/csvw/table_group_spec.rb +143 -0
  34. data/spec/csvw/table_spec.rb +90 -0
  35. data/spec/schema_spec.rb +27 -1
  36. data/spec/spec_helper.rb +0 -1
  37. data/spec/validator_spec.rb +16 -10
  38. metadata +53 -2
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+
3
+ describe Csvlint::Csvw::TableGroup do
4
+
5
+ it "should inherit null to all columns" do
6
+ @metadata=<<-EOL
7
+ {
8
+ "@context": "http://www.w3.org/ns/csvw",
9
+ "null": true,
10
+ "tables": [{
11
+ "url": "test040.csv",
12
+ "tableSchema": {
13
+ "columns": [{
14
+ "titles": "null"
15
+ }, {
16
+ "titles": "lang"
17
+ }, {
18
+ "titles": "textDirection"
19
+ }, {
20
+ "titles": "separator"
21
+ }, {
22
+ "titles": "ordered"
23
+ }, {
24
+ "titles": "default"
25
+ }, {
26
+ "titles": "datatype"
27
+ }, {
28
+ "titles": "aboutUrl"
29
+ }, {
30
+ "titles": "propertyUrl"
31
+ }, {
32
+ "titles": "valueUrl"
33
+ }]
34
+ }
35
+ }]
36
+ }
37
+ EOL
38
+ json = JSON.parse( @metadata )
39
+ table_group = Csvlint::Csvw::TableGroup.from_json("http://w3c.github.io/csvw/tests/test040-metadata.json", json)
40
+
41
+ expect(table_group.class).to eq(Csvlint::Csvw::TableGroup)
42
+ expect(table_group.annotations.length).to eq(0)
43
+ expect(table_group.warnings.length).to eq(1)
44
+ expect(table_group.warnings[0].type).to eq(:invalid_value)
45
+ expect(table_group.warnings[0].category).to eq(:metadata)
46
+ expect(table_group.warnings[0].content).to eq("null: true")
47
+
48
+ expect(table_group.tables.length).to eq(1)
49
+ expect(table_group.tables["http://w3c.github.io/csvw/tests/test040.csv"]).to be_a(Csvlint::Csvw::Table)
50
+
51
+ table = table_group.tables["http://w3c.github.io/csvw/tests/test040.csv"]
52
+ expect(table.columns.length).to eq(10)
53
+ expect(table.columns[0].null).to eq([""])
54
+ end
55
+
56
+ context "when parsing CSVW table group metadata" do
57
+
58
+ before(:each) do
59
+ @metadata=<<-EOL
60
+ {
61
+ "@context": "http://www.w3.org/ns/csvw",
62
+ "tables": [{
63
+ "url": "countries.csv",
64
+ "tableSchema": {
65
+ "columns": [{
66
+ "name": "countryCode",
67
+ "titles": "countryCode",
68
+ "datatype": "string",
69
+ "propertyUrl": "http://www.geonames.org/ontology{#_name}"
70
+ }, {
71
+ "name": "latitude",
72
+ "titles": "latitude",
73
+ "datatype": "number"
74
+ }, {
75
+ "name": "longitude",
76
+ "titles": "longitude",
77
+ "datatype": "number"
78
+ }, {
79
+ "name": "name",
80
+ "titles": "name",
81
+ "datatype": "string"
82
+ }],
83
+ "aboutUrl": "http://example.org/countries.csv{#countryCode}",
84
+ "propertyUrl": "http://schema.org/{_name}",
85
+ "primaryKey": "countryCode"
86
+ }
87
+ }, {
88
+ "url": "country_slice.csv",
89
+ "tableSchema": {
90
+ "columns": [{
91
+ "name": "countryRef",
92
+ "titles": "countryRef",
93
+ "valueUrl": "http://example.org/countries.csv{#countryRef}"
94
+ }, {
95
+ "name": "year",
96
+ "titles": "year",
97
+ "datatype": "gYear"
98
+ }, {
99
+ "name": "population",
100
+ "titles": "population",
101
+ "datatype": "integer"
102
+ }],
103
+ "foreignKeys": [{
104
+ "columnReference": "countryRef",
105
+ "reference": {
106
+ "resource": "countries.csv",
107
+ "columnReference": "countryCode"
108
+ }
109
+ }]
110
+ }
111
+ }]
112
+ }
113
+ EOL
114
+ stub_request(:get, "http://w3c.github.io/csvw/tests/countries.json").to_return(:status => 200, :body => @metadata)
115
+ @countries=<<-EOL
116
+ countryCode,latitude,longitude,name
117
+ AD,42.546245,1.601554,Andorra
118
+ AE,23.424076,53.847818,"United Arab Emirates"
119
+ AF,33.93911,67.709953,Afghanistan
120
+ EOL
121
+ stub_request(:get, "http://w3c.github.io/csvw/tests/countries.csv").to_return(:status => 200, :body => @countries)
122
+ @country_slice=<<-EOL
123
+ countryRef,year,population
124
+ AF,1960,9616353
125
+ AF,1961,9799379
126
+ AF,1962,9989846
127
+ EOL
128
+ stub_request(:get, "http://w3c.github.io/csvw/tests/country_slice.csv").to_return(:status => 200, :body => @country_slice)
129
+ end
130
+
131
+ it "should create a table group from pre-parsed CSVW metadata" do
132
+ json = JSON.parse( @metadata )
133
+ table_group = Csvlint::Csvw::TableGroup.from_json("http://w3c.github.io/csvw/tests/countries.json", json)
134
+
135
+ expect(table_group.class).to eq(Csvlint::Csvw::TableGroup)
136
+ expect(table_group.id).to eq(nil)
137
+ expect(table_group.tables.length).to eq(2)
138
+ expect(table_group.tables["http://w3c.github.io/csvw/tests/countries.csv"]).to be_a(Csvlint::Csvw::Table)
139
+ expect(table_group.notes.length).to eq(0)
140
+ expect(table_group.annotations.length).to eq(0)
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ describe Csvlint::Csvw::Table do
4
+
5
+ context "when parsing CSVW table metadata" do
6
+
7
+ before(:each) do
8
+ @metadata=<<-EOL
9
+ {
10
+ "@context": "http://www.w3.org/ns/csvw",
11
+ "tables": [{
12
+ "url": "countries.csv",
13
+ "tableSchema": {
14
+ "columns": [{
15
+ "name": "countryCode",
16
+ "titles": "countryCode",
17
+ "datatype": "string",
18
+ "propertyUrl": "http://www.geonames.org/ontology{#_name}"
19
+ }, {
20
+ "name": "latitude",
21
+ "titles": "latitude",
22
+ "datatype": "number"
23
+ }, {
24
+ "name": "longitude",
25
+ "titles": "longitude",
26
+ "datatype": "number"
27
+ }, {
28
+ "name": "name",
29
+ "titles": "name",
30
+ "datatype": "string"
31
+ }],
32
+ "aboutUrl": "http://example.org/countries.csv{#countryCode}",
33
+ "propertyUrl": "http://schema.org/{_name}",
34
+ "primaryKey": "countryCode"
35
+ }
36
+ }, {
37
+ "url": "country_slice.csv",
38
+ "tableSchema": {
39
+ "columns": [{
40
+ "name": "countryRef",
41
+ "titles": "countryRef",
42
+ "valueUrl": "http://example.org/countries.csv{#countryRef}"
43
+ }, {
44
+ "name": "year",
45
+ "titles": "year",
46
+ "datatype": "gYear"
47
+ }, {
48
+ "name": "population",
49
+ "titles": "population",
50
+ "datatype": "integer"
51
+ }],
52
+ "foreignKeys": [{
53
+ "columnReference": "countryRef",
54
+ "reference": {
55
+ "resource": "countries.csv",
56
+ "columnReference": "countryCode"
57
+ }
58
+ }]
59
+ }
60
+ }]
61
+ }
62
+ EOL
63
+ stub_request(:get, "http://w3c.github.io/csvw/tests/countries.json").to_return(:status => 200, :body => @metadata)
64
+ @countries=<<-EOL
65
+ countryCode,latitude,longitude,name
66
+ AD,42.546245,1.601554,Andorra
67
+ AE,23.424076,53.847818,"United Arab Emirates"
68
+ AF,33.93911,67.709953,Afghanistan
69
+ EOL
70
+ stub_request(:get, "http://w3c.github.io/csvw/tests/countries.csv").to_return(:status => 200, :body => @countries)
71
+ @country_slice=<<-EOL
72
+ countryRef,year,population
73
+ AF,1960,9616353
74
+ AF,1961,9799379
75
+ AF,1962,9989846
76
+ EOL
77
+ stub_request(:get, "http://w3c.github.io/csvw/tests/country_slice.csv").to_return(:status => 200, :body => @country_slice)
78
+ end
79
+
80
+ it "should create a table from pre-parsed CSVW metadata" do
81
+ json = JSON.parse( @metadata )
82
+ table = Csvlint::Csvw::Table.from_json(json["tables"][0], "http://w3c.github.io/csvw/tests/countries.json")
83
+
84
+ expect(table).to be_a(Csvlint::Csvw::Table)
85
+ expect(table.url.to_s).to eq("http://w3c.github.io/csvw/tests/countries.csv")
86
+ expect(table.columns.length).to eq(4)
87
+ expect(table.columns[0]).to be_a(Csvlint::Csvw::Column)
88
+ end
89
+ end
90
+ end
@@ -170,10 +170,11 @@ describe Csvlint::Schema do
170
170
  expect( schema.fields[0].constraints["required"] ).to eql(true)
171
171
  expect( schema.fields[0].title ).to eql("id")
172
172
  expect( schema.fields[0].description ).to eql("house identifier")
173
+ expect( schema.fields[2].constraints["pattern"]).to eql("[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}")
173
174
  end
174
175
 
175
176
  it "should create a schema from a JSON Table URL" do
176
- schema = Csvlint::Schema.load_from_json_table("http://example.com/example.json")
177
+ schema = Csvlint::Schema.load_from_json("http://example.com/example.json")
177
178
  expect( schema.uri ).to eql("http://example.com/example.json")
178
179
  expect( schema.fields.length ).to eql(3)
179
180
  expect( schema.fields[0].name ).to eql("ID")
@@ -182,4 +183,29 @@ describe Csvlint::Schema do
182
183
  end
183
184
  end
184
185
 
186
+ context "when parsing CSVW metadata" do
187
+
188
+ before(:each) do
189
+ @example=<<-EOL
190
+ {
191
+ "@context": "http://www.w3.org/ns/csvw",
192
+ "url": "http://example.com/example1.csv",
193
+ "tableSchema": {
194
+ "columns": [
195
+ { "name": "Name", "required": true, "datatype": { "base": "string", "format": ".+" } },
196
+ { "name": "Id", "required": true, "datatype": { "base": "string", "minLength": 3 } },
197
+ { "name": "Email", "required": true }
198
+ ]
199
+ }
200
+ }
201
+ EOL
202
+ stub_request(:get, "http://example.com/metadata.json").to_return(:status => 200, :body => @example)
203
+ end
204
+
205
+ it "should create a table group from a CSVW metadata URL" do
206
+ schema = Csvlint::Schema.load_from_json("http://example.com/metadata.json")
207
+ expect( schema.class ).to eq(Csvlint::Csvw::TableGroup)
208
+ end
209
+ end
210
+
185
211
  end
@@ -6,7 +6,6 @@ require 'pry'
6
6
  require 'webmock/rspec'
7
7
 
8
8
  RSpec.configure do |config|
9
- config.treat_symbols_as_metadata_keys_with_true_values = true
10
9
  config.run_all_when_everything_filtered = true
11
10
  config.filter_run :focus
12
11
 
@@ -4,13 +4,16 @@ describe Csvlint::Validator do
4
4
 
5
5
  before do
6
6
  stub_request(:get, "http://example.com/example.csv").to_return(:status => 200, :body => "")
7
+ stub_request(:get, "http://example.com/.well-known/csvm").to_return(:status => 404)
8
+ stub_request(:get, "http://example.com/example.csv-metadata.json").to_return(:status => 404)
9
+ stub_request(:get, "http://example.com/csv-metadata.json").to_return(:status => 404)
7
10
  end
8
11
 
9
12
  context "csv dialect" do
10
13
  it "should provide sensible defaults for CSV parsing" do
11
14
  validator = Csvlint::Validator.new("http://example.com/example.csv")
12
15
  opts = validator.instance_variable_get("@csv_options")
13
- opts.should include({
16
+ expect(opts).to include({
14
17
  :col_sep => ",",
15
18
  :row_sep => :auto,
16
19
  :quote_char => '"',
@@ -25,7 +28,7 @@ describe Csvlint::Validator do
25
28
  "delimiter" => "\t",
26
29
  "quoteChar" => "'"
27
30
  })
28
- opts.should include({
31
+ expect(opts).to include({
29
32
  :col_sep => "\t",
30
33
  :row_sep => "\n",
31
34
  :quote_char => "'",
@@ -93,6 +96,7 @@ describe Csvlint::Validator do
93
96
  it "should warn if column names aren't unique" do
94
97
  data = StringIO.new( "minimum, minimum" )
95
98
  validator = Csvlint::Validator.new(data)
99
+ validator.reset
96
100
  expect( validator.validate_header(["minimum", "minimum"]) ).to eql(true)
97
101
  expect( validator.warnings.size ).to eql(1)
98
102
  expect( validator.warnings.first.type).to eql(:duplicate_column_name)
@@ -173,7 +177,7 @@ describe Csvlint::Validator do
173
177
  validator.build_formats(row)
174
178
  formats = validator.instance_variable_get("@formats")
175
179
 
176
- formats[0].keys.first.should == type
180
+ expect(formats[0].keys.first).to eql type
177
181
  end
178
182
  end
179
183
 
@@ -184,8 +188,8 @@ describe Csvlint::Validator do
184
188
  validator.build_formats(row)
185
189
  formats = validator.instance_variable_get("@formats")
186
190
 
187
- formats[0].keys.first.should == :numeric
188
- formats[1].keys.first.should == :numeric
191
+ expect(formats[0].keys.first).to eql :numeric
192
+ expect(formats[1].keys.first).to eql :numeric
189
193
  end
190
194
 
191
195
  it "should ignore blank arrays" do
@@ -194,7 +198,7 @@ describe Csvlint::Validator do
194
198
  validator = Csvlint::Validator.new("http://example.com/example.csv")
195
199
  validator.build_formats(row)
196
200
  formats = validator.instance_variable_get("@formats")
197
- formats.should == []
201
+ expect(formats).to eql []
198
202
  end
199
203
 
200
204
  it "should work correctly for single columns" do
@@ -212,7 +216,7 @@ describe Csvlint::Validator do
212
216
 
213
217
  formats = validator.instance_variable_get("@formats")
214
218
 
215
- formats.should == [{:string => 3}]
219
+ expect(formats).to eql [{:string => 3}]
216
220
  end
217
221
 
218
222
  it "should return formats correctly if a row is blank" do
@@ -229,7 +233,7 @@ describe Csvlint::Validator do
229
233
 
230
234
  formats = validator.instance_variable_get("@formats")
231
235
 
232
- formats.should == [
236
+ expect(formats).to eql [
233
237
  {:string => 1},
234
238
  {:numeric => 1},
235
239
  {:string => 1},
@@ -254,7 +258,7 @@ describe Csvlint::Validator do
254
258
  warnings = validator.instance_variable_get("@warnings")
255
259
  warnings.delete_if { |h| h.type != :inconsistent_values }
256
260
 
257
- warnings.count.should == 1
261
+ expect(warnings.count).to eql 1
258
262
  end
259
263
 
260
264
  end
@@ -263,12 +267,13 @@ describe Csvlint::Validator do
263
267
 
264
268
  before :all do
265
269
  stub_request(:get, "http://example.com/crlf.csv").to_return(:status => 200, :body => File.read(File.join(File.dirname(__FILE__),'..','features','fixtures','windows-line-endings.csv')))
270
+ stub_request(:get, "http://example.com/crlf.csv-metadata.json").to_return(:status => 404)
266
271
  end
267
272
 
268
273
  it "can get line break symbol" do
269
274
 
270
275
  validator = Csvlint::Validator.new("http://example.com/crlf.csv")
271
- validator.line_breaks.should == "\r\n"
276
+ expect(validator.line_breaks).to eql "\r\n"
272
277
 
273
278
  end
274
279
 
@@ -299,6 +304,7 @@ describe Csvlint::Validator do
299
304
 
300
305
  it "should follow redirects to SSL" do
301
306
  stub_request(:get, "http://example.com/redirect").to_return(:status => 301, :headers=>{"Location" => "https://example.com/example.csv"})
307
+ stub_request(:get, "http://example.com/redirect-metadata.json").to_return(:status => 404)
302
308
  stub_request(:get, "https://example.com/example.csv").to_return(:status => 200,
303
309
  :headers=>{"Content-Type" => "text/csv; header=present"},
304
310
  :body => File.read(File.join(File.dirname(__FILE__),'..','features','fixtures','valid.csv')))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csvlint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - pezholio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-06 00:00:00.000000000 Z
11
+ date: 2015-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mime-types
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ! '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: escape_utils
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: uri_template
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: bundler
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -286,6 +314,7 @@ files:
286
314
  - features/check_format.feature
287
315
  - features/csv_options.feature
288
316
  - features/csvupload.feature
317
+ - features/csvw_schema_validation.feature
289
318
  - features/fixtures/cr-line-endings.csv
290
319
  - features/fixtures/crlf-line-endings.csv
291
320
  - features/fixtures/inconsistent-line-endings-unquoted.csv
@@ -293,6 +322,7 @@ files:
293
322
  - features/fixtures/invalid-byte-sequence.csv
294
323
  - features/fixtures/lf-line-endings.csv
295
324
  - features/fixtures/spreadsheet.xls
325
+ - features/fixtures/spreadsheet.xlsx
296
326
  - features/fixtures/title-row.csv
297
327
  - features/fixtures/valid.csv
298
328
  - features/fixtures/windows-line-endings.csv
@@ -309,11 +339,19 @@ files:
309
339
  - features/step_definitions/validation_info_steps.rb
310
340
  - features/step_definitions/validation_warnings_steps.rb
311
341
  - features/support/env.rb
342
+ - features/support/load_tests.rb
312
343
  - features/support/webmock.rb
313
344
  - features/validation_errors.feature
314
345
  - features/validation_info.feature
315
346
  - features/validation_warnings.feature
316
347
  - lib/csvlint.rb
348
+ - lib/csvlint/csvw/column.rb
349
+ - lib/csvlint/csvw/date_format.rb
350
+ - lib/csvlint/csvw/metadata_error.rb
351
+ - lib/csvlint/csvw/number_format.rb
352
+ - lib/csvlint/csvw/property_checker.rb
353
+ - lib/csvlint/csvw/table.rb
354
+ - lib/csvlint/csvw/table_group.rb
317
355
  - lib/csvlint/error_collector.rb
318
356
  - lib/csvlint/error_message.rb
319
357
  - lib/csvlint/field.rb
@@ -321,6 +359,11 @@ files:
321
359
  - lib/csvlint/validate.rb
322
360
  - lib/csvlint/version.rb
323
361
  - lib/csvlint/wrapped_io.rb
362
+ - spec/csvw/column_spec.rb
363
+ - spec/csvw/date_format_spec.rb
364
+ - spec/csvw/number_format_spec.rb
365
+ - spec/csvw/table_group_spec.rb
366
+ - spec/csvw/table_spec.rb
324
367
  - spec/field_spec.rb
325
368
  - spec/schema_spec.rb
326
369
  - spec/spec_helper.rb
@@ -353,6 +396,7 @@ test_files:
353
396
  - features/check_format.feature
354
397
  - features/csv_options.feature
355
398
  - features/csvupload.feature
399
+ - features/csvw_schema_validation.feature
356
400
  - features/fixtures/cr-line-endings.csv
357
401
  - features/fixtures/crlf-line-endings.csv
358
402
  - features/fixtures/inconsistent-line-endings-unquoted.csv
@@ -360,6 +404,7 @@ test_files:
360
404
  - features/fixtures/invalid-byte-sequence.csv
361
405
  - features/fixtures/lf-line-endings.csv
362
406
  - features/fixtures/spreadsheet.xls
407
+ - features/fixtures/spreadsheet.xlsx
363
408
  - features/fixtures/title-row.csv
364
409
  - features/fixtures/valid.csv
365
410
  - features/fixtures/windows-line-endings.csv
@@ -376,10 +421,16 @@ test_files:
376
421
  - features/step_definitions/validation_info_steps.rb
377
422
  - features/step_definitions/validation_warnings_steps.rb
378
423
  - features/support/env.rb
424
+ - features/support/load_tests.rb
379
425
  - features/support/webmock.rb
380
426
  - features/validation_errors.feature
381
427
  - features/validation_info.feature
382
428
  - features/validation_warnings.feature
429
+ - spec/csvw/column_spec.rb
430
+ - spec/csvw/date_format_spec.rb
431
+ - spec/csvw/number_format_spec.rb
432
+ - spec/csvw/table_group_spec.rb
433
+ - spec/csvw/table_spec.rb
383
434
  - spec/field_spec.rb
384
435
  - spec/schema_spec.rb
385
436
  - spec/spec_helper.rb