Skip to content

Commit

Permalink
Merge pull request #133 from theodi/feature-catch-invalid-uris
Browse files Browse the repository at this point in the history
Catch invalid URIs
  • Loading branch information
Floppy committed Jul 14, 2015
2 parents d44c2eb + dc4e6ba commit 85b819c
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 51 deletions.
8 changes: 6 additions & 2 deletions lib/csvlint/field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,12 @@ def convert_to_type(value)
'http://www.w3.org/2001/XMLSchema#float' => lambda { |value, constraints| Float value },
'http://www.w3.org/2001/XMLSchema#double' => lambda { |value, constraints| Float value },
'http://www.w3.org/2001/XMLSchema#anyURI' => lambda do |value, constraints|
u = URI.parse value
raise ArgumentError unless u.kind_of?(URI::HTTP) || u.kind_of?(URI::HTTPS)
begin
u = URI.parse value
raise ArgumentError unless u.kind_of?(URI::HTTP) || u.kind_of?(URI::HTTPS)
rescue URI::InvalidURIError
raise ArgumentError
end
u
end,
'http://www.w3.org/2001/XMLSchema#boolean' => lambda do |value, constraints|
Expand Down
103 changes: 54 additions & 49 deletions spec/field_spec.rb
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
require 'spec_helper'

describe Csvlint::Field do

it "should validate required fields" do
field = Csvlint::Field.new("test", { "required" => true } )
expect( field.validate_column( nil ) ).to be(false)
expect( field.validate_column( nil ) ).to be(false)
expect( field.errors.first.category ).to be(:schema)
expect( field.validate_column( "" ) ).to be(false)
expect( field.validate_column( "data" ) ).to be(true)
end

it "should include the failed constraints" do
field = Csvlint::Field.new("test", { "required" => true } )
expect( field.validate_column( nil ) ).to be(false)
expect( field.validate_column( nil ) ).to be(false)
expect( field.errors.first.constraints ).to eql( { "required" => true } )
end

it "should validate minimum length" do
field = Csvlint::Field.new("test", { "minLength" => 3 } )
expect( field.validate_column( nil ) ).to be(false)
expect( field.validate_column( "" ) ).to be(false)
expect( field.validate_column( "" ) ).to be(false)
expect( field.validate_column( "ab" ) ).to be(false)
expect( field.validate_column( "abc" ) ).to be(true)
expect( field.validate_column( "abcd" ) ).to be(true)
expect( field.validate_column( "abcd" ) ).to be(true)
end

it "should validate maximum length" do
field = Csvlint::Field.new("test", { "maxLength" => 3 } )
expect( field.validate_column( nil ) ).to be(true)
expect( field.validate_column( "" ) ).to be(true)
expect( field.validate_column( "" ) ).to be(true)
expect( field.validate_column( "ab" ) ).to be(true)
expect( field.validate_column( "abc" ) ).to be(true)
expect( field.validate_column( "abcd" ) ).to be(false)
end

it "should validate against regex" do
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}\}"} )
expect( field.validate_column( "abc") ).to be(false)
expect( field.validate_column( "{3B0DA29C-C89A-4FAA-918A-0000074FA0E0}") ).to be(true)
expect( field.validate_column( "{3B0DA29C-C89A-4FAA-918A-0000074FA0E0}") ).to be(true)
end

it "should apply combinations of constraints" do
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}\}"} )
expect( field.validate_column( "abc") ).to be(false)
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}\}" } )

expect( field.validate_column( nil ) ).to be(false)
expect( field.errors.first.constraints ).to eql( { "required"=>true } )
expect( field.validate_column( "{3B0DA29C-C89A-4FAA-918A-0000074FA0E0}") ).to be(true)

expect( field.validate_column( "{3B0DA29C-C89A-4FAA-918A-0000074FA0E0}") ).to be(true)

end

it "should enforce uniqueness for a column" do
Expand All @@ -65,13 +65,13 @@
field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#int" })
expect( field.validate_column("")).to be(true)
end

it "validates strings" do
field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#string" })
expect( field.validate_column("42")).to be(true)
expect( field.validate_column("forty-two")).to be(true)
end

it "validates ints" do
field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#int" })
expect( field.validate_column("42")).to be(true)
Expand All @@ -82,7 +82,7 @@
field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#integer" })
expect( field.validate_column("42")).to be(true)
expect( field.validate_column("forty-two")).to be(false)
end
end

it "validates floats" do
field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#float" })
Expand All @@ -98,6 +98,11 @@
expect(field.validate_column("42.0")).to be(false)
end

it "works with invalid URIs" do
field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#anyURI" })
expect(field.validate_column("£123")).to be(false)
end

it "validates booleans" do
field = Csvlint::Field.new("test", { "type" => "http://www.w3.org/2001/XMLSchema#boolean" })
expect(field.validate_column("true")).to be(true)
Expand Down Expand Up @@ -137,111 +142,111 @@
expect(field.validate_column("1")).to be(true)
end
end

context "when validating ranges" do

it "should enforce minimum values" do
field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#int",
"minimum" => "40"
})
expect( field.validate_column("42")).to be(true)

field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#int",
"minimum" => "40"
})
expect( field.validate_column("39")).to be(false)
expect( field.validate_column("39")).to be(false)
expect( field.errors.first.type ).to eql(:below_minimum)
end

it "should enforce maximum values" do
field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#int",
"maximum" => "40"
})
expect( field.validate_column("39")).to be(true)

field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#int",
"maximum" => "40"
})
expect( field.validate_column("41")).to be(false)
expect( field.validate_column("41")).to be(false)
expect( field.errors.first.type ).to eql(:above_maximum)

end
end
end

context "when validating dates" do
it "should validate a date time" do
field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#dateTime"
})
expect( field.validate_column("2014-02-17T11:09:00Z")).to be(true)
expect( field.validate_column("invalid-date")).to be(false)
expect( field.validate_column("2014-02-17")).to be(false)
expect( field.validate_column("2014-02-17")).to be(false)
end
it "should validate a date" do
field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#date"
})
expect( field.validate_column("2014-02-17T11:09:00Z")).to be(false)
expect( field.validate_column("invalid-date")).to be(false)
expect( field.validate_column("2014-02-17")).to be(true)
expect( field.validate_column("2014-02-17")).to be(true)
end
it "should validate a time" do
field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#time"
})
expect( field.validate_column("11:09:00")).to be(true)
expect( field.validate_column("2014-02-17T11:09:00Z")).to be(false)
expect( field.validate_column("not-a-time")).to be(false)
expect( field.validate_column("27:97:00")).to be(false)
expect( field.validate_column("not-a-time")).to be(false)
expect( field.validate_column("27:97:00")).to be(false)
end
it "should validate a year" do
field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#gYear"
})
expect( field.validate_column("1999")).to be(true)
expect( field.validate_column("2525")).to be(true)
expect( field.validate_column("0001")).to be(true)
expect( field.validate_column("2014-02-17T11:09:00Z")).to be(false)
expect( field.validate_column("not-a-time")).to be(false)
expect( field.validate_column("27:97:00")).to be(false)
expect( field.validate_column("not-a-time")).to be(false)
expect( field.validate_column("27:97:00")).to be(false)
end
it "should validate a year-month" do
field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#gYearMonth"
})
expect( field.validate_column("1999-12")).to be(true)
expect( field.validate_column("2525-01")).to be(true)
expect( field.validate_column("2014-02-17T11:09:00Z")).to be(false)
expect( field.validate_column("not-a-time")).to be(false)
expect( field.validate_column("27:97:00")).to be(false)
expect( field.validate_column("not-a-time")).to be(false)
expect( field.validate_column("27:97:00")).to be(false)
end
it "should allow user to specify custom date time pattern" do
field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#dateTime",
"datePattern" => "%Y-%m-%d %H:%M:%S"
})
expect( field.validate_column("1999-12-01 10:00:00")).to be(true)
expect( field.validate_column("invalid-date")).to be(false)
expect( field.validate_column("2014-02-17")).to be(false)
expect( field.errors.first.constraints ).to eql( {
expect( field.validate_column("2014-02-17")).to be(false)
expect( field.errors.first.constraints ).to eql( {
"type" => "http://www.w3.org/2001/XMLSchema#dateTime",
"datePattern" => "%Y-%m-%d %H:%M:%S"
})

end
it "should allow user to compare dates" do
field = Csvlint::Field.new("test", {
field = Csvlint::Field.new("test", {
"type" => "http://www.w3.org/2001/XMLSchema#dateTime",
"datePattern" => "%Y-%m-%d %H:%M:%S",
"minimum" => "1990-01-01 10:00:00"
})
expect( field.validate_column("1999-12-01 10:00:00")).to be(true)
expect( field.validate_column("1989-12-01 10:00:00")).to be(false)
expect( field.validate_column("1989-12-01 10:00:00")).to be(false)
end
end
end
end
end

0 comments on commit 85b819c

Please sign in to comment.