Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V1.x #29

Merged
merged 10 commits into from
Sep 13, 2016
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
language: node_js

node_js:
- "0.10"
- "4"
- "6"

script:
- "npm run-script cover"
- "npm run lint"
- "npm run cover"

sudo: false
74 changes: 24 additions & 50 deletions lib/generators/format.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,28 @@
'use strict';
var Moment = require('moment');
var Chance = require('chance').Chance();
var Randexp = require('randexp').randexp;
const Moment = require('moment');
const Chance = require('chance').Chance();
const Randexp = require('randexp').randexp;

const date = () => Moment().format('YYYY-MM-DD');
const dataTime = () => Moment().toISOString();
const url = () => Chance.url();
const email = () => Chance.email();
const phone = () => Chance.phone();
const guid = () => Chance.guid();
const ipv4 = () => Chance.ip();
const ipv6 = () => Chance.ipv6();
const hostname = () => Randexp(/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/gm);

module.exports = {
date: dateMock,
'date-time': dataTimeMock,
uri: urlMock,
url: urlMock,
email: emailMock,
phone: phoneMock,
uuid: guidMock,
guid: guidMock,
ipv4: ipv4,
ipv6: ipv6,
hostname: hostname
date,
'date-time': dataTime,
uri: url,
url,
email,
phone,
uuid: guid,
guid,
ipv4,
ipv6,
hostname
};

function dateMock() {
return Moment().format('YYYY-MM-DD');
}

function dataTimeMock() {
return Moment().toISOString();
}

function urlMock() {
return Chance.url();
}

function emailMock() {
return Chance.email();
}

function phoneMock() {
return Chance.phone();
}

function guidMock() {
return Chance.guid();
}

function ipv4() {
return Chance.ip();
}

function ipv6() {
return Chance.ipv6();
}

function hostname() {
return Randexp(/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/gm);
}
170 changes: 86 additions & 84 deletions lib/generators/index.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,28 @@
'use strict';
var Chance = require('chance').Chance();
var Format = require('./format');
var Util = require('../util');
var Randexp = require('randexp').randexp;
const Chance = require('chance').Chance();
const Format = require('./format');
const Randexp = require('randexp').randexp;

var Generators = module.exports = {
object: objectMock,
array: arrayMock,
string: stringMock,
integer: integerMock,
number: numberMock,
boolean: booleanMock,
file: fileMock,
mock: mock
};

function mock(schema) {
var mock;
const mock = schema => {
let mock;
if (schema) {
var type = schema.type || findType(schema);
let type = schema.type || findType(schema);
/**
* Get the mock generator from the `type` of the schema
*/
var generator = Generators[type];
const generator = Generators[type];
if (generator) {
mock = generator.call(null, schema);
}
}
return mock;
}

function objectMock(schema) {
var mockObj = {};
var props = schema.properties;
if (props) {
Object.keys(props).forEach(function (key) {
mockObj[key] = mock(props[key]);
};

const objectMock = ({ properties, additionalProperties }) => {
let mockObj = {};
if (properties) {
Object.keys(properties).forEach(function (key) {
mockObj[key] = mock(properties[key]);
});
/**
* In the absense of `properties`, check if `additionalProperties` is defined or not.
Expand All @@ -44,30 +31,29 @@ function objectMock(schema) {
*
* If present, use this to generate mocks.
*/
} else if (schema.additionalProperties) {
} else if (additionalProperties) {
//Create a random property
mockObj[Chance.word()] = mock(schema.additionalProperties);
mockObj[Chance.word()] = mock(additionalProperties);
}
return mockObj;
}
};
/**
* Generates a mock `array` data of `items`
* Supports: `minItems` and `maxItems`
* TODO: Implement `uniqueItems`
*/
function arrayMock(schema) {
var items = schema.items;
var min;
var max;
var numItems;
var arr = [];
const arrayMock = ({ items, minItems, maxItems }) => {
let min;
let max;
let numItems;
let arr = [];

if (items) {
//Use the min as the base
min = schema.minItems || 1;
if (schema.maxItems) {
min = minItems || 1;
if (maxItems) {
//If min is greater than max, use min as max.
max = (schema.maxItems < min) ? min : schema.maxItems;
max = (maxItems < min) ? min : maxItems;
} else {
//If max is not defined, use min as max.
max = min;
Expand All @@ -77,20 +63,20 @@ function arrayMock(schema) {
min: min,
max: max
});
for (var i = 0; i < numItems; i++) {
for (let i = 0; i < numItems; i++) {
arr.push(mock(items));
}
}
return arr;
}
};
/**
* Generates a mock `integer` value
* Supports `minimum`, `maximum`, `exclusiveMinimum` and `exclusiveMaximum`
* TODO - Validate `minimum` and `maximum` values
*/
function integerMock(schema) {
var opts = {};
var intmock;
const integerMock = schema => {
let opts = {};
let intmock;

/**
* If `enum` is defined for the property
Expand All @@ -99,34 +85,36 @@ function integerMock(schema) {
return enumMock(schema);
}

if (Util.isInteger(schema.minimum)) {
opts.min = (schema.exclusiveMinimum) ? schema.minimum : schema.minimum + 1;
if (Number.isInteger(schema.minimum)) {
opts.min = (schema.exclusiveMinimum) ? schema.minimum + 1 : schema.minimum;
}
if (Util.isInteger(schema.maximum)) {
opts.max = (schema.exclusiveMaximum) ? schema.maximum : schema.maximum - 1;
if (Number.isInteger(schema.maximum)) {
opts.max = (schema.exclusiveMaximum) ? schema.maximum - 1 : schema.maximum;
}
//Generate a number that is multiple of schema.multipleOf
if (Util.isInteger(schema.multipleOf) && schema.multipleOf > 0) {
//Use the muplilier as the min number
opts.min = schema.multipleOf;
if (Number.isInteger(schema.multipleOf) && schema.multipleOf > 0) {
//Use the min/muplilier as the min number
//Use default min as 1 if min is not properly set.
opts.min = (Number.isInteger(opts.min)) ? (Math.ceil(opts.min / schema.multipleOf)) : 1;
//Use the max/muplilier as the new max value
opts.max = (Util.isInteger(opts.max)) ? (Math.floor(opts.max/schema.multipleOf)) : opts.max;
//Use a default - min + 10 - if max value is not properly set.
opts.max = (Number.isInteger(opts.max)) ? (Math.floor(opts.max / schema.multipleOf)) : (opts.min + 10);
intmock = Chance.integer(opts);
intmock = intmock * schema.multipleOf;
} else {
intmock = Chance.integer(opts);
}
return intmock;
}
};

/**
* Generates a mock `number` value
* Supports `minimum`, `maximum`, `exclusiveMinimum` and `exclusiveMaximum`
* TODO - Validate `minimum` and `maximum` values
*/
function numberMock(schema) {
var opts = {};
var nummock;
const numberMock = schema => {
let opts = {};
let nummock;

/**
* If `enum` is defined for the property
Expand All @@ -135,45 +123,48 @@ function numberMock(schema) {
return enumMock(schema);
}

if (schema.minimum) {
opts.min = (schema.exclusiveMinimum) ? schema.minimum : schema.minimum + 0.1;
if (Number.isFinite(schema.minimum)) {
opts.min = (schema.exclusiveMinimum) ? schema.minimum + 0.1 : schema.minimum;
}
if (schema.maximum) {
opts.max = (schema.exclusiveMaximum) ? schema.maximum : schema.maximum - 0.1;
if (Number.isFinite(schema.maximum)) {
opts.max = (schema.exclusiveMaximum) ? schema.maximum - 0.1 : schema.maximum ;
}
//Generate a number that is multiple of schema.multipleOf
if (schema.multipleOf > 0) {
//Use the muplilier as the min number
opts.min = schema.multipleOf;
if (Number.isFinite(schema.multipleOf) && schema.multipleOf > 0) {
//Use the min/muplilier as the min number
//Use default min as 1 if min is not properly set
opts.min = (Number.isFinite(opts.min)) ? (Math.ceil(opts.min / schema.multipleOf)) : 1;
//Use the max/muplilier as the new max value
opts.max = (opts.max) ? opts.max/schema.multipleOf : opts.max;
nummock = Chance.floating(opts);
//Use a default - min + 10 - if max value is not properly set.
opts.max = (Number.isFinite(opts.max)) ? (Math.floor(opts.max / schema.multipleOf)) : (opts.min + 10);

nummock = Chance.integer(opts);
nummock = nummock * schema.multipleOf;
} else {
nummock = Chance.floating(opts);
}
return nummock;
}
};

function booleanMock(schema) {
const booleanMock = schema => {
/**
* If `enum` is defined for the property
*/
if (schema.enum && schema.enum.length > 0) {
return enumMock(schema);
}
return Chance.bool();
}
};
/**
* Geneartes a mock `string` value
* Supports: `minLength`, `maxLength`, `enum`, `date`, and `date-time`
* TODO : `pattern`
*
*/
function stringMock(schema) {
var mockStr;
var opts = {};
var minLength = schema.minLength || 1;
var maxLength = schema.maxLength || minLength + 10;
const stringMock = schema => {
let mockStr;
let opts = {};
let minLength = schema.minLength || 1;
let maxLength = schema.maxLength || minLength + 10;
opts.min = minLength;
opts.max = maxLength;

Expand All @@ -200,29 +191,40 @@ function stringMock(schema) {
}

return mockStr;
}
};

function enumMock(schema) {
var len = schema.enum.length;
var opts = {
const enumMock = schema => {
let len = schema.enum.length;
let opts = {
min: 0,
max: len - 1
};
return schema.enum[Chance.integer(opts)];
}
};

function fileMock() {
const fileMock = () => {
return Chance.file();
}
};

//Find out the type based on schema props
//(This is not a complete list or full proof solution)
function findType(schema) {
var type = 'object';// Use 'object' as the default type
const findType = schema => {
let type = 'object';// Use 'object' as the default type
if (schema.pattern) {
type = 'string';
} else if (schema.items) {
type = 'array';
}
return type;
}
};

const Generators = module.exports = {
object: objectMock,
array: arrayMock,
string: stringMock,
integer: integerMock,
number: numberMock,
boolean: booleanMock,
file: fileMock,
mock
};
Loading