api-test
Advanced tools
Comparing version 2.6.0 to 2.7.0
47
check.js
@@ -30,5 +30,3 @@ 'use strict' | ||
} | ||
expected.forEach(function (each, i) { | ||
module.exports(actual[i], each, strict, [], path ? path + '.' + i : i) | ||
}) | ||
checkArray(actual, expected, expected.isOrdered, strict, ignoredKeys, path) | ||
} else if (expected && | ||
@@ -66,2 +64,45 @@ typeof expected === 'object' && | ||
} | ||
} | ||
/** | ||
* @param {Array} actual | ||
* @param {Array} expected | ||
* @param {boolean} isOrdered | ||
* @param {boolean} strict | ||
* @param {Array<string>} ignoredKeys | ||
* @param {string} path | ||
* @throws if invalid. The exception has a 'path' field with the path name that caused the error | ||
*/ | ||
function checkArray(actual, expected, isOrdered, strict, ignoredKeys, path) { | ||
if (isOrdered) { | ||
// Simple case: compare expected[i] with actual[i] | ||
expected.forEach(function (each, i) { | ||
module.exports(actual[i], each, strict, [], path ? path + '.' + i : i) | ||
}) | ||
return | ||
} | ||
var visited = actual.map(function () { | ||
return false | ||
}) | ||
expected.forEach(function (eachExpected) { | ||
var j | ||
for (j = 0; j < actual.length; j++) { | ||
if (visited[j]) { | ||
continue | ||
} | ||
try { | ||
module.exports(actual[j], eachExpected, strict, [], path ? path + '.' + j : j) | ||
visited[j] = true | ||
break | ||
} catch (e) { | ||
// Ignore these errors, we'll check next elements | ||
} | ||
} | ||
if (j === actual.length) { | ||
throw new Error('Unordered array mismatch') | ||
} | ||
}) | ||
} |
@@ -14,2 +14,3 @@ 'use strict' | ||
this.lines = [] | ||
/** | ||
@@ -24,4 +25,6 @@ * @member {Object} | ||
} | ||
/** @member {boolean} */ | ||
this.parsed = false | ||
/** @member {Object|Array|string|Mixin} */ | ||
@@ -71,5 +74,5 @@ this.value = null | ||
if (!(this._parseArray() || | ||
this._parseObject() || | ||
this._parseMixin() || | ||
this._parseJS())) { | ||
this._parseObject() || | ||
this._parseMixin() || | ||
this._parseJS())) { | ||
throw new ParseError('Invalid syntax', this) | ||
@@ -100,5 +103,7 @@ } | ||
if (Array.isArray(this.value)) { | ||
return this.value.map(function (each, i) { | ||
r = this.value.map(function (each, i) { | ||
return each.execute(context, name + '.' + i) | ||
}) | ||
r.isOrdered = this.value.isOrdered | ||
return r | ||
} else if (typeof this.value === 'string') { | ||
@@ -138,4 +143,4 @@ return _eval(this.value, context, name) | ||
if (!this.lines.length || this.lines[0][0] !== '*') { | ||
// An array must start with a '*' | ||
if (!this.lines.length || (this.lines[0][0] !== '*' && this.lines[0][0] !== '-')) { | ||
// An array must start with a '*' or '-' | ||
return false | ||
@@ -146,8 +151,9 @@ } | ||
this.value = [] | ||
this.value.isOrdered = true | ||
for (i = 0; i < this.lines.length; i++) { | ||
line = this.lines[i] | ||
if (line[0] === '*') { | ||
if (line[0] === '*' || line[0] === '-') { | ||
// A new element | ||
if (line[1] !== '\t') { | ||
throw new ParseError('Expected a "\\t" after "*"', this) | ||
throw new ParseError('Expected a "\\t" after "' + line[0] + '"', this) | ||
} | ||
@@ -159,2 +165,9 @@ if (obj) { | ||
obj.push(line.substr(2)) | ||
// Get ordering | ||
if (!i) { | ||
this.value.isOrdered = line[0] === '*' | ||
} else if (this.value.isOrdered !== (line[0] === '*')) { | ||
throw new ParseError('Either all elements start with "*" or "-"', this) | ||
} | ||
} else if (line[0] === '\t') { | ||
@@ -164,3 +177,3 @@ // Last obj continuation | ||
} else { | ||
throw new ParseError('Expected either a "*" or "\\t"', this) | ||
throw new ParseError('Expected either "*", "-" or "\\t"', this) | ||
} | ||
@@ -206,3 +219,3 @@ } | ||
save(key, obj) | ||
// 1 for path and simple key; 3 for escaped key | ||
// 1 for path and simple key; 3 for escaped key | ||
key = acceptPath ? match[1] : match[1] || match[3] | ||
@@ -209,0 +222,0 @@ obj = new Obj(this.source.begin + i) |
@@ -52,2 +52,10 @@ # Doc Syntax | ||
## Unordered arrays | ||
Act the same as an array in most cases, except matching does not considered the order of the elements. That is: | ||
set: | ||
- 3 | ||
- 14 | ||
- 15 | ||
matches `[15, 3, 14]`. | ||
## Arrays of arrays | ||
@@ -54,0 +62,0 @@ * * 1 |
{ | ||
"name": "api-test", | ||
"version": "2.6.0", | ||
"version": "2.7.0", | ||
"author": "Sitegui <sitegui@sitegui.com.br>", | ||
@@ -5,0 +5,0 @@ "description": "API testing made simple", |
@@ -95,3 +95,3 @@ /*globals describe, it*/ | ||
], { | ||
tags: ['light', 'pink'] | ||
tags: array(['light', 'pink'], true) | ||
}) | ||
@@ -103,5 +103,13 @@ | ||
'* 15' | ||
], [3, 14, 15]) | ||
], array([3, 14, 15], true)) | ||
}) | ||
it('should work for unordered arrays', function () { | ||
check([ | ||
'- 92', | ||
'- 65', | ||
'- 35' | ||
], array([92, 65, 35], false)) | ||
}) | ||
it('should work for more complex arrays', function () { | ||
@@ -115,3 +123,3 @@ check([ | ||
], { | ||
messages: [{ | ||
messages: array([{ | ||
group: 'family', | ||
@@ -122,11 +130,11 @@ num: 2 | ||
num: 12 | ||
}] | ||
}], true) | ||
}) | ||
check([ | ||
'* * 1', | ||
' * 2', | ||
'* - 1', | ||
' - 2', | ||
'* * 3', | ||
' * 4' | ||
], [[1, 2], [3, 4]]) | ||
], array([array([1, 2], false), array([3, 4], true)], true)) | ||
}) | ||
@@ -230,2 +238,11 @@ | ||
should(obj.execute(context, '<>')).be.eql(value) | ||
} | ||
/** | ||
* @param {Array} elements | ||
* @param {boolean} isOrdered | ||
*/ | ||
function array(elements, isOrdered) { | ||
elements.isOrdered = isOrdered | ||
return elements | ||
} |
69434
2027