Skip to content

Commit

Permalink
Merge pull request #54 from theodi/check-header-without-schema
Browse files Browse the repository at this point in the history
Check header without schema
  • Loading branch information
Floppy committed Feb 18, 2014
2 parents b41be27 + 918afbe commit 2db7728
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 38 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ The following types of error can be reported:
* `:whitespace` -- a quoted column has leading or trailing whitespace
* `:line_breaks` -- line breaks were inconsistent or incorrectly specified
* `:no_header` -- the CSV file doesn't include a header
* `:empty_column_name` -- a column in the CSV header has an empty name
* `:duplicate_column_name` -- a column in the CSV header has a duplicate name

## Warnings

Expand Down Expand Up @@ -190,8 +192,6 @@ Schema validation provides some additional types of error and warning messages:
* `:extra_column` (warning) -- a row in the CSV file has extra column.
* `:unique` (error) -- a column with a `unique` constraint contains non-unique values
* `:out_of_range` (error) -- a column with a `minimum` or `maximum` constraint contains a value that is outside of the range
* `:empty_column_name` (error) -- a column in the CSV header has an empty name
* `:duplicate_column_name` (error) -- a column in the CSV header has a duplicate name

## Contributing

Expand Down
10 changes: 2 additions & 8 deletions lib/csvlint/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,9 @@ def initialize(uri, fields=[])
end

def validate_header(header)
names = Set.new
reset
header.each_with_index do |name,i|
build_warnings(:header_name, :schema, nil, i+1) if fields[i].name.downcase != name.downcase
build_errors(:empty_column_name, :schema, nil, i+1) if name == ""
if names.include?(name)
build_errors(:duplicate_column_name, :schema, nil, i+1)
else
names << name
end
build_warnings(:header_name, :schema, nil, i+1) if fields[i].name != name
end
return valid?
end
Expand Down
25 changes: 19 additions & 6 deletions lib/csvlint/validate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,8 @@ def parse_csv(io)
row = csv.shift
wrapper.finished
if row
if header? && current_line == 1 #header
if @schema
@schema.validate_header(row)
@errors += @schema.errors
@warnings += @schema.warnings
end
if header? && current_line == 1
validate_header(row)
else

build_formats(row, current_line)
Expand Down Expand Up @@ -128,6 +124,23 @@ def parse_csv(io)
return expected_columns
end

def validate_header(header)
names = Set.new
header.each_with_index do |name,i|
build_errors(:empty_column_name, :schema, nil, i+1) if name == ""
if names.include?(name)
build_errors(:duplicate_column_name, :schema, nil, i+1)
else
names << name
end
end
if @schema
@schema.validate_header(header)
@errors += @schema.errors
@warnings += @schema.warnings
end
return valid?
end

def header?
return @csv_header
Expand Down
25 changes: 3 additions & 22 deletions spec/schema_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,30 +87,11 @@
expect( schema.warnings.size ).to eql(1)
expect( schema.warnings.first.type).to eql(:header_name)
expect( schema.warnings.first.category).to eql(:schema)
end

it "should error if column names aren't unique" do
minimum = Csvlint::Field.new("minimum", { "minLength" => 3 } )
required = Csvlint::Field.new("required", { "required" => true } )
schema = Csvlint::Schema.new("http://example.org", [minimum, required] )

expect( schema.validate_header(["minimum", "minimum"]) ).to eql(false)
expect( schema.errors.size ).to eql(1)
expect( schema.errors.first.type).to eql(:duplicate_column_name)
expect( schema.errors.first.category).to eql(:schema)
end
expect( schema.validate_header(["minimum", "Required"]) ).to eql(true)
expect( schema.warnings.size ).to eql(1)

it "should error if column names are blank" do
minimum = Csvlint::Field.new("minimum", { "minLength" => 3 } )
required = Csvlint::Field.new("required", { "required" => true } )
schema = Csvlint::Schema.new("http://example.org", [minimum, required] )

expect( schema.validate_header(["minimum", ""]) ).to eql(false)
expect( schema.errors.size ).to eql(1)
expect( schema.errors.first.type).to eql(:empty_column_name)
expect( schema.errors.first.category).to eql(:schema)
end

end
end

context "when parsing JSON Tables" do
Expand Down
22 changes: 22 additions & 0 deletions spec/validator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,28 @@

end

context "when validating headers" do
it "should error if column names aren't unique" do
data = StringIO.new( "minimum, minimum" )
validator = Csvlint::Validator.new(data)
expect( validator.validate_header(["minimum", "minimum"]) ).to eql(false)
expect( validator.errors.size ).to eql(1)
expect( validator.errors.first.type).to eql(:duplicate_column_name)
expect( validator.errors.first.category).to eql(:schema)
end

it "should error if column names are blank" do
data = StringIO.new( "minimum," )
validator = Csvlint::Validator.new(data)

expect( validator.validate_header(["minimum", ""]) ).to eql(false)
expect( validator.errors.size ).to eql(1)
expect( validator.errors.first.type).to eql(:empty_column_name)
expect( validator.errors.first.category).to eql(:schema)
end

end

context "build_formats" do

it "should return the format of each column correctly" do
Expand Down

0 comments on commit 2db7728

Please sign in to comment.