wjordan213.csvlint 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitattributes +2 -0
  4. data/.gitignore +28 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +32 -0
  7. data/CHANGELOG.md +361 -0
  8. data/Gemfile +7 -0
  9. data/LICENSE.md +22 -0
  10. data/README.md +328 -0
  11. data/Rakefile +17 -0
  12. data/bin/create_schema +32 -0
  13. data/bin/csvlint +10 -0
  14. data/features/check_format.feature +46 -0
  15. data/features/cli.feature +210 -0
  16. data/features/csv_options.feature +35 -0
  17. data/features/csvupload.feature +145 -0
  18. data/features/csvw_schema_validation.feature +127 -0
  19. data/features/fixtures/cr-line-endings.csv +0 -0
  20. data/features/fixtures/crlf-line-endings.csv +0 -0
  21. data/features/fixtures/inconsistent-line-endings-unquoted.csv +0 -0
  22. data/features/fixtures/inconsistent-line-endings.csv +0 -0
  23. data/features/fixtures/invalid-byte-sequence.csv +0 -0
  24. data/features/fixtures/invalid_many_rows.csv +0 -0
  25. data/features/fixtures/lf-line-endings.csv +0 -0
  26. data/features/fixtures/spreadsheet.xls +0 -0
  27. data/features/fixtures/spreadsheet.xlsx +0 -0
  28. data/features/fixtures/title-row.csv +0 -0
  29. data/features/fixtures/valid.csv +0 -0
  30. data/features/fixtures/valid_many_rows.csv +0 -0
  31. data/features/fixtures/windows-line-endings.csv +0 -0
  32. data/features/information.feature +22 -0
  33. data/features/parse_csv.feature +90 -0
  34. data/features/schema_validation.feature +105 -0
  35. data/features/sources.feature +17 -0
  36. data/features/step_definitions/cli_steps.rb +11 -0
  37. data/features/step_definitions/csv_options_steps.rb +24 -0
  38. data/features/step_definitions/information_steps.rb +13 -0
  39. data/features/step_definitions/parse_csv_steps.rb +42 -0
  40. data/features/step_definitions/schema_validation_steps.rb +33 -0
  41. data/features/step_definitions/sources_steps.rb +7 -0
  42. data/features/step_definitions/validation_errors_steps.rb +90 -0
  43. data/features/step_definitions/validation_info_steps.rb +22 -0
  44. data/features/step_definitions/validation_warnings_steps.rb +60 -0
  45. data/features/support/aruba.rb +56 -0
  46. data/features/support/env.rb +26 -0
  47. data/features/support/load_tests.rb +114 -0
  48. data/features/support/webmock.rb +1 -0
  49. data/features/validation_errors.feature +147 -0
  50. data/features/validation_info.feature +16 -0
  51. data/features/validation_warnings.feature +86 -0
  52. data/lib/csvlint.rb +27 -0
  53. data/lib/csvlint/cli.rb +165 -0
  54. data/lib/csvlint/csvw/column.rb +359 -0
  55. data/lib/csvlint/csvw/date_format.rb +182 -0
  56. data/lib/csvlint/csvw/metadata_error.rb +13 -0
  57. data/lib/csvlint/csvw/number_format.rb +211 -0
  58. data/lib/csvlint/csvw/property_checker.rb +761 -0
  59. data/lib/csvlint/csvw/table.rb +204 -0
  60. data/lib/csvlint/csvw/table_group.rb +165 -0
  61. data/lib/csvlint/error_collector.rb +27 -0
  62. data/lib/csvlint/error_message.rb +15 -0
  63. data/lib/csvlint/field.rb +196 -0
  64. data/lib/csvlint/schema.rb +92 -0
  65. data/lib/csvlint/validate.rb +599 -0
  66. data/lib/csvlint/version.rb +3 -0
  67. data/spec/csvw/column_spec.rb +112 -0
  68. data/spec/csvw/date_format_spec.rb +49 -0
  69. data/spec/csvw/number_format_spec.rb +417 -0
  70. data/spec/csvw/table_group_spec.rb +143 -0
  71. data/spec/csvw/table_spec.rb +90 -0
  72. data/spec/field_spec.rb +252 -0
  73. data/spec/schema_spec.rb +211 -0
  74. data/spec/spec_helper.rb +17 -0
  75. data/spec/validator_spec.rb +619 -0
  76. data/wjordan213_csvlint.gemspec +46 -0
  77. metadata +490 -0
@@ -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
@@ -0,0 +1,252 @@
1
+ require 'spec_helper'
2
+
3
+ describe Csvlint::Field do
4
+
5
+ it "should validate required fields" do
6
+ field = Csvlint::Field.new("test", { "required" => true } )
7
+ expect( field.validate_column( nil ) ).to be(false)
8
+ expect( field.errors.first.category ).to be(:schema)
9
+ expect( field.validate_column( "" ) ).to be(false)
10
+ expect( field.validate_column( "data" ) ).to be(true)
11
+ end
12
+
13
+ it "should include the failed constraints" do
14
+ field = Csvlint::Field.new("test", { "required" => true } )
15
+ expect( field.validate_column( nil ) ).to be(false)
16
+ expect( field.errors.first.constraints ).to eql( { "required" => true } )
17
+ end
18
+
19
+ it "should validate minimum length" do
20
+ field = Csvlint::Field.new("test", { "minLength" => 3 } )
21
+ expect( field.validate_column( nil ) ).to be(false)
22
+ expect( field.validate_column( "" ) ).to be(false)
23
+ expect( field.validate_column( "ab" ) ).to be(false)
24
+ expect( field.validate_column( "abc" ) ).to be(true)
25
+ expect( field.validate_column( "abcd" ) ).to be(true)
26
+ end
27
+
28
+ it "should validate maximum length" do
29
+ field = Csvlint::Field.new("test", { "maxLength" => 3 } )
30
+ expect( field.validate_column( nil ) ).to be(true)
31
+ expect( field.validate_column( "" ) ).to be(true)
32
+ expect( field.validate_column( "ab" ) ).to be(true)
33
+ expect( field.validate_column( "abc" ) ).to be(true)
34
+ expect( field.validate_column( "abcd" ) ).to be(false)
35
+ end
36
+
37
+ it "should validate against regex" do
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
+ expect( field.validate_column( "abc") ).to be(false)
40
+ expect( field.validate_column( "{3B0DA29C-C89A-4FAA-918A-0000074FA0E0}") ).to be(true)
41
+ end
42
+
43
+ it "should apply combinations of constraints" do
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
+ expect( field.validate_column( "abc") ).to be(false)
46
+ expect( field.errors.first.constraints ).to eql( { "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}\}" } )
47
+
48
+ expect( field.validate_column( nil ) ).to be(false)
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
+
53
+ end
54
+
55
+ it "should enforce uniqueness for a column" do
56
+ field = Csvlint::Field.new("test", { "unique" => true } )
57
+ expect( field.validate_column( "abc") ).to be(true)
58
+ expect( field.validate_column( "abc") ).to be(false)
59
+ expect( field.errors.first.category ).to be(:schema)
60
+ expect( field.errors.first.type ).to be(:unique)
61
+ end
62
+
63
+ context "it should validate correct types" do
64
+ it "skips empty fields" do
65
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#int" })
66
+ expect( field.validate_column("")).to be(true)
67
+ end
68
+
69
+ it "validates strings" do
70
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#string" })
71
+ expect( field.validate_column("42")).to be(true)
72
+ expect( field.validate_column("forty-two")).to be(true)
73
+ end
74
+
75
+ it "validates ints" do
76
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#int" })
77
+ expect( field.validate_column("42")).to be(true)
78
+ expect( field.validate_column("forty-two")).to be(false)
79
+ end
80
+
81
+ it "validates integers" do
82
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#integer" })
83
+ expect( field.validate_column("42")).to be(true)
84
+ expect( field.validate_column("forty-two")).to be(false)
85
+ end
86
+
87
+ it "validates floats" do
88
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#float" })
89
+ expect(field.validate_column("42.0")).to be(true)
90
+ expect(field.validate_column("42")).to be(true)
91
+ expect(field.validate_column("forty-two")).to be(false)
92
+ end
93
+
94
+ it "validates URIs" do
95
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#anyURI" })
96
+ expect(field.validate_column("http://theodi.org/team")).to be(true)
97
+ expect(field.validate_column("https://theodi.org/team")).to be(true)
98
+ expect(field.validate_column("42.0")).to be(false)
99
+ end
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
+
106
+ it "validates booleans" do
107
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#boolean" })
108
+ expect(field.validate_column("true")).to be(true)
109
+ expect(field.validate_column("1")).to be(true)
110
+ expect(field.validate_column("false")).to be(true)
111
+ expect(field.validate_column("0")).to be(true)
112
+ expect(field.validate_column("derp")).to be(false)
113
+ end
114
+
115
+ context "it should validate all kinds of integers" do
116
+ it "validates a non-positive integer" do
117
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#nonPositiveInteger" })
118
+ expect(field.validate_column("0")).to be(true)
119
+ expect(field.validate_column("-1")).to be(true)
120
+ expect(field.validate_column("1")).to be(false)
121
+ end
122
+
123
+ it "validates a negative integer" do
124
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#negativeInteger" })
125
+ expect(field.validate_column("0")).to be(false)
126
+ expect(field.validate_column("-1")).to be(true)
127
+ expect(field.validate_column("1")).to be(false)
128
+ end
129
+
130
+ it "validates a non-negative integer" do
131
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#nonNegativeInteger" })
132
+ expect(field.validate_column("0")).to be(true)
133
+ expect(field.validate_column("-1")).to be(false)
134
+ expect(field.validate_column("1")).to be(true)
135
+ end
136
+
137
+ it "validates a positive integer" do
138
+ field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#positiveInteger" })
139
+ expect(field.validate_column("0")).to be(false)
140
+ expect(field.validate_column("-1")).to be(false)
141
+ expect(field.errors.first.constraints).to eql( { "type" => "http://www.w3.org/2001/XMLSchema#positiveInteger" } )
142
+ expect(field.validate_column("1")).to be(true)
143
+ end
144
+ end
145
+
146
+ context "when validating ranges" do
147
+
148
+ it "should enforce minimum values" do
149
+ field = Csvlint::Field.new("test", {
150
+ "type" => "http://www.w3.org/2001/XMLSchema#int",
151
+ "minimum" => "40"
152
+ })
153
+ expect( field.validate_column("42")).to be(true)
154
+
155
+ field = Csvlint::Field.new("test", {
156
+ "type" => "http://www.w3.org/2001/XMLSchema#int",
157
+ "minimum" => "40"
158
+ })
159
+ expect( field.validate_column("39")).to be(false)
160
+ expect( field.errors.first.type ).to eql(:below_minimum)
161
+ end
162
+
163
+ it "should enforce maximum values" do
164
+ field = Csvlint::Field.new("test", {
165
+ "type" => "http://www.w3.org/2001/XMLSchema#int",
166
+ "maximum" => "40"
167
+ })
168
+ expect( field.validate_column("39")).to be(true)
169
+
170
+ field = Csvlint::Field.new("test", {
171
+ "type" => "http://www.w3.org/2001/XMLSchema#int",
172
+ "maximum" => "40"
173
+ })
174
+ expect( field.validate_column("41")).to be(false)
175
+ expect( field.errors.first.type ).to eql(:above_maximum)
176
+
177
+ end
178
+ end
179
+
180
+ context "when validating dates" do
181
+ it "should validate a date time" do
182
+ field = Csvlint::Field.new("test", {
183
+ "type" => "http://www.w3.org/2001/XMLSchema#dateTime"
184
+ })
185
+ expect( field.validate_column("2014-02-17T11:09:00Z")).to be(true)
186
+ expect( field.validate_column("invalid-date")).to be(false)
187
+ expect( field.validate_column("2014-02-17")).to be(false)
188
+ end
189
+ it "should validate a date" do
190
+ field = Csvlint::Field.new("test", {
191
+ "type" => "http://www.w3.org/2001/XMLSchema#date"
192
+ })
193
+ expect( field.validate_column("2014-02-17T11:09:00Z")).to be(false)
194
+ expect( field.validate_column("invalid-date")).to be(false)
195
+ expect( field.validate_column("2014-02-17")).to be(true)
196
+ end
197
+ it "should validate a time" do
198
+ field = Csvlint::Field.new("test", {
199
+ "type" => "http://www.w3.org/2001/XMLSchema#time"
200
+ })
201
+ expect( field.validate_column("11:09:00")).to be(true)
202
+ expect( field.validate_column("2014-02-17T11:09:00Z")).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)
205
+ end
206
+ it "should validate a year" do
207
+ field = Csvlint::Field.new("test", {
208
+ "type" => "http://www.w3.org/2001/XMLSchema#gYear"
209
+ })
210
+ expect( field.validate_column("1999")).to be(true)
211
+ expect( field.validate_column("2525")).to be(true)
212
+ expect( field.validate_column("0001")).to be(true)
213
+ expect( field.validate_column("2014-02-17T11:09:00Z")).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)
216
+ end
217
+ it "should validate a year-month" do
218
+ field = Csvlint::Field.new("test", {
219
+ "type" => "http://www.w3.org/2001/XMLSchema#gYearMonth"
220
+ })
221
+ expect( field.validate_column("1999-12")).to be(true)
222
+ expect( field.validate_column("2525-01")).to be(true)
223
+ expect( field.validate_column("2014-02-17T11:09:00Z")).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)
226
+ end
227
+ it "should allow user to specify custom date time pattern" do
228
+ field = Csvlint::Field.new("test", {
229
+ "type" => "http://www.w3.org/2001/XMLSchema#dateTime",
230
+ "datePattern" => "%Y-%m-%d %H:%M:%S"
231
+ })
232
+ expect( field.validate_column("1999-12-01 10:00:00")).to be(true)
233
+ expect( field.validate_column("invalid-date")).to be(false)
234
+ expect( field.validate_column("2014-02-17")).to be(false)
235
+ expect( field.errors.first.constraints ).to eql( {
236
+ "type" => "http://www.w3.org/2001/XMLSchema#dateTime",
237
+ "datePattern" => "%Y-%m-%d %H:%M:%S"
238
+ })
239
+
240
+ end
241
+ it "should allow user to compare dates" do
242
+ field = Csvlint::Field.new("test", {
243
+ "type" => "http://www.w3.org/2001/XMLSchema#dateTime",
244
+ "datePattern" => "%Y-%m-%d %H:%M:%S",
245
+ "minimum" => "1990-01-01 10:00:00"
246
+ })
247
+ expect( field.validate_column("1999-12-01 10:00:00")).to be(true)
248
+ expect( field.validate_column("1989-12-01 10:00:00")).to be(false)
249
+ end
250
+ end
251
+ end
252
+ end