Skip to content

Commit

Permalink
differentiating between validation errors and validation warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
dharmamike committed Apr 9, 2015
1 parent 9f707f4 commit e2993c6
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 3 deletions.
1 change: 1 addition & 0 deletions app.rb
Expand Up @@ -8,6 +8,7 @@
# Require base
require 'sinatra/base'

require 'app/errors'
require 'app/models'
require 'app/routes'

Expand Down
8 changes: 8 additions & 0 deletions app/errors.rb
@@ -0,0 +1,8 @@
module Lorry
module Errors

class ComposeValidationWarning < Kwalify::ValidationError
end

end
end
10 changes: 8 additions & 2 deletions app/models/validation.rb
Expand Up @@ -4,15 +4,21 @@ class Validation

def initialize(document)
validator = ComposeValidator.new
validator.services = YAML.load(document).keys
if yaml = YAML.load(document)
validator.services = yaml.keys if yaml.respond_to?(:keys)
end
@parser = Kwalify::Yaml::Parser.new(validator)
@parser.parse(document) if document
rescue Kwalify::SyntaxError => e
raise ArgumentError.new(e.message)
end

def errors
@parser.errors unless Array(@parser.errors).empty?
@parser.errors.map { |err| err if err.instance_of? Kwalify::ValidationError }.compact
end

def warnings
@parser.errors.map { |err| err if err.instance_of? Lorry::Errors::ComposeValidationWarning }.compact
end
end
end
Expand Down
13 changes: 12 additions & 1 deletion app/routes/validation.rb
Expand Up @@ -17,7 +17,12 @@ class Validation < Base
post do
@document = @payload[:document]
@validation = Lorry::Models::Validation.new(@document)
json(lines: document_lines, status: validation_status, errors: validation_errors)
json(
lines: document_lines,
status: validation_status,
errors: validation_errors,
warnings: validation_warnings
)
end
end

Expand All @@ -34,6 +39,12 @@ def validation_errors
end
end

def validation_warnings
Array(@validation.warnings).map do |w|
{ warning: { message: w.message, line: w.linenum, column: w.column } }
end
end

def validation_status
@validation.errors ? 'invalid' : 'valid'
end
Expand Down
54 changes: 54 additions & 0 deletions spec/models/validation_spec.rb
@@ -0,0 +1,54 @@
require 'spec_helper'

describe Validation do
let(:parser_with_errors) do
double('parser',
parse: true,
errors: [Kwalify::ValidationError.new('error'),
Lorry::Errors::ComposeValidationWarning.new('warning')])
end
let(:parser_without_errors) { double('parser', errors: [], warnings: []) }
let(:validator) { double('validator') }

before do
allow(ComposeValidator).to receive(:new).and_return(validator)
allow(validator).to receive(:services=).and_return(true)
allow(YAML).to receive(:load).and_return(double(keys:[]))
end

describe '#errors' do
context('when the document has errors') do
before do
allow(Kwalify::Yaml::Parser).to receive(:new).and_return(parser_with_errors)
end

subject { Lorry::Models::Validation.new(nil) }

it('returns an array') do
expect(subject.errors).to be_an(Array)
end

it('returns an array with only Kwalify::ValidationError instances') do
expect(subject.errors).to all(be_an_instance_of Kwalify::ValidationError)
end
end
end

describe '#warnings' do
context('when the document has warnings') do
before do
allow(Kwalify::Yaml::Parser).to receive(:new).and_return(parser_with_errors)
end

subject { Lorry::Models::Validation.new(nil) }

it('returns an array') do
expect(subject.warnings).to be_an(Array)
end

it('returns an array with only Kwalify::ValidationError instances') do
expect(subject.warnings).to all(be_an_instance_of Lorry::Errors::ComposeValidationWarning)
end
end
end
end
70 changes: 70 additions & 0 deletions spec/routes/validations_spec.rb
@@ -0,0 +1,70 @@
require 'spec_helper'

describe Lorry::Routes::Validation do

describe 'OPTIONS /validation' do
it 'returns a response with status code 200' do
response = options '/validation'
expect(response.status).to be 200
end
end

describe 'POST validations' do

let(:request_body) { { document: "" }.to_json }

it 'returns a response with status code 200' do
response = post '/validation', request_body
expect(response.status).to eq 200
end

it 'returns a JSON object with an array of lines' do
response = post '/validation', request_body
expect(JSON.parse(response.body)['lines']).to eq []
end

it 'returns a JSON object with a status indicator' do
response = post '/validation', request_body
expect(JSON.parse(response.body)['status']).to eq 'invalid'
end

it 'returns a JSON object with an array of errors' do
response = post '/validation', request_body
expect(JSON.parse(response.body)['errors']).to eq []
end

it 'returns a JSON object with an array of warnings' do
response = post '/validation', request_body
expect(JSON.parse(response.body)['warnings']).to eq []
end

context('when the validation returns errors') do
let(:request_body) { { document: "foo" }.to_json }

it 'the errors array contains an error object with message, line, and column attributes' do
response = post '/validation', request_body
errors = JSON.parse(response.body)['errors']
expect(errors.first['error'].keys).to match_array(%w(message line column))
end
end

context('when the validation returns warnings') do
let(:warnings) do
[Lorry::Errors::ComposeValidationWarning.new('warning')]
end
let(:validation) { double('validation', warnings: warnings, errors: nil) }
let(:request_body) { { document: "" }.to_json }

before do
allow(Lorry::Models::Validation).to receive(:new).and_return(validation)
end

it 'the warnings array contains a warning object with message, line, and column attributes' do
response = post '/validation', request_body
errors = JSON.parse(response.body)['warnings']
expect(errors.first['warning'].keys).to match_array(%w(message line column))
end
end
end

end

0 comments on commit e2993c6

Please sign in to comment.