Skip to content

Commit

Permalink
Merge pull request #19 from apiaryio/gavel-7-update
Browse files Browse the repository at this point in the history
Uses the latest Gavel API
  • Loading branch information
artem-zakharchenko authored Jul 24, 2019
2 parents e7876dd + 468ac0c commit a68b9f1
Show file tree
Hide file tree
Showing 12 changed files with 553 additions and 1,155 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,19 @@ npm install gavel2html
## Usage

```javascript
Gavel2Html = require('gavel2html');
const gavel = require('gavel');
const Gavel2Html = require('gavel2html');

// Perform Gavel validation
const gavelResult = gavel(expected, actual);

const gavel2html = new Gavel2Html({
// Pass the name of the field you wish to render
fieldName: 'body',
// ...and the validation result chunk for that field
fieldResult: gavelResult.fields.body,

// ...not sure values are even needed
dataReal: '{"name": "hell"}',
dataExpected: '{"name": "hello"}',
});
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gavel2html",
"version": "1.0.2",
"version": "2.0.0",
"description": "Convert output from Gavel to HTML",
"main": "lib/index.js",
"scripts": {
Expand Down
54 changes: 10 additions & 44 deletions src/converter.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ escapeBasicHtml = (val) ->


class Converter
constructor: ({@dataReal, @dataExpected, @gavelResult, @usePointers}) ->
constructor: ({@dataReal, @dataExpected, @fieldResult, @usePointers}) ->
@usedErrors = []

getHtml: (options = {}) ->
Expand Down Expand Up @@ -118,72 +118,38 @@ class Converter
compiledPointersKey = 'lowercased'
return [transformKeysFn, compiledPointersKey]

#@private
# aggregate all errors for given path and mark them with state missing, added, changed etc..
getStateAndMessageFromAmandaResult: ({pathArray, lowerCasedKeys}) ->
resultsCount = @gavelResult?.rawData?.length or 0
state = 0
message = ''

if resultsCount
[transformKeysFn, compiledPointersKey] = @getPointerTransformKeys lowerCasedKeys
@buildDataRealPointers {transformKeysFn, compiledPointersKey}

pathArrayTransformed = pathArray.map transformKeysFn

for i in [0..resultsCount-1]
if @areArraysIdentical pathArrayTransformed, @gavelResult.rawData[i]?['property'] or []
errorPointer = jsonPointer.compile(@gavelResult.rawData[i]?['property'] or [])
# key is missing in real and is present in expected, so it's missing
if errorPointer not in @dataRealPointers[compiledPointersKey]
if message
message = ' | ' + message
message = @gavelResult.rawData[i]['message'] + message
state = -1

else

# key is present in both real and expected, so its changed (different value primitive type probably)
if not state
state = 2
if message
message += " | "
message += @gavelResult.rawData[i]['message']

return {pathArray: pathArray, 'state': state, 'message': message}

#@private
# aggregate all errors for given path and mark them with state missing, added, changed etc..
getStateAndMessageFromResults: ({pathArray, lowerCasedKeys}) ->
resultsCount = @gavelResult?.results?.length
errorsCount = @fieldResult?.errors?.length
state = 0
message = ''

if resultsCount
if errorsCount
[transformKeysFn, compiledPointersKey] = @getPointerTransformKeys lowerCasedKeys
@buildDataRealPointers {transformKeysFn, compiledPointersKey}

pathArrayTransformed = pathArray.map(transformKeysFn)

for result in @gavelResult.results
if result['pointer']? # filter out non json related errors
if @areArraysIdentical pathArrayTransformed, jsonPointer.parse(result['pointer'])
errorPointer = result['pointer']
for error in @fieldResult.errors
errorPointer = error.location?.pointer

if errorPointer? # filter out non json related errors
if @areArraysIdentical pathArrayTransformed, jsonPointer.parse(errorPointer)
# key is missing in real and is present in expected, so it's missing
if errorPointer not in @dataRealPointers[compiledPointersKey]
if message
message = ' | ' + message
message = result['message'] + message
message = error['message'] + message
state = -1

else

# key is present in both real and expected, so its changed (different value primitive typeprobably)
if not state
state = 2
if message
message += " | "
message += result['message']
message += error['message']

return {pathArray: pathArray, 'state': state, 'message': message}

Expand Down
37 changes: 19 additions & 18 deletions src/gavel2html.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ transformJsonData = (real, expected) ->
return {real: realTransformed, expected: expectedTransformed}

class Gavel2Html
constructor: ({dataReal, dataExpected, gavelResult, usePointers}) ->
@dataReal = dataReal
@dataExpected = dataExpected
@gavelResult = gavelResult
constructor: ({ fieldName, fieldResult, usePointers }) ->
@fieldName = fieldName
# Real and expected data are stored only to preserve
# previously existing references. Remove this and use "fieldResult"
# referenced directly when refactoring.
@dataReal = fieldResult.values.actual
@dataExpected = fieldResult.values.expected
@fieldResult = fieldResult
@usePointers = usePointers
@usedErrors = []


getHtml: (givenOptions = {}) ->
{
wrapWith
Expand Down Expand Up @@ -60,6 +63,7 @@ class Gavel2Html
@usedErrors = converter.usedErrors
return result
catch e
console.error('gavelhtml: Internal error.\n', e)
html = missingStartTag + "Internal validator error\n\n" + endTag
try
if typeof(@dataReal) != 'string'
Expand All @@ -77,26 +81,23 @@ class Gavel2Html
#@private
getConverter: ->
options = {
@fieldName
@dataReal
@dataExpected
@gavelResult
@fieldResult
@usePointers
}

switch @gavelResult?.validator
when 'TextDiff'
return new TextResultConverter options
if @fieldResult?.kind == 'json'
if @fieldName == 'headers'
return new HeadersResultConverter options

when 'JsonSchema', 'JsonExample'
transformedData = transformJsonData(options.dataReal, options.dataExpected)
if transformedData
options.dataReal = transformedData.real
options.dataExpected = transformedData.expected
return new JsonResultConverter options
return new TextResultConverter options
transformedData = transformJsonData(options.dataReal, options.dataExpected)

when 'HeadersJsonSchema', 'HeadersJsonExample'
return new HeadersResultConverter options
if transformedData
options.dataReal = transformedData.real
options.dataExpected = transformedData.expected
return new JsonResultConverter options

return new TextResultConverter options

Expand Down
9 changes: 1 addition & 8 deletions src/headers-result-converter.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,13 @@ clone = require 'clone'
Converter = require './converter'

class HeadersResultConverter extends Converter
#@protected
getLinesFromAmandaResults: ->
@_getLines()

#@protected
getLinesFromResults: ->
@_getLines()

#@private
_getLines: ->
if @usePointers
lineResultGetter = @getStateAndMessageFromResults
else
lineResultGetter = @getStateAndMessageFromAmandaResult
lineResultGetter = @getStateAndMessageFromResults

@dataReal = @getFromString @dataReal
@dataExpected = @getFromString @dataExpected
Expand Down
51 changes: 5 additions & 46 deletions src/json-result-converter.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ class JsonResultConverter extends Converter
prevLevel = 0
prevNode = null
errorsPaths = []
if @usePointers
errors = @getErrorsFromResults()
else
errors = @getErrors()
errors = @getErrorsFromResults()

closingBrackets = []
typesOnLevels = {}
Expand Down Expand Up @@ -185,47 +182,9 @@ class JsonResultConverter extends Converter

return ''

#@private
getErrors: ()->
if not (@gavelResult.rawData and @gavelResult.rawData.length)
return [] # not sure about this, added keys will not be marked as addeds

amandaErrorsPaths = {}
errors = []
dataExpectedPointers = []

# get all pointers in expected data
traverse(@dataExpected).forEach (nodeValue) ->
dataExpectedPointers.push jsonPointer.compile this.path
return

# path from real does not exits in expected data so it's addded
traverse(@dataReal).forEach (nodeValue) ->
if not (jsonPointer.compile(this.path) in dataExpectedPointers)
errors.push {pathArray: this.path, value: nodeValue, 'state': 1, 'message': undefined}
return

# get unique paths in errors
for i in [0..@gavelResult.rawData.length - 1]

# get pointer from array and sanitize 'null' path array meant as root
if @gavelResult.rawData[i]['property']
pointer = jsonPointer.compile @gavelResult.rawData[i]['property']
else
pointer = ''

if not amandaErrorsPaths[pointer]
amandaErrorsPaths[pointer] = @gavelResult.rawData[i]['property'] or []

# get aggregated message and state for each error pointer/pathArray
for pointer, pathArray of amandaErrorsPaths
errors.push @getStateAndMessageFromAmandaResult pathArray: pathArray, lowerCasedKeys: false

return errors

#@private
getErrorsFromResults: () ->
if @gavelResult.results.length == 0
if @fieldResult.errors.length == 0
return [] # not sure about this, added keys will not be marked as added

errorsPaths = {}
Expand All @@ -244,9 +203,9 @@ class JsonResultConverter extends Converter
return

# get unique paths in errors
for result in @gavelResult.results
if result['pointer']? # filter out non JSON related errors
errorsPaths[result['pointer']] = jsonPointer.parse result['pointer']
for error in @fieldResult.errors
if error.location?.pointer? # drop non JSON related errors
errorsPaths[error.location.pointer] = jsonPointer.parse error.location.pointer

# get aggregated message and state for each error pointer/pathArray
for pointer, pathArray of errorsPaths
Expand Down
Loading

0 comments on commit a68b9f1

Please sign in to comment.