csvlint 0.2.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,22 +20,22 @@ module Csvlint
20
20
  @warnings += @tables.map{|url,table| table.warnings}.flatten
21
21
  end
22
22
 
23
- def validate_header(header, table_url)
23
+ def validate_header(header, table_url, strict)
24
24
  reset
25
25
  table_url = "file:#{File.absolute_path(table_url)}" if table_url.instance_of? File
26
26
  table = tables[table_url]
27
- table.validate_header(header)
27
+ table.validate_header(header, strict)
28
28
  @errors += table.errors
29
29
  @warnings += table.warnings
30
30
  return valid?
31
31
  end
32
32
 
33
- def validate_row(values, row=nil, all_errors=[], table_url)
33
+ def validate_row(values, row=nil, all_errors=[], table_url, validate)
34
34
  reset
35
35
  table_url = "file:#{File.absolute_path(table_url)}" if table_url.instance_of? File
36
36
  @validated_tables[table_url] = true
37
37
  table = tables[table_url]
38
- table.validate_row(values, row)
38
+ table.validate_row(values, row, validate)
39
39
  @errors += table.errors
40
40
  @warnings += table.warnings
41
41
  return valid?
@@ -93,10 +93,10 @@ module Csvlint
93
93
  annotations[property] = v
94
94
  elsif type == :common
95
95
  common_properties[property] = v
96
- elsif type == :column
97
- warnings << Csvlint::ErrorMessage.new(:invalid_property, :metadata, nil, nil, "#{property}", nil)
98
- else
96
+ elsif type == :inherited
99
97
  inherited_properties[property] = v
98
+ else
99
+ warnings << Csvlint::ErrorMessage.new(:invalid_property, :metadata, nil, nil, "#{property}", nil)
100
100
  end
101
101
  end
102
102
  end
@@ -118,7 +118,7 @@ module Csvlint
118
118
  end
119
119
  table_url = URI.join(base_url, table_url).to_s
120
120
  table_desc["url"] = table_url
121
- table = Csvlint::Csvw::Table.from_json(table_desc, base_url, lang, inherited_properties)
121
+ table = Csvlint::Csvw::Table.from_json(table_desc, base_url, lang, common_properties, inherited_properties)
122
122
  tables[table_url] = table
123
123
  else
124
124
  warnings << Csvlint::ErrorMessage.new(:invalid_table_description, :metadata, nil, nil, "#{table_desc}", nil)
@@ -154,7 +154,7 @@ module Csvlint
154
154
  end
155
155
  end
156
156
 
157
- return self.new(base_url, id: id, tables: tables, notes: json["notes"] || [], annotations: annotations, warnings: warnings)
157
+ return self.new(base_url, id: id, tables: tables, notes: common_properties["notes"] || [], annotations: annotations, warnings: warnings)
158
158
  end
159
159
 
160
160
  private
@@ -54,7 +54,7 @@ module Csvlint
54
54
 
55
55
  end
56
56
 
57
- def validate_header(header, source_url=nil)
57
+ def validate_header(header, source_url=nil, validate=true)
58
58
  reset
59
59
 
60
60
  found_header = header.to_csv(:row_sep => '')
@@ -65,7 +65,7 @@ module Csvlint
65
65
  return valid?
66
66
  end
67
67
 
68
- def validate_row(values, row=nil, all_errors=[], source_url=nil)
68
+ def validate_row(values, row=nil, all_errors=[], source_url=nil, validate=true)
69
69
  reset
70
70
  if values.length < fields.length
71
71
  fields[values.size..-1].each_with_index do |field, i|
@@ -68,6 +68,7 @@ module Csvlint
68
68
  @csv_header = true
69
69
  @headers = {}
70
70
  @lambda = options[:lambda]
71
+ @validate = options[:validate].nil? ? true : options[:validate]
71
72
  @leading = ""
72
73
 
73
74
  @limit_lines = options[:limit_lines]
@@ -151,6 +152,7 @@ module Csvlint
151
152
  end
152
153
  rescue ArgumentError => ae
153
154
  build_errors(:invalid_encoding, :structure, @current_line, nil, @current_line) unless @reported_invalid_encoding
155
+ @current_line = @current_line+1
154
156
  @reported_invalid_encoding = true
155
157
  end
156
158
 
@@ -181,7 +183,6 @@ module Csvlint
181
183
  build_exception_messages(e, stream, current_line)
182
184
  end
183
185
 
184
- @data << row
185
186
  if row
186
187
  if current_line <= 1 && @csv_header
187
188
  # this conditional should be refactored somewhere
@@ -195,7 +196,7 @@ module Csvlint
195
196
  build_errors(:blank_rows, :structure, current_line, nil, stream.to_s) if row.reject { |c| c.nil? || c.empty? }.size == 0
196
197
  # Builds errors and warnings related to the provided schema file
197
198
  if @schema
198
- @schema.validate_row(row, current_line, all_errors, @source)
199
+ @schema.validate_row(row, current_line, all_errors, @source, @validate)
199
200
  @errors += @schema.errors
200
201
  all_errors += @schema.errors
201
202
  @warnings += @schema.warnings
@@ -204,6 +205,7 @@ module Csvlint
204
205
  end
205
206
  end
206
207
  end
208
+ @data << row
207
209
  end
208
210
 
209
211
  def finish
@@ -214,7 +216,7 @@ module Csvlint
214
216
  # return expected_columns to calling class
215
217
  build_warnings(:check_options, :structure) if @expected_columns == 1
216
218
  check_consistency
217
- check_foreign_keys
219
+ check_foreign_keys if @validate
218
220
  check_mixed_linebreaks
219
221
  validate_encoding
220
222
  end
@@ -250,7 +252,7 @@ module Csvlint
250
252
  schema = Schema.load_from_json(url)
251
253
  if schema.instance_of? Csvlint::Csvw::TableGroup
252
254
  if schema.tables[@source_url]
253
- link_schema = schema
255
+ @schema = schema
254
256
  else
255
257
  warn_if_unsuccessful = true
256
258
  build_warnings(:schema_mismatch, :context, nil, nil, @source_url, schema)
@@ -293,6 +295,7 @@ module Csvlint
293
295
  end
294
296
  @dialect = {
295
297
  "header" => true,
298
+ "headerRowCount" => 1,
296
299
  "delimiter" => ",",
297
300
  "skipInitialSpace" => true,
298
301
  "lineTerminator" => :auto,
@@ -358,7 +361,7 @@ module Csvlint
358
361
  end
359
362
  end
360
363
  if @schema
361
- @schema.validate_header(header, @source)
364
+ @schema.validate_header(header, @source, @validate)
362
365
  @errors += @schema.errors
363
366
  @warnings += @schema.warnings
364
367
  end
@@ -441,15 +444,11 @@ module Csvlint
441
444
  @schema = nil
442
445
  end
443
446
  end
444
- link_schema = nil
445
- @schema = link_schema if link_schema
446
-
447
447
  paths = []
448
448
  if @source_url =~ /^http(s)?/
449
449
  begin
450
450
  well_known_uri = URI.join(@source_url, "/.well-known/csvm")
451
- well_known = open(well_known_uri).read
452
- # TODO
451
+ paths = open(well_known_uri).read.split("\n")
453
452
  rescue OpenURI::HTTPError, URI::BadURIError
454
453
  end
455
454
  end
@@ -464,6 +463,7 @@ module Csvlint
464
463
  if schema.instance_of? Csvlint::Csvw::TableGroup
465
464
  if schema.tables[@source_url]
466
465
  @schema = schema
466
+ return
467
467
  else
468
468
  warn_if_unsuccessful = true
469
469
  build_warnings(:schema_mismatch, :context, nil, nil, @source_url, schema)
@@ -472,9 +472,6 @@ module Csvlint
472
472
  rescue Errno::ENOENT
473
473
  rescue OpenURI::HTTPError, URI::BadURIError, ArgumentError
474
474
  rescue => e
475
- STDERR.puts e.class
476
- STDERR.puts e.message
477
- STDERR.puts e.backtrace
478
475
  raise e
479
476
  end
480
477
  end
@@ -1,3 +1,3 @@
1
1
  module Csvlint
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -4,21 +4,21 @@ describe Csvlint::Csvw::Column do
4
4
 
5
5
  it "shouldn't generate errors for string values" do
6
6
  column = Csvlint::Csvw::Column.new(1, "foo")
7
- valid = column.validate("bar", 2)
8
- expect(valid).to eq(true)
7
+ value = column.validate("bar", 2)
8
+ expect(value).to eq("bar")
9
9
  end
10
10
 
11
11
  it "should generate errors for string values that aren't long enough" do
12
12
  column = Csvlint::Csvw::Column.new(1, "foo", datatype: { "base" => "http://www.w3.org/2001/XMLSchema#string", "minLength" => 4 })
13
- valid = column.validate("bar", 2)
14
- expect(valid).to eq(false)
13
+ value = column.validate("bar", 2)
14
+ expect(value).to eq({ :invalid => "bar" })
15
15
  expect(column.errors.length).to eq(1)
16
16
  end
17
17
 
18
18
  it "shouldn't generate errors for string values that are long enough" do
19
19
  column = Csvlint::Csvw::Column.new(1, "foo", datatype: { "base" => "http://www.w3.org/2001/XMLSchema#string", "minLength" => 4 })
20
- valid = column.validate("barn", 2)
21
- expect(valid).to eq(true)
20
+ value = column.validate("barn", 2)
21
+ expect(value).to eq("barn")
22
22
  expect(column.errors.length).to eq(0)
23
23
  end
24
24
 
@@ -1,40 +1,40 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Csvlint::Csvw::NumberFormat do
3
+ describe Csvlint::Csvw::DateFormat do
4
4
 
5
5
  it "should parse dates that match yyyy-MM-dd correctly" do
6
6
  format = Csvlint::Csvw::DateFormat.new("yyyy-MM-dd")
7
- expect(format.parse("2015-03-22")).to eql(Date.new(2015, 3, 22))
7
+ expect(format.parse("2015-03-22")[:dateTime]).to eql(Date.new(2015, 3, 22))
8
8
  expect(format.parse("2015-02-30")).to eql(nil)
9
9
  expect(format.parse("22/03/2015")).to eq(nil)
10
10
  end
11
11
 
12
12
  it "should parse times that match HH:mm:ss correctly" do
13
13
  format = Csvlint::Csvw::DateFormat.new("HH:mm:ss")
14
- expect(format.parse("12:34:56")).to eql({ "hour" => 12, "minute" => 34, "second" => 56.0 })
14
+ expect(format.parse("12:34:56")).to eql({ :hour => 12, :minute => 34, :second => 56.0, :string => "12:34:56", :dateTime => DateTime.new(0,1,1,12,34,56.0,"+00:00") })
15
15
  expect(format.parse("22/03/2015")).to eq(nil)
16
16
  end
17
17
 
18
18
  it "should parse times that match HH:mm:ss.SSS correctly" do
19
19
  format = Csvlint::Csvw::DateFormat.new("HH:mm:ss.SSS")
20
- expect(format.parse("12:34:56")).to eql({ "hour" => 12, "minute" => 34, "second" => 56.0 })
21
- expect(format.parse("12:34:56.78")).to eql({ "hour" => 12, "minute" => 34, "second" => 56.78 })
22
- expect(format.parse("12:34:56.789")).to eql({ "hour" => 12, "minute" => 34, "second" => 56.789 })
20
+ expect(format.parse("12:34:56")).to eql({ :hour => 12, :minute => 34, :second => 56.0, :string => "12:34:56", :dateTime => DateTime.new(0,1,1,12,34,56.0,"+00:00") })
21
+ expect(format.parse("12:34:56.78")).to eql({ :hour => 12, :minute => 34, :second => 56.78, :string => "12:34:56.78", :dateTime => DateTime.new(0,1,1,12,34,56.78,"+00:00") })
22
+ expect(format.parse("12:34:56.789")).to eql({ :hour => 12, :minute => 34, :second => 56.789, :string => "12:34:56.789", :dateTime => DateTime.new(0,1,1,12,34,56.789,"+00:00") })
23
23
  expect(format.parse("12:34:56.7890")).to eql(nil)
24
24
  expect(format.parse("22/03/2015")).to eq(nil)
25
25
  end
26
26
 
27
27
  it "should parse dateTimes that match yyyy-MM-ddTHH:mm:ss correctly" do
28
28
  format = Csvlint::Csvw::DateFormat.new("yyyy-MM-ddTHH:mm:ss")
29
- expect(format.parse("2015-03-15T15:02:37")).to eql(DateTime.new(2015, 3, 15, 15, 2, 37))
29
+ expect(format.parse("2015-03-15T15:02:37")[:dateTime]).to eql(DateTime.new(2015, 3, 15, 15, 2, 37))
30
30
  expect(format.parse("12:34:56")).to eql(nil)
31
31
  expect(format.parse("22/03/2015")).to eq(nil)
32
32
  end
33
33
 
34
34
  it "should parse dateTimes that match yyyy-MM-ddTHH:mm:ss.S correctly" do
35
35
  format = Csvlint::Csvw::DateFormat.new("yyyy-MM-ddTHH:mm:ss.S")
36
- expect(format.parse("2015-03-15T15:02:37")).to eql(DateTime.new(2015, 3, 15, 15, 2, 37.0))
37
- expect(format.parse("2015-03-15T15:02:37.4")).to eql(DateTime.new(2015, 3, 15, 15, 2, 37.4))
36
+ expect(format.parse("2015-03-15T15:02:37")[:dateTime]).to eql(DateTime.new(2015, 3, 15, 15, 2, 37.0))
37
+ expect(format.parse("2015-03-15T15:02:37.4")[:dateTime]).to eql(DateTime.new(2015, 3, 15, 15, 2, 37.4))
38
38
  expect(format.parse("2015-03-15T15:02:37.45")).to eql(nil)
39
39
  expect(format.parse("12:34:56")).to eql(nil)
40
40
  expect(format.parse("22/03/2015")).to eq(nil)
@@ -43,7 +43,7 @@ describe Csvlint::Csvw::NumberFormat do
43
43
  it "should parse dateTimes that match M/d/yyyy HH:mm correctly" do
44
44
  format = Csvlint::Csvw::DateFormat.new("M/d/yyyy HH:mm")
45
45
  expect(format.parse("2015-03-15T15:02:37")).to eql(nil)
46
- expect(format.parse("3/15/2015 15:02")).to eql(DateTime.new(2015, 3, 15, 15, 2))
46
+ expect(format.parse("3/15/2015 15:02")[:dateTime]).to eql(DateTime.new(2015, 3, 15, 15, 2))
47
47
  end
48
48
 
49
49
  end
@@ -152,6 +152,7 @@ describe Csvlint::Csvw::NumberFormat do
152
152
 
153
153
  it "should parse numbers that match ##0 correctly" do
154
154
  format = Csvlint::Csvw::NumberFormat.new("##0")
155
+ expect(format.parse("-1")).to eql(-1)
155
156
  expect(format.parse("1")).to eql(1)
156
157
  expect(format.parse("12")).to eql(12)
157
158
  expect(format.parse("123")).to eql(123)
@@ -380,6 +381,21 @@ describe Csvlint::Csvw::NumberFormat do
380
381
  expect(format.parse("12.34E5")).to eql(12.34E5)
381
382
  end
382
383
 
384
+ it "should parse numbers that match %000 correctly" do
385
+ format = Csvlint::Csvw::NumberFormat.new("%000")
386
+ expect(format.parse("%001")).to eq(0.01)
387
+ expect(format.parse("%012")).to eq(0.12)
388
+ expect(format.parse("%123")).to eq(1.23)
389
+ expect(format.parse("%1234")).to eq(12.34)
390
+ end
391
+
392
+ it "should parse numbers that match -0 correctly" do
393
+ format = Csvlint::Csvw::NumberFormat.new("-0")
394
+ expect(format.parse("1")).to eq(nil)
395
+ expect(format.parse("-1")).to eq(-1)
396
+ expect(format.parse("-12")).to eq(-12)
397
+ end
398
+
383
399
  it "should parse numbers normally when there is no pattern" do
384
400
  format = Csvlint::Csvw::NumberFormat.new()
385
401
  expect(format.parse("1")).to eql(1)
@@ -414,4 +430,17 @@ describe Csvlint::Csvw::NumberFormat do
414
430
  expect(format.parse("-INF")).to eql(-Float::INFINITY)
415
431
  end
416
432
 
433
+ it "should parse numbers including decimal separators when they are specified" do
434
+ format = Csvlint::Csvw::NumberFormat.new(nil, " ", ",")
435
+ expect(format.parse("1")).to eql(1)
436
+ expect(format.parse("12,3")).to eql(12.3)
437
+ expect(format.parse("12,34")).to eql(12.34)
438
+ expect(format.parse("12,3E4")).to eql(12.3E4)
439
+ expect(format.parse("12,3E45")).to eql(12.3E45)
440
+ expect(format.parse("12,34E5")).to eql(12.34E5)
441
+ expect(format.parse("1 234")).to eql(1234)
442
+ expect(format.parse("1 234 567")).to eql(1234567)
443
+ expect(format.parse("1 234")).to eq(nil)
444
+ end
445
+
417
446
  end
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.2.6
4
+ version: 0.3.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-11-16 00:00:00.000000000 Z
11
+ date: 2016-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mime-types
@@ -332,6 +332,34 @@ dependencies:
332
332
  - - ! '>='
333
333
  - !ruby/object:Gem::Version
334
334
  version: '0'
335
+ - !ruby/object:Gem::Dependency
336
+ name: rdf
337
+ requirement: !ruby/object:Gem::Requirement
338
+ requirements:
339
+ - - ! '>='
340
+ - !ruby/object:Gem::Version
341
+ version: '0'
342
+ type: :development
343
+ prerelease: false
344
+ version_requirements: !ruby/object:Gem::Requirement
345
+ requirements:
346
+ - - ! '>='
347
+ - !ruby/object:Gem::Version
348
+ version: '0'
349
+ - !ruby/object:Gem::Dependency
350
+ name: rdf-turtle
351
+ requirement: !ruby/object:Gem::Requirement
352
+ requirements:
353
+ - - ! '>='
354
+ - !ruby/object:Gem::Version
355
+ version: '0'
356
+ type: :development
357
+ prerelease: false
358
+ version_requirements: !ruby/object:Gem::Requirement
359
+ requirements:
360
+ - - ! '>='
361
+ - !ruby/object:Gem::Version
362
+ version: '0'
335
363
  description: CSV Validator
336
364
  email:
337
365
  - pezholio@gmail.com
@@ -371,6 +399,7 @@ files:
371
399
  - features/fixtures/title-row.csv
372
400
  - features/fixtures/valid.csv
373
401
  - features/fixtures/valid_many_rows.csv
402
+ - features/fixtures/w3.org/.well-known/csvm
374
403
  - features/fixtures/windows-line-endings.csv
375
404
  - features/information.feature
376
405
  - features/parse_csv.feature
@@ -386,6 +415,7 @@ files:
386
415
  - features/step_definitions/validation_info_steps.rb
387
416
  - features/step_definitions/validation_warnings_steps.rb
388
417
  - features/support/aruba.rb
418
+ - features/support/earl_formatter.rb
389
419
  - features/support/env.rb
390
420
  - features/support/load_tests.rb
391
421
  - features/support/webmock.rb
@@ -458,6 +488,7 @@ test_files:
458
488
  - features/fixtures/title-row.csv
459
489
  - features/fixtures/valid.csv
460
490
  - features/fixtures/valid_many_rows.csv
491
+ - features/fixtures/w3.org/.well-known/csvm
461
492
  - features/fixtures/windows-line-endings.csv
462
493
  - features/information.feature
463
494
  - features/parse_csv.feature
@@ -473,6 +504,7 @@ test_files:
473
504
  - features/step_definitions/validation_info_steps.rb
474
505
  - features/step_definitions/validation_warnings_steps.rb
475
506
  - features/support/aruba.rb
507
+ - features/support/earl_formatter.rb
476
508
  - features/support/env.rb
477
509
  - features/support/load_tests.rb
478
510
  - features/support/webmock.rb