swagger-tools
Advanced tools
Comparing version 0.1.5 to 0.1.6
107
index.js
@@ -280,2 +280,6 @@ /* | ||
if (!api.operations || !_.isArray(api.operations)) { | ||
return; | ||
} | ||
_.each(api.operations, function (operation, index) { | ||
@@ -438,5 +442,88 @@ var operationPath = apiPath + '.operations[' + index + ']'; | ||
// TODO: Validate discriminitor property exists | ||
// TODO: Validate required properties exist | ||
return { | ||
errors: errors, | ||
warnings: warnings | ||
}; | ||
}; | ||
var validateOperations = function validateOperations (spec, resource) { | ||
var errors = []; | ||
var warnings = []; | ||
switch (spec.version) { | ||
case '1.2': | ||
if (resource.apis && _.isArray(resource.apis)) { | ||
_.each(resource.apis, function (api, index) { | ||
var apiPath = '$.apis[' + index + ']'; | ||
var seenMethods = []; | ||
var seenNicknames = []; | ||
if (!api.operations || !_.isArray(api.operations)) { | ||
return; | ||
} | ||
_.each(api.operations, function (operation, index) { | ||
var operationPath = apiPath + '.operations[' + index + ']'; | ||
var seenResponseMessageCodes = []; | ||
// Identify duplicate operation methods | ||
if (operation.method) { | ||
if (seenMethods.indexOf(operation.method) > -1) { | ||
errors.push({ | ||
code: 'DUPLICATE_OPERATION_METHOD', | ||
message: 'Operation method already defined: ' + operation.method, | ||
data: operation.method, | ||
path: operationPath + '.method' | ||
}); | ||
} else { | ||
seenMethods.push(operation.method); | ||
} | ||
} | ||
// Identify duplicate operation nicknames | ||
if (operation.nickname) { | ||
if (seenNicknames.indexOf(operation.nickname) > -1) { | ||
errors.push({ | ||
code: 'DUPLICATE_OPERATION_NICKNAME', | ||
message: 'Operation method already defined: ' + operation.nickname, | ||
data: operation.nickname, | ||
path: operationPath + '.nickname' | ||
}); | ||
} else { | ||
seenNicknames.push(operation.nickname); | ||
} | ||
} | ||
// Identify duplicate operation responseMessage codes | ||
if (operation.responseMessages && _.isArray(operation.responseMessages)) { | ||
_.each(operation.responseMessages, function (responseMessage, index) { | ||
if (responseMessage.code) { | ||
if (seenResponseMessageCodes.indexOf(responseMessage.code) > -1) { | ||
errors.push({ | ||
code: 'DUPLICATE_OPERATION_RESPONSEMESSAGE_CODE', | ||
message: 'Operation responseMessage code already defined: ' + responseMessage.code, | ||
data: responseMessage.code, | ||
path: operationPath + '.responseMessages[' + index + '].code' | ||
}); | ||
} else { | ||
seenResponseMessageCodes.push(responseMessage.code); | ||
} | ||
} | ||
}); | ||
} | ||
// Identify operation summary greater than 120 characters | ||
if (operation.summary && _.isString(operation.summary) && operation.summary.length > 120) { | ||
warnings.push({ | ||
code: 'OPERATION_SUMMARY_LONG', | ||
message: 'Operation summary is greater than 120 characters: ' + operation.summary.length, | ||
data: operation.summary, | ||
path: operationPath + '.summary' | ||
}); | ||
} | ||
}); | ||
}); | ||
} | ||
} | ||
return { | ||
@@ -495,11 +582,13 @@ errors: errors, | ||
case 'apiDeclaration.json': | ||
result = validateModels(this, data); | ||
[validateModels, validateOperations].forEach(function (func) { | ||
result = func(this, data); | ||
if (result.errors && _.isArray(result.errors)) { | ||
errors = errors.concat(result.errors); | ||
} | ||
if (result.errors && _.isArray(result.errors)) { | ||
errors = errors.concat(result.errors); | ||
} | ||
if (result.warnings && _.isArray(result.warnings)) { | ||
warnings = warnings.concat(result.warnings); | ||
} | ||
if (result.warnings && _.isArray(result.warnings)) { | ||
warnings = warnings.concat(result.warnings); | ||
} | ||
}.bind(this)); | ||
@@ -506,0 +595,0 @@ break; |
{ | ||
"name": "swagger-tools", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"description": "Various tools for using and integrating with Swagger.", | ||
@@ -33,3 +33,3 @@ "main": "index.js", | ||
"devDependencies": { | ||
"gulp": "^3.8.0", | ||
"gulp": "^3.8.5", | ||
"gulp-jshint": "^1.6.2", | ||
@@ -36,0 +36,0 @@ "gulp-mocha": "^0.4.1", |
@@ -45,2 +45,3 @@ /* global describe, it */ | ||
var invalidModelInheritanceJson = require('./v1_2-invalid-model-inheritance.json'); | ||
var invalidOperationMiscJson = require('./v1_2-invalid-operation-misc.json'); | ||
@@ -286,3 +287,3 @@ // Load the sample files from disk | ||
it('should return errors for model subTypes redeclaring ancestor properties apiDeclaration files', function () { | ||
it('should return errors for model subTypes redeclaring ancestor properties in apiDeclaration files', function () { | ||
var errors = []; | ||
@@ -306,3 +307,3 @@ | ||
it('should return warning for model subTypes with duplicate entries apiDeclaration files', function () { | ||
it('should return warning for model subTypes with duplicate entries in apiDeclaration files', function () { | ||
var warnings = []; | ||
@@ -326,3 +327,3 @@ | ||
it('should return errors for model with invalid discriminator apiDeclaration files', function () { | ||
it('should return errors for model with invalid discriminator in apiDeclaration files', function () { | ||
var errors = []; | ||
@@ -338,6 +339,6 @@ | ||
{ | ||
'code': 'INVALID_MODEL_DISCRIMINATOR', | ||
'message': 'Model cannot have discriminator without subTypes: aId', | ||
'data': 'aId', | ||
'path': '$.models[\'A\'].discriminator' | ||
code: 'INVALID_MODEL_DISCRIMINATOR', | ||
message: 'Model cannot have discriminator without subTypes: aId', | ||
data: 'aId', | ||
path: '$.models[\'A\'].discriminator' | ||
} | ||
@@ -347,3 +348,3 @@ ]); | ||
it('should return errors for model with missing required property apiDeclaration files', function () { | ||
it('should return errors for model with missing required property in apiDeclaration files', function () { | ||
var errors = []; | ||
@@ -366,3 +367,83 @@ | ||
}); | ||
it('should return warning for operations with duplicate method apiDeclaration files', function () { | ||
var errors = []; | ||
spec.validate(invalidOperationMiscJson).errors.forEach(function (error) { | ||
if (error.code === 'DUPLICATE_OPERATION_METHOD') { | ||
errors.push(error); | ||
} | ||
}); | ||
assert.deepEqual(errors, [ | ||
{ | ||
code: 'DUPLICATE_OPERATION_METHOD', | ||
message: 'Operation method already defined: GET', | ||
data: 'GET', | ||
path: '$.apis[0].operations[1].method' | ||
} | ||
]); | ||
}); | ||
it('should return warning for operations with duplicate nickname apiDeclaration files', function () { | ||
var errors = []; | ||
spec.validate(invalidOperationMiscJson).errors.forEach(function (error) { | ||
if (error.code === 'DUPLICATE_OPERATION_NICKNAME') { | ||
errors.push(error); | ||
} | ||
}); | ||
assert.deepEqual(errors, [ | ||
{ | ||
code: 'DUPLICATE_OPERATION_NICKNAME', | ||
message: 'Operation method already defined: getGreeting', | ||
data: 'getGreeting', | ||
path: '$.apis[0].operations[1].nickname' | ||
} | ||
]); | ||
}); | ||
it('should return warning for operations with responseMessage codes nickname apiDeclaration files', function () { | ||
var errors = []; | ||
spec.validate(invalidOperationMiscJson).errors.forEach(function (error) { | ||
if (error.code === 'DUPLICATE_OPERATION_RESPONSEMESSAGE_CODE') { | ||
errors.push(error); | ||
} | ||
}); | ||
assert.deepEqual(errors, [ | ||
{ | ||
code: 'DUPLICATE_OPERATION_RESPONSEMESSAGE_CODE', | ||
message: 'Operation responseMessage code already defined: 400', | ||
data: 400, | ||
path: '$.apis[0].operations[0].responseMessages[1].code' | ||
} | ||
]); | ||
}); | ||
it('should return warning for operation with 121+ character summary length in apiDeclaration files', function () { | ||
var json = _.cloneDeep(invalidOperationMiscJson); | ||
var summary = new Array(122).join('.'); | ||
var warnings = []; | ||
json.apis[0].operations[1].summary = summary; | ||
spec.validate(json).warnings.forEach(function (warning) { | ||
if (warning.code === 'OPERATION_SUMMARY_LONG') { | ||
warnings.push(warning); | ||
} | ||
}); | ||
assert.deepEqual(warnings, [ | ||
{ | ||
code: 'OPERATION_SUMMARY_LONG', | ||
message: 'Operation summary is greater than 120 characters: 121', | ||
data: summary, | ||
path: '$.apis[0].operations[1].summary' | ||
} | ||
]); | ||
}); | ||
}); | ||
}); |
101755
28
2838