return function (theApi) {
        assert.ok(theApi instanceof types.SwaggerApi);
        assert.deepEqual(swaggerDoc, theApi.definition);
        assert.equal(implementation.documentation, theApi.documentation);
        assert.deepEqual(options, theApi.options);
        assert.equal(implementation.version, theApi.version);
        assert.deepEqual(resolvedRefs, theApi.references);
        assert.deepEqual(resolvedSwaggerDoc, theApi.resolved);

        // Validate the merging of the Swagger definition properties and the SwaggerApi properties
        _.forEach(swaggerDoc, function (val, key) {
          assert.deepEqual(val, theApi[key]);
        });

        // Validate the operations (Simple tests for now, deeper testing is below)
        assert.ok(_.isArray(theApi.operationObjects));
        assert.ok(theApi.operationObjects.length > 0);

        _.each(theApi.operationObjects, function (operation) {
          assert.ok(operation instanceof types.Operation);

          // Validate the parameters (Simple tests for now, deeper testing is below)
          _.each(operation.parameterObjects, function (parameter) {
            assert.ok(parameter instanceof types.Parameter);
          });
        });
      };
exports.getMockValue = function(version, schema) {
    if (version === '1.2' && !_.isUndefined(schema.defaultValue)) {
        return schema.defaultValue;
    } else if (version === '2.0' && !_.isUndefined(schema.default)) {
        return schema.default;
    } else if (_.isArray(schema.enum)) {
        var len = schema.enum.length;
        return schema.enum[Mock.Random.integer(0, len - 1)];
    }
}
function getMockValue (version, schema) {
    var type = _.isPlainObject(schema) ? schema.type : schema;
    var Random = Mock.Random;
    var value;
    if (!type) {
        type = 'object';
    }
    switch (type) {
        case 'array':
            value = [];
            var minimum = schema.minimum || DEFAULT_ARRAY_MIN;
            var maximum = schema.maximum || DEFAULT_ARRAY_MAX;
            var count = Random.integer(minimum, maximum);
            for (var i = 0; i < count; i++) {
                value.push(getMockValue(version, _.isArray(schema.items) ? schema.items[0] : schema.items));
            }
            break;
        case 'object':
            value = {};
            _.each(schema.allOf, function (parentSchema) {
                _.each(parentSchema.properties, function (property, propName) {
                    value[propName] = getMockValue(version, property);
                });
            });
            _.each(schema.properties, function (property, propName) {
                value[propName] = getMockValue(version, property);
            });
            break;
        default:
            var xformat = schema[X_FORMAT];
            var filepath = '';
            var argArr = [__dirname, type];
            if (xformat) {
                //尝试一次是否存在指定类型的特殊x-format类型数据
                argArr.push(xformat);
                filepath = path.join.apply(path, argArr);
                if (!fs.existsSync(filepath.trim() + '.js')) {
                    argArr.pop();
                }
            }
            filepath = path.join.apply(path, argArr);
            try {
                var PrimitiveParseModule = require(filepath);
                value = PrimitiveParseModule.getMockValue(version, schema);
                break;
            } catch (err) {
                throw err;
            }
    }
    return value;
};
module.exports = function (options) {

	var argv = ['node', 'cucumber-js'];
	var format = options.format || 'pretty';
	var tags = [];
	var files = [];
	var runOptions = ['-f', format];
	var stepRegex = options.stepRegex || '^($1)[^-_]';
	var stepRegexFlags = options.stepRegexFlags || 'gi';

	if (options.support) {
		files = files.concat(glob([].concat(options.support)));
	}

	if (options.steps) {
		files = files.concat(glob([].concat(options.steps)));
	}

	// Support tags in array or string format
	// @see https://github.com/cucumber/cucumber/wiki/Tags
	if (options.tags) {
		tags = ['--tags', options.tags];
		if (_.isArray(options.tags)) {
			if (options.requireAllTags) {
				tags = _(options.tags)
					.map(function (tag) {
						return ['--tags', tag]
					})
					.flatten()
					.value();
			} else {
				tags = ['--tags', options.tags.join(',')];
			}
		}
	}

	var parseAndRunTests = function(file, enc, callback) {
		var feature = path.parse(file.path);

		if (feature.ext !== '.feature') {
			return callback();
		}

		var index = _.findIndex(files, function (step) {
			var parsedStepPath = path.parse(step);
			// Match step name with feature name, stop searching when we hit - or _
			// after first part match. In case we are looking for ux-list and we
			// come across ux-list-item.
			var regex = new RegExp(stepRegex.replace('$1', feature.name), stepRegexFlags);
			return parsedStepPath.name.match(regex);
		});

		var matchingStep = files[index];
		var args = argv.concat(['-r', matchingStep, file.path], runOptions, tags);

		Cucumber.Cli(args).run(function(succeeded) {
			if (succeeded) {
				callback();
			} else {
				callback(new Error('Cucumber tests failed!'));
			}
		});
	};

	var finish = function (callback) {
		this.emit('end');
		return callback();
	};

	return through.obj(parseAndRunTests, finish);

};
Beispiel #5
0
var initializeMiddleware = function initializeMiddleware (rlOrSO, resources, callback) {
  var args;
  var spec;

  debug('Initializing middleware');

  if (_.isUndefined(rlOrSO)) {
    throw new Error('rlOrSO is required');
  } else if (!_.isPlainObject(rlOrSO)) {
    throw new TypeError('rlOrSO must be an object');
  }

  args = [rlOrSO];
  spec = helpers.getSpec(helpers.getSwaggerVersion(rlOrSO), true);

  debug('  Identified Swagger version: %s', spec.version);

  if (spec.version === '1.2') {
    if (_.isUndefined(resources)) {
      throw new Error('resources is required');
    } else if (!_.isArray(resources)) {
      throw new TypeError('resources must be an array');
    }

    debug('  Number of API Declarations: %d', resources.length);

    args.push(resources);
  } else {
    callback = arguments[1];
  }

  if (_.isUndefined(callback)) {
    throw new Error('callback is required');
  } else if (!_.isFunction(callback)) {
    throw new TypeError('callback must be a function');
  }

  args.push(function (err, results) {
    if (results && results.errors.length + _.reduce(results.apiDeclarations || [], function (count, apiDeclaration) {
      return count += (apiDeclaration ? apiDeclaration.errors.length : 0);
    }, 0) > 0) {
      err = new Error('Swagger document(s) failed validation so the server cannot start');

      err.results = results;
    }

    debug('  Validation: %s', err ? 'failed' : 'succeeded');

    if (err) {
      if (process.env.NODE_ENV === 'test') {
        throw err;
      } else {
        helpers.printValidationResults(spec.version, rlOrSO, resources, results, true);

        process.exit(helpers.getErrorCount(results) > 0 ? 1 : 0);
      }
    }

    callback({
      // Create a wrapper to avoid having to pass the non-optional arguments back to the swaggerMetadata middleware
      swaggerMetadata: function () {
        var swaggerMetadata = require('./middleware/swagger-metadata');

        return swaggerMetadata.apply(undefined, args.slice(0, args.length - 1));
      },
      swaggerRouter: require('./middleware/swagger-router'),
      swaggerSecurity: require('./middleware/swagger-security'),
      // Create a wrapper to avoid having to pass the non-optional arguments back to the swaggerUi middleware
      swaggerUi: function (options) {
        var swaggerUi = require('./middleware/swagger-ui');
        var suArgs = [rlOrSO];

        if (spec.version === '1.2') {
          suArgs.push(_.reduce(resources, function (map, resource) {
            map[resource.resourcePath] = resource;

            return map;
          }, {}));
        }

        suArgs.push(options || {});

        return swaggerUi.apply(undefined, suArgs);
      },
      swaggerValidator: require('./middleware/swagger-validator')
    });
  });

  spec.validate.apply(spec, args);
};
Beispiel #6
0
    value = _.map(value, function (item, index) {
      var iSchema = _.isArray(schema.items) ? schema.items[index] : schema.items;

      return convertValue(item, iSchema, iSchema ? iSchema.type : undefined);
    });
Beispiel #7
0
var convertValue = module.exports.convertValue = function (value, schema, type) {
  var original = value;

  // Default to {}
  if (_.isUndefined(schema)) {
    schema = {};
  }

  // Try to find the type or default to 'object'
  if (_.isUndefined(type)) {
    type = getParameterType(schema);
  }

  // If there is no value, do not convert it
  if (_.isUndefined(value)) {
    return value;
  }

  // If there is an empty value and allowEmptyValue is true, return it
  if (schema.allowEmptyValue && value === '') {
    return value;
  }

  switch (type) {
  case 'array':
    if (_.isString(value)) {
      switch (schema.collectionFormat) {
      case 'csv':
      case undefined:
        try {
          value = JSON.parse(value);
        } catch (err) {
          value = original;
        }

        if (_.isString(value)) {
          value = value.split(',');
        }
        break;
      case 'multi':
        value = [value];
        break;
      case 'pipes':
        value = value.split('|');
        break;
      case 'ssv':
        value = value.split(' ');
        break;
      case 'tsv':
        value = value.split('\t');
        break;
      }
    }

    // Handle situation where the expected type is array but only one value was provided
    if (!_.isArray(value)) {
      value = [value];
    }

    value = _.map(value, function (item, index) {
      var iSchema = _.isArray(schema.items) ? schema.items[index] : schema.items;

      return convertValue(item, iSchema, iSchema ? iSchema.type : undefined);
    });

    break;

  case 'boolean':
    if (!_.isBoolean(value)) {
      if (['false', 'true'].indexOf(value) === -1) {
        value = original;
      } else {
        value = value === 'true' || value === true ? true : false;
      }
    }

    break;

  case 'integer':
    if (!_.isNumber(value)) {
      if (_.isString(value) && _.trim(value).length === 0) {
        value = NaN;
      }

      value = Number(value);

      if (isNaN(value)) {
        value = original;
      }
    }

    break;

  case 'number':
    if (!_.isNumber(value)) {
      if (_.isString(value) && _.trim(value).length === 0) {
        value = NaN;
      }

      value = Number(value);

      if (isNaN(value)) {
        value = original;
      }
    }

    break;

  case 'object':
    if (_.isString(value)) {
      try {
        value = JSON.parse(value);
      } catch (err) {
        value = original;
      }
    }

    break;

  case 'string':
    try {
      value = JSON.parse(value);
    } catch (err) {
      value = original;
    }
    if (['date', 'date-time'].indexOf(schema.format) > -1 && !_.isDate(value)) {
      value = new Date(value);

      if (!_.isDate(value) || value.toString() === 'Invalid Date') {
        value = original;
      }
    }

    break;

  }

  return value;
};
 cacheEntry = apiCache[path] || _.find(apiCache, function (metadata) {
   match = metadata.re.exec(path);
   return _.isArray(match);
 });
exports = module.exports = function (rlOrSO, apiDeclarations) {
  debug('Initializing swagger-metadata middleware');

  var apiCache = processSwaggerDocuments(rlOrSO, apiDeclarations);
  var swaggerVersion = cHelpers.getSwaggerVersion(rlOrSO);

  if (_.isUndefined(rlOrSO)) {
    throw new Error('rlOrSO is required');
  } else if (!_.isPlainObject(rlOrSO)) {
    throw new TypeError('rlOrSO must be an object');
  }

  if (swaggerVersion === '1.2') {
    if (_.isUndefined(apiDeclarations)) {
      throw new Error('apiDeclarations is required');
    } else if (!_.isArray(apiDeclarations)) {
      throw new TypeError('apiDeclarations must be an array');
    }
  }

  return function swaggerMetadata (req, res, next) {
    var method = req.method.toLowerCase();
    var path = parseurl(req).pathname;
    var cacheEntry;
    var match;
    var metadata;

    cacheEntry = apiCache[path] || _.find(apiCache, function (metadata) {
      match = metadata.re.exec(path);
      return _.isArray(match);
    });

    debug('%s %s', req.method, req.url);
    debug('  Is a Swagger path: %s', !_.isUndefined(cacheEntry));

    // Request does not match an API defined in the Swagger document(s)
    if (!cacheEntry) {
      return next();
    }

    metadata = swaggerVersion === '1.2' ?
      {
        api: cacheEntry.api,
        apiDeclaration: cacheEntry.apiDeclaration,
        apiIndex: cacheEntry.apiIndex,
        params: {},
        resourceIndex: cacheEntry.resourceIndex,
        resourceListing: cacheEntry.resourceListing
      } :
    {
      apiPath : cacheEntry.apiPath,
      path: cacheEntry.path,
      params: {},
      swaggerObject: cacheEntry.swaggerObject.resolved
    };

    if (_.isPlainObject(cacheEntry.operations[method])) {
      metadata.operation = cacheEntry.operations[method].operation;
      metadata.operationPath = cacheEntry.operations[method].operationPath;

      if (swaggerVersion === '1.2') {
        metadata.authorizations = metadata.operation.authorizations || cacheEntry.apiDeclaration.authorizations;
      } else {
        metadata.operationParameters = cacheEntry.operations[method].operationParameters;
        metadata.security = metadata.operation.security || metadata.swaggerObject.security || [];
      }
    }

    metadata.swaggerVersion = swaggerVersion;

    req.swagger = metadata;

    debug('  Is a Swagger operation: %s', !_.isUndefined(metadata.operation));

    if (metadata.operation) {
      // Process the operation parameters
      return processOperationParameters(metadata, cacheEntry.keys, match, req, res, next, debug);
    } else {
      return next();
    }
  };
};
Beispiel #10
0
var processSwaggerDocuments = function (rlOrSO, apiDeclarations) {
  if (_.isUndefined(rlOrSO)) {
    throw new Error('rlOrSO is required');
  } else if (!_.isPlainObject(rlOrSO)) {
    throw new TypeError('rlOrSO must be an object');
  }

  var spec = cHelpers.getSpec(cHelpers.getSwaggerVersion(rlOrSO), true);
  var apiCache = {};
  var composeParameters = function (apiPath, method, path, operation) {
    var cParams = [];
    var seenParams = [];

    _.each(operation.parameters, function (parameter, index) {
      cParams.push({
        path: apiPath.concat([method, 'parameters', index.toString()]),
        schema: parameter
      });

      seenParams.push(parameter.name + ':' + parameter.in);
    });

    _.each(path.parameters, function (parameter, index) {
      if (seenParams.indexOf(parameter.name + ':' + parameter.in) === -1) {
        cParams.push({
          path: apiPath.concat(['parameters', index.toString()]),
          schema: parameter
        });
      }
    });

    return cParams;
  };
  var createCacheEntry = function (adOrSO, apiOrPath, indexOrName, indent) {
    var apiPath = spec.version === '1.2' ? apiOrPath.path : indexOrName;
    var expressPath = expressStylePath(adOrSO.basePath, spec.version === '1.2' ? apiOrPath.path: indexOrName);
    var keys = [];
    var handleSubPaths = !(rlOrSO.paths && rlOrSO.paths[apiPath]['x-swagger-router-handle-subpaths']);
    var re = pathToRegexp(expressPath, keys, { end: handleSubPaths });
    var cacheKey = re.toString();
    var cacheEntry;

    // This is an absolute path, use it as the cache key
    if (expressPath.indexOf('{') === -1) {
      cacheKey = expressPath;
    }

    debug(new Array(indent + 1).join(' ') + 'Found %s: %s',
          (spec.version === '1.2' ? 'API' : 'Path'),
          apiPath);

    cacheEntry = apiCache[cacheKey] = spec.version === '1.2' ?
      {
        api: apiOrPath,
        apiDeclaration: adOrSO,
        apiIndex: indexOrName,
        keys: keys,
        params: {},
        re: re,
        operations: {},
        resourceListing: rlOrSO
      } :
      {
        apiPath: indexOrName,
        path: apiOrPath,
        keys: keys,
        re: re,
        operations: {},
        swaggerObject: {
          original: rlOrSO,
          resolved: adOrSO
        }
      };

    return cacheEntry;
  };

  debug('  Identified Swagger version: %s', spec.version);

  if (spec.version === '1.2') {
    if (_.isUndefined(apiDeclarations)) {
      throw new Error('apiDeclarations is required');
    } else if (!_.isArray(apiDeclarations)) {
      throw new TypeError('apiDeclarations must be an array');
    }

    debug('  Number of API Declarations: %d', apiDeclarations.length);

    _.each(apiDeclarations, function (apiDeclaration, adIndex) {
      debug('  Processing API Declaration %d', adIndex);

      _.each(apiDeclaration.apis, function (api, apiIndex) {
        var cacheEntry = createCacheEntry(apiDeclaration, api, apiIndex, 4);

        cacheEntry.resourceIndex = adIndex;

        _.each(api.operations, function (operation, operationIndex) {
          cacheEntry.operations[operation.method.toLowerCase()] = {
            operation: operation,
            operationPath: ['apis', apiIndex.toString(), 'operations', operationIndex.toString()],
            operationParameters: operation.parameters
          };
        });
      });
    });
  } else {
    // To avoid running into issues with references throughout the Swagger object we will use the resolved version.
    // Getting the resolved version is an asynchronous process but since initializeMiddleware caches the resolved document
    // this is a synchronous action at this point.
    spec.resolve(rlOrSO, function (err, resolved) {
      // Gather the paths, their path regex patterns and the corresponding operations
      _.each(resolved.paths, function (path, pathName) {
        var cacheEntry = createCacheEntry(resolved, path, pathName, 2);

        _.each(['get', 'put', 'post', 'delete', 'options', 'head', 'patch'], function (method) {
          var operation = path[method];

          if (!_.isUndefined(operation)) {
            cacheEntry.operations[method] = {
              operation: operation,
              operationPath: ['paths', pathName, method],
              // Required since we have to compose parameters based on the operation and the path
              operationParameters: composeParameters(['paths', pathName], method, path, operation)
            };
          }
        });
      });
    });
  }

  return apiCache;
};
Beispiel #11
0
module.exports.getParameterValue = function (version, parameter, pathKeys, match, req, debug) {
  var defaultVal = version === '1.2' ? parameter.defaultValue : parameter.default;
  var paramLocation = version === '1.2' ? parameter.paramType : parameter.in;
  var paramType = getParameterType(parameter);
  var val;

  // Get the value to validate based on the operation parameter type
  switch (paramLocation) {
  case 'body':
    val = req.body;

    break;
  case 'form':
  case 'formData':
    if (paramType.toLowerCase() === 'file') {
      if (_.isArray(req.files)) {
        val = _.find(req.files, function (file) {
          return file.fieldname === parameter.name;
        });
      } else if (!_.isUndefined(req.files)) {
        val = req.files[parameter.name] ? req.files[parameter.name] : undefined;
      }

      // Swagger does not allow an array of files
      if (_.isArray(val)) {
        val = val[0];
      }
    } else if (isModelParameter(version, parameter)) {
      val = req.body;
    } else {
      val = req.body[parameter.name];
    }

    break;
  case 'header':
    val = req.headers[parameter.name.toLowerCase()];

    break;
  case 'path':
    _.each(pathKeys, function (key, index) {
      if (key.name === parameter.name) {
        val = decodeURIComponent(match[index + 1]);
      }
    });

    break;
  case 'query':
    val = _.get(req.query, parameter.name);

    break;
  }

  debug('      Value provided: %s', !_.isUndefined(val));

  // Use the default value when necessary
  if (_.isUndefined(val) && !_.isUndefined(defaultVal)) {
    val = defaultVal;
  }

  return val;
};
Beispiel #12
0
var initializeMiddleware = function initializeMiddleware (rlOrSO, resources, callback) {
  var args;
  var spec;

  debug('Initializing middleware');

  if (_.isUndefined(rlOrSO)) {
    throw new Error('rlOrSO is required');
  } else if (!_.isPlainObject(rlOrSO)) {
    throw new TypeError('rlOrSO must be an object');
  }

  args = [rlOrSO];
  spec = helpers.getSpec(helpers.getSwaggerVersion(rlOrSO), true);

  debug('  Identified Swagger version: %s', spec.version);

  if (spec.version === '1.2') {
    if (_.isUndefined(resources)) {
      throw new Error('resources is required');
    } else if (!_.isArray(resources)) {
      throw new TypeError('resources must be an array');
    }

    debug('  Number of API Declarations: %d', resources.length);

    args.push(resources);
  } else {
    callback = arguments[1];
  }

  if (_.isUndefined(callback)) {
    throw new Error('callback is required');
  } else if (!_.isFunction(callback)) {
    throw new TypeError('callback must be a function');
  }

  args.push(function (err, results) {
    if (results && results.errors.length + _.reduce(results.apiDeclarations || [], function (count, apiDeclaration) {
      return count += (apiDeclaration ? apiDeclaration.errors.length : 0);
    }, 0) > 0) {
      err = new Error('Swagger document(s) failed validation so the server cannot start');

      err.failedValidation = true;
      err.results = results;
    }

    debug('  Validation: %s', err ? 'failed' : 'succeeded');

    try {
      if (err) {
        throw err;
      }

      callback({
        // Create a wrapper to avoid having to pass the non-optional arguments back to the swaggerMetadata middleware
        swaggerMetadata: function () {
          var swaggerMetadata = require('./middleware/swagger-metadata');

          return swaggerMetadata.apply(undefined, args.slice(0, args.length - 1));
        },
        swaggerRouter: require('./middleware/swagger-router'),
        swaggerSecurity: require('./middleware/swagger-security'),
        // Create a wrapper to avoid having to pass the non-optional arguments back to the swaggerUi middleware
        swaggerUi: function (options) {
          var swaggerUi = require('./middleware/swagger-ui');
          var suArgs = [rlOrSO];

          if (spec.version === '1.2') {
            suArgs.push(_.reduce(resources, function (map, resource) {
              map[resource.resourcePath] = resource;

              return map;
            }, {}));
          }

          suArgs.push(options || {});

          return swaggerUi.apply(undefined, suArgs);
        },
        swaggerValidator: require('./middleware/swagger-validator')
      });
    } catch (err) {
      if (process.env.RUNNING_SWAGGER_TOOLS_TESTS === 'true') {
        // When running the swagger-tools test suite, we want to return an error instead of exiting the process.  This
        // does not mean that this function is an error-first callback but due to json-refs using Promises, we have to
        // return the error to avoid the error being swallowed.
        callback(err);
      } else {
        if (err.failedValidation === true) {
          helpers.printValidationResults(spec.version, rlOrSO, resources, results, true);
        } else {
          console.error('Error initializing middleware');
          console.error(err.stack);
        }

        process.exit(1);
      }
    }
  });

  spec.validate.apply(spec, args);
};