csvlint 0.1.1 → 0.1.2

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MDgwMGE1ZmY5ZWE2MzM2ODhhMTFhZjM5NTkyZTNkZWExZjFkN2I0Mw==
4
+ NjUyMGZlNGIyNjM4ZmU1OGVjMDc3Y2U2YmQ0NWEzMzM3ZGFkYzA0Yw==
5
5
  data.tar.gz: !binary |-
6
- OTRhZTljMTc5ZDlmZDVlMmQ2ZDU2MTFmYmRlNGUyMGIyMTI3NTBmOQ==
6
+ NzYzMjUxY2NlZmE4ODY3NjYwNTU4NzUyMmE2NTU0NjM1MmQ0YzI4NQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZDE4YWVlNGYzY2E5OGJjM2ZkZjA0MzQwMWE1Yzg5YTI3YzM0MjNkMmFhNjFj
10
- YmY3YzYzN2E5NDk1NDM4YmNmMGY1ZWRlNmExZWI0NmYzZmQzNTc2N2ZiOTMx
11
- YzU2MjhiMmE4YTc2NTVmNzE4YWI4ZDZjOWM5MDlhNTRlY2RkMzE=
9
+ ODQwMGQzMjY4NGQzNGY5ZGY1Nzg3ODc5MDI3M2E3NmNmNzUwNzU1MzBjNjNk
10
+ YzRiMjE3NTJlNTc5YWI2NjhkNGJjNDcxNzVkMDgyZmRkYjZlYWFmZjUyOWQx
11
+ ZmVkOWRjZDJhMGU4M2QyYmI0YzZmMDBlYWRhMjFmNGFlZmJmZTg=
12
12
  data.tar.gz: !binary |-
13
- NDY1ODhkODdlZDJlYzMyMTQ1NzFlYzAyNTYyN2YzMGE1NTM2Yzg1NWRiYTQ5
14
- NmQ1ODE5MzNmOTU4ZjhmNmZjNWQwNWU1N2E5OTdmOWMyZmZiYjE4ZmVhNmVh
15
- YzdmN2VmNjY1NjFkMDdmYTc0YzZiNTk2YWQxMWZkMmRkNmVhODg=
13
+ ZjhkODBhMWU1ODFjN2JiNjQ3ZjBlZmFkNzAwMmVhOTNiYzgwNDNjM2RjODg5
14
+ YWE2NGUwNjk1M2JlYWFjZmVlY2U0YjNmMTZmM2U4YTFlMDcyMGViNWU3NWY2
15
+ NTY5NmIyNmE5ZjYwNDkwOTE1NjQ2MWRiZGU0ZGRhM2MxMTEyYjU=
data/README.md CHANGED
@@ -221,7 +221,7 @@ Schema validation provides some additional types of error and warning messages:
221
221
  * `:min_length` (error) -- a column with a `minLength` constraint has a value that is too short
222
222
  * `:max_length` (error) -- a column with a `maxLength` constraint has a value that is too long
223
223
  * `:pattern` (error) -- a column with a `pattern` constraint has a value that doesn't match the regular expression
224
- * `:header_name` (warning) -- the header in the CSV has a column name that doesn't match the schema
224
+ * `:malformed_header` (warning) -- the header in the CSV doesn't match the schema
225
225
  * `:missing_column` (warning) -- a row in the CSV file has a missing column, that is specified in the schema. This is a warning only, as it may be legitimate
226
226
  * `:extra_column` (warning) -- a row in the CSV file has extra column.
227
227
  * `:unique` (error) -- a column with a `unique` constraint contains non-unique values
@@ -105,8 +105,12 @@ module Csvlint
105
105
  'http://www.w3.org/2001/XMLSchema#float' => lambda { |value, constraints| Float value },
106
106
  'http://www.w3.org/2001/XMLSchema#double' => lambda { |value, constraints| Float value },
107
107
  'http://www.w3.org/2001/XMLSchema#anyURI' => lambda do |value, constraints|
108
- u = URI.parse value
109
- raise ArgumentError unless u.kind_of?(URI::HTTP) || u.kind_of?(URI::HTTPS)
108
+ begin
109
+ u = URI.parse value
110
+ raise ArgumentError unless u.kind_of?(URI::HTTP) || u.kind_of?(URI::HTTPS)
111
+ rescue URI::InvalidURIError
112
+ raise ArgumentError
113
+ end
110
114
  u
111
115
  end,
112
116
  'http://www.w3.org/2001/XMLSchema#boolean' => lambda do |value, constraints|
@@ -16,9 +16,13 @@ module Csvlint
16
16
 
17
17
  def validate_header(header)
18
18
  reset
19
- header.each_with_index do |name,i|
20
- build_warnings(:header_name, :schema, nil, i+1, name) if fields[i].name != name
19
+
20
+ found_header = header.join(',')
21
+ expected_header = @fields.map{ |f| f.name }.join(',')
22
+ if found_header != expected_header
23
+ build_warnings(:malformed_header, :schema, 1, nil, found_header, expected_header)
21
24
  end
25
+
22
26
  return valid?
23
27
  end
24
28
 
@@ -1,3 +1,3 @@
1
1
  module Csvlint
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -1,45 +1,45 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Csvlint::Field do
4
-
4
+
5
5
  it "should validate required fields" do
6
6
  field = Csvlint::Field.new("test", { "required" => true } )
7
- expect( field.validate_column( nil ) ).to be(false)
7
+ expect( field.validate_column( nil ) ).to be(false)
8
8
  expect( field.errors.first.category ).to be(:schema)
9
9
  expect( field.validate_column( "" ) ).to be(false)
10
10
  expect( field.validate_column( "data" ) ).to be(true)
11
11
  end
12
-
12
+
13
13
  it "should include the failed constraints" do
14
14
  field = Csvlint::Field.new("test", { "required" => true } )
15
- expect( field.validate_column( nil ) ).to be(false)
15
+ expect( field.validate_column( nil ) ).to be(false)
16
16
  expect( field.errors.first.constraints ).to eql( { "required" => true } )
17
17
  end
18
-
18
+
19
19
  it "should validate minimum length" do
20
20
  field = Csvlint::Field.new("test", { "minLength" => 3 } )
21
21
  expect( field.validate_column( nil ) ).to be(false)
22
- expect( field.validate_column( "" ) ).to be(false)
22
+ expect( field.validate_column( "" ) ).to be(false)
23
23
  expect( field.validate_column( "ab" ) ).to be(false)
24
24
  expect( field.validate_column( "abc" ) ).to be(true)
25
- expect( field.validate_column( "abcd" ) ).to be(true)
25
+ expect( field.validate_column( "abcd" ) ).to be(true)
26
26
  end
27
-
27
+
28
28
  it "should validate maximum length" do
29
29
  field = Csvlint::Field.new("test", { "maxLength" => 3 } )
30
30
  expect( field.validate_column( nil ) ).to be(true)
31
- expect( field.validate_column( "" ) ).to be(true)
31
+ expect( field.validate_column( "" ) ).to be(true)
32
32
  expect( field.validate_column( "ab" ) ).to be(true)
33
33
  expect( field.validate_column( "abc" ) ).to be(true)
34
34
  expect( field.validate_column( "abcd" ) ).to be(false)
35
35
  end
36
-
36
+
37
37
  it "should validate against regex" do
38
38
  field = Csvlint::Field.new("test", { "pattern" => "\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\}"} )
39
39
  expect( field.validate_column( "abc") ).to be(false)
40
- expect( field.validate_column( "{3B0DA29C-C89A-4FAA-918A-0000074FA0E0}") ).to be(true)
40
+ expect( field.validate_column( "{3B0DA29C-C89A-4FAA-918A-0000074FA0E0}") ).to be(true)
41
41
  end
42
-
42
+
43
43
  it "should apply combinations of constraints" do
44
44
  field = Csvlint::Field.new("test", { "required"=>true, "pattern" => "\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\}"} )
45
45
  expect( field.validate_column( "abc") ).to be(false)
@@ -47,9 +47,9 @@ describe Csvlint::Field do
47
47
 
48
48
  expect( field.validate_column( nil ) ).to be(false)
49
49
  expect( field.errors.first.constraints ).to eql( { "required"=>true } )
50
-
51
- expect( field.validate_column( "{3B0DA29C-C89A-4FAA-918A-0000074FA0E0}") ).to be(true)
52
-
50
+
51
+ expect( field.validate_column( "{3B0DA29C-C89A-4FAA-918A-0000074FA0E0}") ).to be(true)
52
+
53
53
  end
54
54
 
55
55
  it "should enforce uniqueness for a column" do
@@ -65,13 +65,13 @@ describe Csvlint::Field do
65
65
  field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#int" })
66
66
  expect( field.validate_column("")).to be(true)
67
67
  end
68
-
68
+
69
69
  it "validates strings" do
70
70
  field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#string" })
71
71
  expect( field.validate_column("42")).to be(true)
72
72
  expect( field.validate_column("forty-two")).to be(true)
73
73
  end
74
-
74
+
75
75
  it "validates ints" do
76
76
  field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#int" })
77
77
  expect( field.validate_column("42")).to be(true)
@@ -82,7 +82,7 @@ describe Csvlint::Field do
82
82
  field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#integer" })
83
83
  expect( field.validate_column("42")).to be(true)
84
84
  expect( field.validate_column("forty-two")).to be(false)
85
- end
85
+ end
86
86
 
87
87
  it "validates floats" do
88
88
  field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#float" })
@@ -98,6 +98,11 @@ describe Csvlint::Field do
98
98
  expect(field.validate_column("42.0")).to be(false)
99
99
  end
100
100
 
101
+ it "works with invalid URIs" do
102
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#anyURI" })
103
+ expect(field.validate_column("£123")).to be(false)
104
+ end
105
+
101
106
  it "validates booleans" do
102
107
  field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#boolean" })
103
108
  expect(field.validate_column("true")).to be(true)
@@ -137,111 +142,111 @@ describe Csvlint::Field do
137
142
  expect(field.validate_column("1")).to be(true)
138
143
  end
139
144
  end
140
-
145
+
141
146
  context "when validating ranges" do
142
-
147
+
143
148
  it "should enforce minimum values" do
144
- field = Csvlint::Field.new("test", {
149
+ field = Csvlint::Field.new("test", {
145
150
  "type" => "http://www.w3.org/2001/XMLSchema#int",
146
151
  "minimum" => "40"
147
152
  })
148
153
  expect( field.validate_column("42")).to be(true)
149
154
 
150
- field = Csvlint::Field.new("test", {
155
+ field = Csvlint::Field.new("test", {
151
156
  "type" => "http://www.w3.org/2001/XMLSchema#int",
152
157
  "minimum" => "40"
153
158
  })
154
- expect( field.validate_column("39")).to be(false)
159
+ expect( field.validate_column("39")).to be(false)
155
160
  expect( field.errors.first.type ).to eql(:below_minimum)
156
161
  end
157
-
162
+
158
163
  it "should enforce maximum values" do
159
- field = Csvlint::Field.new("test", {
164
+ field = Csvlint::Field.new("test", {
160
165
  "type" => "http://www.w3.org/2001/XMLSchema#int",
161
166
  "maximum" => "40"
162
167
  })
163
168
  expect( field.validate_column("39")).to be(true)
164
169
 
165
- field = Csvlint::Field.new("test", {
170
+ field = Csvlint::Field.new("test", {
166
171
  "type" => "http://www.w3.org/2001/XMLSchema#int",
167
172
  "maximum" => "40"
168
173
  })
169
- expect( field.validate_column("41")).to be(false)
174
+ expect( field.validate_column("41")).to be(false)
170
175
  expect( field.errors.first.type ).to eql(:above_maximum)
171
176
 
172
- end
177
+ end
173
178
  end
174
-
179
+
175
180
  context "when validating dates" do
176
181
  it "should validate a date time" do
177
- field = Csvlint::Field.new("test", {
182
+ field = Csvlint::Field.new("test", {
178
183
  "type" => "http://www.w3.org/2001/XMLSchema#dateTime"
179
184
  })
180
185
  expect( field.validate_column("2014-02-17T11:09:00Z")).to be(true)
181
186
  expect( field.validate_column("invalid-date")).to be(false)
182
- expect( field.validate_column("2014-02-17")).to be(false)
187
+ expect( field.validate_column("2014-02-17")).to be(false)
183
188
  end
184
189
  it "should validate a date" do
185
- field = Csvlint::Field.new("test", {
190
+ field = Csvlint::Field.new("test", {
186
191
  "type" => "http://www.w3.org/2001/XMLSchema#date"
187
192
  })
188
193
  expect( field.validate_column("2014-02-17T11:09:00Z")).to be(false)
189
194
  expect( field.validate_column("invalid-date")).to be(false)
190
- expect( field.validate_column("2014-02-17")).to be(true)
195
+ expect( field.validate_column("2014-02-17")).to be(true)
191
196
  end
192
197
  it "should validate a time" do
193
- field = Csvlint::Field.new("test", {
198
+ field = Csvlint::Field.new("test", {
194
199
  "type" => "http://www.w3.org/2001/XMLSchema#time"
195
200
  })
196
201
  expect( field.validate_column("11:09:00")).to be(true)
197
202
  expect( field.validate_column("2014-02-17T11:09:00Z")).to be(false)
198
- expect( field.validate_column("not-a-time")).to be(false)
199
- expect( field.validate_column("27:97:00")).to be(false)
203
+ expect( field.validate_column("not-a-time")).to be(false)
204
+ expect( field.validate_column("27:97:00")).to be(false)
200
205
  end
201
206
  it "should validate a year" do
202
- field = Csvlint::Field.new("test", {
207
+ field = Csvlint::Field.new("test", {
203
208
  "type" => "http://www.w3.org/2001/XMLSchema#gYear"
204
209
  })
205
210
  expect( field.validate_column("1999")).to be(true)
206
211
  expect( field.validate_column("2525")).to be(true)
207
212
  expect( field.validate_column("0001")).to be(true)
208
213
  expect( field.validate_column("2014-02-17T11:09:00Z")).to be(false)
209
- expect( field.validate_column("not-a-time")).to be(false)
210
- expect( field.validate_column("27:97:00")).to be(false)
214
+ expect( field.validate_column("not-a-time")).to be(false)
215
+ expect( field.validate_column("27:97:00")).to be(false)
211
216
  end
212
217
  it "should validate a year-month" do
213
- field = Csvlint::Field.new("test", {
218
+ field = Csvlint::Field.new("test", {
214
219
  "type" => "http://www.w3.org/2001/XMLSchema#gYearMonth"
215
220
  })
216
221
  expect( field.validate_column("1999-12")).to be(true)
217
222
  expect( field.validate_column("2525-01")).to be(true)
218
223
  expect( field.validate_column("2014-02-17T11:09:00Z")).to be(false)
219
- expect( field.validate_column("not-a-time")).to be(false)
220
- expect( field.validate_column("27:97:00")).to be(false)
224
+ expect( field.validate_column("not-a-time")).to be(false)
225
+ expect( field.validate_column("27:97:00")).to be(false)
221
226
  end
222
227
  it "should allow user to specify custom date time pattern" do
223
- field = Csvlint::Field.new("test", {
228
+ field = Csvlint::Field.new("test", {
224
229
  "type" => "http://www.w3.org/2001/XMLSchema#dateTime",
225
230
  "datePattern" => "%Y-%m-%d %H:%M:%S"
226
231
  })
227
232
  expect( field.validate_column("1999-12-01 10:00:00")).to be(true)
228
233
  expect( field.validate_column("invalid-date")).to be(false)
229
- expect( field.validate_column("2014-02-17")).to be(false)
230
- expect( field.errors.first.constraints ).to eql( {
234
+ expect( field.validate_column("2014-02-17")).to be(false)
235
+ expect( field.errors.first.constraints ).to eql( {
231
236
  "type" => "http://www.w3.org/2001/XMLSchema#dateTime",
232
237
  "datePattern" => "%Y-%m-%d %H:%M:%S"
233
238
  })
234
-
239
+
235
240
  end
236
241
  it "should allow user to compare dates" do
237
- field = Csvlint::Field.new("test", {
242
+ field = Csvlint::Field.new("test", {
238
243
  "type" => "http://www.w3.org/2001/XMLSchema#dateTime",
239
244
  "datePattern" => "%Y-%m-%d %H:%M:%S",
240
245
  "minimum" => "1990-01-01 10:00:00"
241
246
  })
242
247
  expect( field.validate_column("1999-12-01 10:00:00")).to be(true)
243
- expect( field.validate_column("1989-12-01 10:00:00")).to be(false)
248
+ expect( field.validate_column("1989-12-01 10:00:00")).to be(false)
244
249
  end
245
250
  end
246
251
  end
247
- end
252
+ end
@@ -94,16 +94,50 @@ describe Csvlint::Schema do
94
94
 
95
95
  expect( schema.validate_header(["wrong", "required"]) ).to eql(true)
96
96
  expect( schema.warnings.size ).to eql(1)
97
- expect( schema.warnings.first.type).to eql(:header_name)
98
- expect( schema.warnings.first.content).to eql("wrong")
99
- expect( schema.warnings.first.column).to eql(1)
100
- expect( schema.warnings.first.category).to eql(:schema)
101
-
97
+ expect( schema.warnings.first.row ).to eql(1)
98
+ expect( schema.warnings.first.type ).to eql(:malformed_header)
99
+ expect( schema.warnings.first.content ).to eql('wrong,required')
100
+ expect( schema.warnings.first.column ).to eql(nil)
101
+ expect( schema.warnings.first.category ).to eql(:schema)
102
+ expect( schema.warnings.first.constraints ).to eql('minimum,required')
103
+
102
104
  expect( schema.validate_header(["minimum", "Required"]) ).to eql(true)
103
105
  expect( schema.warnings.size ).to eql(1)
104
106
 
105
- end
106
- end
107
+ end
108
+
109
+ it "should warn if column count is less than field count" do
110
+ minimum = Csvlint::Field.new("minimum", { "minLength" => 3 } )
111
+ required = Csvlint::Field.new("required", { "required" => true } )
112
+ schema = Csvlint::Schema.new("http://example.org", [minimum, required] )
113
+
114
+ expect( schema.validate_header(["minimum"]) ).to eql(true)
115
+ expect( schema.warnings.size ).to eql(1)
116
+ expect( schema.warnings.first.row ).to eql(1)
117
+ expect( schema.warnings.first.type ).to eql(:malformed_header)
118
+ expect( schema.warnings.first.content ).to eql("minimum")
119
+ expect( schema.warnings.first.column ).to eql(nil)
120
+ expect( schema.warnings.first.category ).to eql(:schema)
121
+ expect( schema.warnings.first.constraints ).to eql('minimum,required')
122
+
123
+ end
124
+
125
+ it "should warn if column count is more than field count" do
126
+ minimum = Csvlint::Field.new("minimum", { "minLength" => 3 } )
127
+ schema = Csvlint::Schema.new("http://example.org", [minimum] )
128
+
129
+ expect( schema.validate_header(["wrong", "required"]) ).to eql(true)
130
+ expect( schema.warnings.size ).to eql(1)
131
+ expect( schema.warnings.first.row ).to eql(1)
132
+ expect( schema.warnings.first.type ).to eql(:malformed_header)
133
+ expect( schema.warnings.first.content ).to eql("wrong,required")
134
+ expect( schema.warnings.first.column ).to eql(nil)
135
+ expect( schema.warnings.first.category ).to eql(:schema)
136
+ expect( schema.warnings.first.constraints ).to eql('minimum')
137
+
138
+ end
139
+
140
+ end
107
141
 
108
142
  context "when parsing JSON Tables" do
109
143
 
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.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - pezholio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-13 00:00:00.000000000 Z
11
+ date: 2015-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mime-types