Comparing version 0.1.1 to 0.1.2
{ | ||
"name": "fuzzur", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"description": "A flexible input fuzzer for tests", | ||
@@ -13,3 +13,4 @@ "keywords": [ | ||
"scripts": { | ||
"test": "node_modules/.bin/mocha" | ||
"test": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage", | ||
"codestyle": "./node_modules/.bin/jscs ./src ./test --preset airbnb" | ||
}, | ||
@@ -22,3 +23,3 @@ "author": { | ||
"bugs": { | ||
"url" : "https://github.com/Joe8Bit/fuzzur/issues" | ||
"url": "https://github.com/Joe8Bit/fuzzur/issues" | ||
}, | ||
@@ -35,5 +36,14 @@ "repository": { | ||
"lodash": "^3.3.1", | ||
"type-detect": "^0.1.2" | ||
}, | ||
"devDependencies": { | ||
"coveralls": "^2.11.2", | ||
"jscs": "^1.11.3", | ||
"mocha": "^2.1.0", | ||
"type-detect": "^0.1.2" | ||
} | ||
"mocha-lcov-reporter": "0.0.1", | ||
"pre-commit": "^1.0.5" | ||
}, | ||
"pre-commit": [ | ||
"codestyle" | ||
] | ||
} |
## Fuzzur | ||
![Travis](https://api.travis-ci.org/Joe8Bit/fuzzur.svg) [![Coverage Status](https://coveralls.io/repos/Joe8Bit/fuzzur/badge.svg?branch=master)](https://coveralls.io/r/Joe8Bit/fuzzur?branch=master) [![Code Climate](https://codeclimate.com/github/Joe8Bit/fuzzur/badges/gpa.svg)](https://codeclimate.com/github/Joe8Bit/fuzzur) [![npm version](https://badge.fury.io/js/fuzzur.svg)](http://badge.fury.io/js/fuzzur) [![Dependency Status](https://david-dm.org/joe8bit/fuzzur.svg)](https://david-dm.org/joe8bit/fuzzur) | ||
A [fuzzer](http://en.wikipedia.org/wiki/Fuzz_testing) for testing. This implements mutation fuzzing, in which an expect input is mutated (changed) many times in order to trigger unexpected behavior or crashes. | ||
This is based heavily on the existing [Fuzzer by Mapbox](https://github.com/mapbox/fuzzer). | ||
This is based heavily on the existing [Fuzzer by Mapbox](https://github.com/mapbox/fuzzer) by Mapbox. There are a couple of key differences however: | ||
* The mutation is done through one method, and internal type inference and detection. Built to satisfy my own use case. | ||
* Ancdotally, and again for my specific use case, it is 2x faster. | ||
* It implements additional `regex` and `Date` mutators | ||
* It's `Array` and `Object` recursion patterns are more efficently traversed for some very large trees. I have *a little* data on this, and will update soon, it's not a massive improvement but for my use case made a difference. | ||
* It supports some configurable options for the `String`, `Number` and `Date` mutators. | ||
* It doesn't coerce number sub-types e.g. mutating an integer will result in an integer and mutating a float will result in a float. | ||
## Install | ||
@@ -15,7 +24,15 @@ | ||
Using the fuzzer is simple, in it's most basic forum it can be used thusly. | ||
Using the fuzzer is simple, in it's most basic form it can be used thusly. | ||
```javascript | ||
var fuzzur = require('fuzzur'), | ||
mutatedData = fuzzur.mutate(/* Some data type */); | ||
var test = require('tap').test, | ||
fuzzur = require('fuzzur'); | ||
test('My thing does something', function(t) { | ||
for (var i = 0; i < 1000; i++) { | ||
t.doesNotThrow(function() { | ||
myThing(fuzzur.mutate( /* some input type */ )); | ||
}); | ||
} | ||
}); | ||
``` | ||
@@ -27,2 +44,38 @@ | ||
##Configuation | ||
There are a few configurable options that can be set, they are passed in as the second argument to the `mutate()` invokation e.g. | ||
```javascript | ||
var test = require('tap').test, | ||
fuzzur = require('fuzzur'); | ||
test('My thing does something', function(t) { | ||
for (var i = 0; i < 1000; i++) { | ||
t.doesNotThrow(function() { | ||
myThing(fuzzur.mutate('foobar', { | ||
string: { | ||
sampleSet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', // The set of chars from which the mutated strings are built, can be overriden with custom sets | ||
randomisationPasses: 10 // The maximum number of randomisation passes that are done on each string, a random number between 1 and this | ||
}, | ||
number: { | ||
integer: { | ||
min: -1000, // The floor or numbers to generate from | ||
max: 10000 // The ceiling of features to generate too | ||
}, | ||
float: { | ||
min: -1000, // The floor or numbers to generate from | ||
max: 10000 // The ceiling of features to generate too | ||
arbitraryPrecision: 2 // How many points of precision should be passed into .toFixed() | ||
} | ||
}, | ||
date: { | ||
endYear: 2022 // The year before which our mutated date should be generated | ||
} | ||
})); | ||
}); | ||
} | ||
}); | ||
``` | ||
## Testing | ||
@@ -32,2 +85,10 @@ | ||
npm test | ||
``` | ||
``` | ||
## Notes | ||
There are currently three types that not mutable via Fuzzur, they are: | ||
* `Function` - this is coming soon | ||
* `Undefined` | ||
* `null` |
@@ -1,7 +0,9 @@ | ||
var type = require('type-detect'), | ||
_ = require('lodash'), | ||
merge = require('deepmerge'); | ||
'use strict'; | ||
var type = require('type-detect'); | ||
var _ = require('lodash'); | ||
var merge = require('deepmerge'); | ||
/** | ||
* The public mutate method, takes data, mutates it and returns a mutate copy | ||
* The public mutate method, takes data, mutates it and returns a mutate copy | ||
* @param {Any} data Any data format | ||
@@ -12,4 +14,4 @@ * @param {Object} config An options block, that corressponds to the defaults laid out below | ||
function mutate(data, config) { | ||
var _mutateInstance = new MutateData(data, (config || {})), | ||
typeOf = type(data); | ||
var _mutateInstance = new MutateData(data, (config || {})); | ||
var typeOf = type(data); | ||
@@ -55,4 +57,4 @@ return _mutateInstance[typeOf](); | ||
MutateData.prototype.object = function(obj) { | ||
var _this = this, | ||
copy = _.extend({}, (obj || this.data)); | ||
var _this = this; | ||
var copy = _.extend({}, (obj || this.data)); | ||
@@ -72,4 +74,4 @@ Object.keys(copy).forEach(function(key) { | ||
MutateData.prototype.array = function(arr) { | ||
var _this = this, | ||
mutator = arr || this.data; | ||
var _this = this; | ||
var mutator = arr || this.data; | ||
@@ -87,12 +89,12 @@ return _.map(mutator, function(item) { | ||
MutateData.prototype.string = function(str) { | ||
var mutator = str || this.data, | ||
split = mutator.split(''), | ||
passes = _.random(1, this.config.string.randomisationPasses), | ||
i; | ||
var mutator = str || this.data; | ||
var split = mutator.split(''); | ||
var passes = _.random(1, this.config.string.randomisationPasses); | ||
var i; | ||
for (i = 0; i < passes; i++) { | ||
split.splice(_.random(0, split.length), 0, this.config.string.sampleSet.split('')[_.random(0, this.config.string.sampleSet.length)]); | ||
} | ||
for (i = 0; i < passes; i++) { | ||
split.splice(_.random(0, split.length), 0, this.config.string.sampleSet.split('')[_.random(0, this.config.string.sampleSet.length)]); | ||
} | ||
return _.shuffle(split).join(''); | ||
return _.shuffle(split).join(''); | ||
}; | ||
@@ -134,7 +136,7 @@ | ||
// This is a VERY naive mutation | ||
var mutator = reg || this.data, | ||
composition = mutator.toString().split('/'), | ||
pattern = composition[1], | ||
newPattern = this.string(pattern.replace('-', '')), | ||
flags = composition[2]; | ||
var mutator = reg || this.data; | ||
var composition = mutator.toString().split('/'); | ||
var pattern = composition[1]; | ||
var newPattern = this.string(pattern.replace('-', '')); | ||
var flags = composition[2]; | ||
@@ -171,4 +173,4 @@ return new RegExp([newPattern, flags].join('/')); | ||
MutateData.prototype.date = function(dt) { | ||
var start = dt || this.data, | ||
end = new Date(this.config.date.endYear, 1, 1); | ||
var start = dt || this.data; | ||
var end = new Date(this.config.date.endYear, 1, 1); | ||
@@ -178,2 +180,2 @@ return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); | ||
module.exports.mutate = mutate; | ||
module.exports.mutate = mutate; |
@@ -1,5 +0,5 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'), | ||
_ = require('lodash'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
var _ = require('lodash'); | ||
@@ -11,4 +11,4 @@ describe('The fuzzer', function() { | ||
it('when passed directly in', function() { | ||
var arr = ['aa0u3409', 'bb-03i4r-0i4'], | ||
mut = fuzzer.mutate(arr); | ||
var arr = ['aa0u3409', 'bb-03i4r-0i4']; | ||
var mut = fuzzer.mutate(arr); | ||
@@ -24,4 +24,4 @@ assert.equal(_.find(arr, function(item) { | ||
arr: ['aa09u4', 'bbo2rui'] | ||
}, | ||
mut = fuzzer.mutate(obj); | ||
}; | ||
var mut = fuzzer.mutate(obj); | ||
@@ -34,4 +34,4 @@ assert.equal(_.find(obj.arr, function(item) { | ||
it('when they are nested', function() { | ||
var arr = ['aa', ['bb', 'cc']], | ||
mut = fuzzer.mutate(arr); | ||
var arr = ['aa', ['bb', 'cc']]; | ||
var mut = fuzzer.mutate(arr); | ||
@@ -45,2 +45,2 @@ assert.equal(_.find(arr[1], function(item) { | ||
}); | ||
}); |
@@ -1,4 +0,4 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
@@ -10,4 +10,4 @@ describe('The fuzzer', function() { | ||
it('when passed directly in', function() { | ||
var d = new Date(), | ||
fuzzed = fuzzer.mutate(d); | ||
var d = new Date(); | ||
var fuzzed = fuzzer.mutate(d); | ||
@@ -21,4 +21,4 @@ assert.notEqual(d.getTime(), fuzzed.getTime()); | ||
d: new Date() | ||
}, | ||
fuzzed = fuzzer.mutate(data); | ||
}; | ||
var fuzzed = fuzzer.mutate(data); | ||
@@ -30,4 +30,4 @@ assert.notEqual(data.d.getTime(), fuzzed.d.getTime()); | ||
it('when passed in as array item', function() { | ||
var data = [new Date()] | ||
fuzzed = fuzzer.mutate(data); | ||
var data = [new Date()]; | ||
var fuzzed = fuzzer.mutate(data); | ||
@@ -40,2 +40,2 @@ assert.notEqual(data[0].getTime(), fuzzed[0].getTime()); | ||
}); | ||
}); |
@@ -1,4 +0,4 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
@@ -28,2 +28,2 @@ describe('The fuzzer', function() { | ||
}); | ||
}); |
@@ -1,4 +0,4 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
@@ -11,2 +11,2 @@ describe('The fuzzer', function() { | ||
}); | ||
}); |
@@ -1,4 +0,4 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
@@ -27,2 +27,2 @@ describe('The fuzzer', function() { | ||
}); | ||
}); |
@@ -1,4 +0,4 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
@@ -14,6 +14,6 @@ describe('The fuzzer', function() { | ||
it('when passed directly in', function() { | ||
var inte = 12, | ||
flt = 12.34, | ||
intMut = fuzzer.mutate(inte); | ||
fltMut = fuzzer.mutate(flt); | ||
var inte = 12; | ||
var flt = 12.34; | ||
var intMut = fuzzer.mutate(inte); | ||
var fltMut = fuzzer.mutate(flt); | ||
@@ -33,8 +33,8 @@ assert.notEqual(inte, intMut); | ||
foo: 12 | ||
}, | ||
flt = { | ||
}; | ||
var flt = { | ||
bar: 12.34 | ||
}, | ||
intMut = fuzzer.mutate(inte); | ||
fltMut = fuzzer.mutate(flt); | ||
}; | ||
var intMut = fuzzer.mutate(inte); | ||
var fltMut = fuzzer.mutate(flt); | ||
@@ -54,8 +54,8 @@ assert.notEqual(inte.foo, intMut.foo); | ||
foo: 12 | ||
}, | ||
flt = { | ||
}; | ||
var flt = { | ||
bar: 12.34 | ||
}, | ||
intMut = fuzzer.mutate(inte); | ||
fltMut = fuzzer.mutate(flt); | ||
}; | ||
var intMut = fuzzer.mutate(inte); | ||
var fltMut = fuzzer.mutate(flt); | ||
@@ -86,2 +86,2 @@ assert.notEqual(inte.foo, intMut.foo); | ||
}); | ||
}); |
@@ -1,5 +0,5 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'), | ||
_ = require('lodash'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
var _ = require('lodash'); | ||
@@ -13,4 +13,4 @@ describe('The fuzzer', function() { | ||
foo: 'bar' | ||
}, | ||
mut = fuzzer.mutate(obj); | ||
}; | ||
var mut = fuzzer.mutate(obj); | ||
@@ -24,4 +24,4 @@ assert.notEqual(obj.foo, mut.foo); | ||
foo: 'bar' | ||
}] | ||
mut = fuzzer.mutate(arr); | ||
}]; | ||
var mut = fuzzer.mutate(arr); | ||
@@ -38,4 +38,4 @@ assert.notEqual(arr[1].foo, mut[1].foo); | ||
} | ||
}, | ||
mut = fuzzer.mutate(obj); | ||
}; | ||
var mut = fuzzer.mutate(obj); | ||
@@ -48,2 +48,2 @@ assert.notEqual(obj.baz.blork, mut.baz.blork); | ||
}); | ||
}); |
@@ -1,4 +0,4 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
@@ -10,6 +10,6 @@ describe('The fuzzer', function() { | ||
it('when passed directly in', function() { | ||
var r = /a-z/gi, | ||
r2 = new RegExp(/a-z/gi), | ||
fuzzed = fuzzer.mutate(r); | ||
fuzzed2 = fuzzer.mutate(r2); | ||
var r = /a-z/gi; | ||
var r2 = new RegExp(/a-z/gi); | ||
var fuzzed = fuzzer.mutate(r); | ||
var fuzzed2 = fuzzer.mutate(r2); | ||
@@ -25,4 +25,4 @@ assert.notEqual(r.toString(), fuzzed.toString()); | ||
d: /a-z/gi | ||
}, | ||
fuzzed = fuzzer.mutate(data); | ||
}; | ||
var fuzzed = fuzzer.mutate(data); | ||
@@ -34,4 +34,4 @@ assert.notEqual(data.d.toString(), fuzzed.d.toString()); | ||
it('when passed in as array item', function() { | ||
var data = [new RegExp(/a-z/gi)] | ||
fuzzed = fuzzer.mutate(data); | ||
var data = [new RegExp(/a-z/gi)]; | ||
var fuzzed = fuzzer.mutate(data); | ||
@@ -44,2 +44,2 @@ assert.notEqual(data[0].toString(), fuzzed[0].toString()); | ||
}); | ||
}); |
@@ -1,4 +0,4 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
@@ -28,4 +28,4 @@ describe('The fuzzer', function() { | ||
it('and make an arbitrary number of randomisation passes', function() { | ||
var str = 'kuh83', | ||
mut = fuzzer.mutate(str, { | ||
var str = 'kuh83'; | ||
var mut = fuzzer.mutate(str, { | ||
string: { | ||
@@ -39,6 +39,6 @@ randomisationPasses: 50 | ||
it('and take an arbitrary sample set to mutate strings from', function() { | ||
var allowedStrings = ['f', 'o', 'o', 'A', 'B'], | ||
str = 'foo', | ||
sample = 'AB', | ||
mut = fuzzer.mutate(str, { | ||
var allowedStrings = ['f', 'o', 'o', 'A', 'B']; | ||
var str = 'foo'; | ||
var sample = 'AB'; | ||
var mut = fuzzer.mutate(str, { | ||
string: { | ||
@@ -56,2 +56,2 @@ sampleSet: sample | ||
}); | ||
}); |
@@ -1,4 +0,4 @@ | ||
var assert = require('assert'), | ||
type = require('type-detect'), | ||
fuzzer = require('../src/'); | ||
var assert = require('assert'); | ||
var type = require('type-detect'); | ||
var fuzzer = require('../src/'); | ||
@@ -21,3 +21,3 @@ describe('The fuzzer', function() { | ||
it('it should just return undefined when called as array item', function() { | ||
var foo = [undefined] | ||
var foo = [undefined]; | ||
assert.equal(fuzzer.mutate(foo)[0], foo[0]); | ||
@@ -28,2 +28,2 @@ }); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
19900
4
15
453
92
5
- Removedmocha@^2.1.0
- Removedcommander@0.6.12.3.0(transitive)
- Removeddebug@2.2.0(transitive)
- Removeddiff@1.4.0(transitive)
- Removedescape-string-regexp@1.0.2(transitive)
- Removedglob@3.2.11(transitive)
- Removedgrowl@1.9.2(transitive)
- Removedjade@0.26.3(transitive)
- Removedlru-cache@2.7.3(transitive)
- Removedminimatch@0.3.0(transitive)
- Removedminimist@0.0.8(transitive)
- Removedmkdirp@0.3.00.5.1(transitive)
- Removedmocha@2.5.3(transitive)
- Removedms@0.7.1(transitive)
- Removedsigmund@1.0.1(transitive)
- Removedsupports-color@1.2.0(transitive)
- Removedto-iso-string@0.0.2(transitive)