chance-generators
Advanced tools
Comparing version 2.4.1 to 2.5.0
@@ -12,8 +12,12 @@ /*global define*/ | ||
})(this, function (Chance) { | ||
function copy (source) { | ||
var result = {} | ||
Object.keys(source).forEach(function (key) { | ||
result[key] = source[key] | ||
}) | ||
return result | ||
function extend (target) { | ||
for (var i = 1; i < arguments.length; i += 1) { | ||
var source = arguments[i]; | ||
if (source) { | ||
Object.keys(source).forEach(function (key) { | ||
target[key] = source[key]; | ||
}); | ||
} | ||
} | ||
return target; | ||
} | ||
@@ -95,2 +99,12 @@ | ||
if (generator.expand) { | ||
mapGenerator.expand = function (value) { | ||
if (value === lastMappedValue) { | ||
return generator.expand(lastValue).map(f) | ||
} else { | ||
return mapGenerator | ||
} | ||
} | ||
} | ||
installMapFunction(mapGenerator) | ||
@@ -119,2 +133,6 @@ | ||
picksetGenerator.expand = function (data) { | ||
return expanders.pickset(picksetGenerator, data) | ||
} | ||
return picksetGenerator | ||
@@ -142,3 +160,3 @@ }, | ||
var currentLimits = generator.args[0] || {} | ||
var limits = copy(currentLimits) | ||
var limits = extend({}, currentLimits) | ||
@@ -306,2 +324,76 @@ var value = typeof data === 'string' | ||
var expanders = { | ||
n: function (generator, data) { | ||
var dataGenerator = generator.args[0] | ||
var count = generator.args[1] | ||
var options = generator.args[2] | ||
return that.pickset([dataGenerator].concat(data), count, options) | ||
}, | ||
string: function (generator, data) { | ||
return generator.map(function (text) { | ||
var margin = Math.max(Math.min(Math.floor((text.length - data.length) / 2), Math.ceil(data.length * 0.3)), 0) | ||
var includeLeftMargin = chance.bool({ likelihood: 70 }) | ||
var includeRightMargin = chance.bool({ likelihood: 70 }) | ||
var marginLength = (includeLeftMargin ? margin : 0) + (includeRightMargin ? margin : 0) | ||
var result = new Array(marginLength + data.length) | ||
var i = 0 | ||
if (includeLeftMargin) { | ||
while (i < margin) { | ||
result[i] = text[i++] | ||
} | ||
} | ||
for (var j = 0; j < data.length; i++, j++) { | ||
result[i] = chance.bool({ likelihood: 95 }) ? data[j] : text[i % text.length] | ||
} | ||
if (includeRightMargin) { | ||
while (i < result.length) { | ||
result[i] = text[i++] | ||
} | ||
} | ||
return result.join('') | ||
}) | ||
}, | ||
pickset: function (generator, data) { | ||
return generator.map(function (items) { | ||
var margin = Math.max(Math.min(Math.floor((items.length - data.length) / 2), Math.ceil(data.length * 0.3)), 0) | ||
var result = new Array(margin * 2 + data.length) | ||
var i = 0 | ||
while (i < margin) { | ||
result[i] = items[i++] | ||
} | ||
for (var j = 0; j < data.length; i++, j++) { | ||
result[i] = chance.bool({ likelihood: 95 }) ? data[j] : items[i % items.length] | ||
} | ||
while (i < result.length) { | ||
result[i] = items[i++] | ||
} | ||
return result | ||
}) | ||
}, | ||
shape: function (generator, data) { | ||
var shapeGenerators = generator.args[0] | ||
var newShape = Object.keys(shapeGenerators).reduce(function (result, key) { | ||
var entry = shapeGenerators[key] | ||
if (entry && typeof entry.expand === 'function') { | ||
result[key] = entry.expand(data[key]) | ||
} else { | ||
result[key] = entry | ||
} | ||
return result | ||
}, {}) | ||
return that.shape(newShape) | ||
} | ||
} | ||
function createGenerator (name, args, omitUnwap) { | ||
@@ -340,2 +432,13 @@ var omitUnwrapIndex = {} | ||
var expander = expanders[name] | ||
if (expander) { | ||
g.expand = function (data) { | ||
return expander(g, data) | ||
} | ||
} else { | ||
g.expand = function (data) { | ||
return that.pickone([g, that.constant(data)]) | ||
} | ||
} | ||
installMapFunction(g) | ||
@@ -449,3 +552,3 @@ | ||
that.sequence = generatorFunction('sequence', [], function (fn, count) { | ||
that.sequence = generatorFunction('sequence', [], function (fn, count, options) { | ||
count = typeof count === 'undefined' | ||
@@ -456,4 +559,6 @@ ? that.natural({ max: 50 }) | ||
var g = generatorFunction('sequence', [fn, count], function () { | ||
var context = {} | ||
var previous = null | ||
options = options || {} | ||
var context = options.context || {} | ||
g.lastContext = context | ||
var previous = 'previous' in options ? options.previous : null | ||
var valueGenerator = function () { | ||
@@ -469,3 +574,4 @@ var result = previous === null | ||
return that.array(valueGenerator, count)() | ||
g.lastValue = that.array(valueGenerator, count)() | ||
return g.lastValue | ||
}) | ||
@@ -488,2 +594,23 @@ | ||
g.expand = function (data) { | ||
if (g.lastValue !== data || !options.resumable) { | ||
return that.sequence(fn, count) | ||
} | ||
var count = g.args[1] | ||
if (count && count.args[0] && count.args[0].max && count.shrink) { | ||
count = count.shrink(count.args[0].max - data.length) | ||
} else if (typeof count === 'number') { | ||
count = count - data.length | ||
} | ||
return that.sequence(fn, count, { | ||
context: Object.create(g.lastContext), | ||
previous: data[data.length - 1], | ||
resumable: true | ||
}).map(function (items) { | ||
return data.concat(items) | ||
}) | ||
} | ||
installMapFunction(g) | ||
@@ -490,0 +617,0 @@ |
{ | ||
"name": "chance-generators", | ||
"version": "2.4.1", | ||
"version": "2.5.0", | ||
"description": "Random generators based on changejs", | ||
@@ -5,0 +5,0 @@ "main": "lib/chance-generators.js", |
@@ -88,2 +88,21 @@ /*global describe, it*/ | ||
}) | ||
describe('expand', () => { | ||
it('returns a new generator that work on the provided data plus random data from the origin generator', () => { | ||
const originalGenerator = chance.integer({ min: -10, max: 10 }) | ||
const expandedGenerator = originalGenerator.expand(0) | ||
expect([ | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator() | ||
], 'to equal', [ | ||
0, 9, 0, 0, -7, -7, -9 | ||
]) | ||
}) | ||
}) | ||
}) | ||
@@ -154,2 +173,22 @@ | ||
}) | ||
describe('expand', () => { | ||
it('returns a new generator that work on the provided data plus random data from the origin generator', () => { | ||
const lengthGenerator = chance.natural({ max: 30 }) | ||
const originalGenerator = chance.string({ length: lengthGenerator }) | ||
const expandedGenerator = originalGenerator.expand('foobarbaz') | ||
expect([ | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator() | ||
], 'to equal', [ | ||
'(foobarblz', 'panfoTbarbazvMT', 'foobarbaz', 'foobarbaz', 'nc)f5obarbaz&yg', ')uSfoobarbaz', 'ifoobarbazx' | ||
]) | ||
}) | ||
}) | ||
}) | ||
@@ -276,2 +315,18 @@ | ||
}) | ||
describe('expand', () => { | ||
it('returns a new generator that work on the provided data plus random data from the origin generator', () => { | ||
const valueGenerator = chance.string | ||
const lengthGenerator = chance.integer({ min: 2, max: 4 }) | ||
const originalGenerator = chance.n(valueGenerator, lengthGenerator) | ||
const expandedGenerator = originalGenerator.expand(['foo', 'bar', 'baz']) | ||
expect([expandedGenerator(), expandedGenerator(), expandedGenerator(), expandedGenerator()], 'to equal', [ | ||
[ 'baz', 'bar', 'SSlGlheH#ySk0Wbe)' ], | ||
[ 'baz', 'bar', ']nTwTMa', 'foo' ], | ||
[ 'kdv[BrHg6To', 'foo', 'baz' ], | ||
[ 'bar', 'baz', 'foo' ] | ||
]) | ||
}) | ||
}) | ||
}) | ||
@@ -479,2 +534,27 @@ | ||
describe('pickset', () => { | ||
it('returns a new generator picking the given number of random elements from the array', () => { | ||
const arr = [42, 'foo', { wat: 'taw' }] | ||
expect(chance.pickset(arr, 2), 'when called', 'to satisfy', | ||
expect.it('to have length', 2) | ||
.and('to have items satisfying', 'to be contained by', arr)) | ||
}) | ||
describe('expand', () => { | ||
it('returns a new generator that work on the provided data plus random data from the origin generator', () => { | ||
const valueGenerator = chance.string | ||
const lengthGenerator = chance.integer({ min: 2, max: 20 }) | ||
const originalGenerator = chance.pickset(Array(20).fill(valueGenerator), lengthGenerator) | ||
const expandedGenerator = originalGenerator.expand(['foo', 'bar', 'baz']) | ||
expect([expandedGenerator(), expandedGenerator(), expandedGenerator(), expandedGenerator()], 'to equal', [ | ||
[ ')19*p', 'foo', 'MaFbvMTDkdv[Br', 'baz', 'mHea(*)P7CwbhrY' ], | ||
[ 'UHyheBxXyX1RVu$PIC', 'foo', 'bar', 'baz', 'JxPLZ^ksSEN3pq*' ], | ||
[ ')%P%$U', 'foo', 'bar', 'baz', 'HW]qn0brKyn3BW3!' ], | ||
[ 'foo', 'bar', 'baz' ] | ||
]) | ||
}) | ||
}) | ||
}) | ||
describe('pickone', () => { | ||
@@ -659,2 +739,36 @@ describe('given an array', () => { | ||
describe('expand', () => { | ||
it('returns a new generator that expands the entry generators', () => { | ||
let originalGenerator = chance.shape({ | ||
constant: 42, | ||
number: chance.integer({ min: 2, max: 4 }), | ||
string: chance.string({ length: chance.natural({ max: 20 }) }) | ||
}) | ||
const expandedGenerator = originalGenerator.expand({ | ||
constant: 42, | ||
number: 3, | ||
string: 'foobar' | ||
}) | ||
expect([ | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator() | ||
], 'to equal', [ | ||
{ constant: 42, number: 3, string: 'fooblr' }, | ||
{ constant: 42, number: 3, string: 'aFfoobardv' }, | ||
{ constant: 42, number: 3, string: 'foobara' }, | ||
{ constant: 42, number: 4, string: 'jfoobarC' }, | ||
{ constant: 42, number: 3, string: 'foobar' }, | ||
{ constant: 42, number: 3, string: 'foobar' }, | ||
{ constant: 42, number: 4, string: 'ukfoobarF5' } | ||
]) | ||
}) | ||
}) | ||
describe('map', () => { | ||
@@ -712,2 +826,24 @@ it('returns a new generator where the generated values are mapped with the given function', () => { | ||
}) | ||
describe('shrink', () => { | ||
it('returns a new generator where the input is expanded with with regards to the original generator', () => { | ||
let generator = chance.shape({ | ||
x: chance.integer({ min: -20, max: 20 }), | ||
y: chance.integer({ min: -20, max: 20 }) | ||
}).map(coordinate => `${coordinate.x},${coordinate.y}`) | ||
const expandedGenerator = generator.expand(generator()) | ||
expect([ | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator(), | ||
expandedGenerator() | ||
], 'to satisfy', [ | ||
'18,12', '-5,-14', '-14,-18', '15,4', '-5,-20', '-5,12' | ||
]) | ||
}) | ||
}) | ||
}) | ||
@@ -751,3 +887,63 @@ }) | ||
}) | ||
describe('expand (when resumable)', () => { | ||
it('returns a new generator continues when the sequence generator stopped', () => { | ||
let generator = chance.sequence((context, previous) => { | ||
const length = previous === undefined | ||
? 25 | ||
: Math.max(0, previous.length - 1) | ||
return chance.string({ length }) | ||
}, chance.natural({ max: 30 }), { resumable: true }) | ||
const value = generator() | ||
expect(value, 'to satisfy', [ | ||
'(n25SSlGlheH#ySk0Wbe)19*p', | ||
'n]nTwTMaFbvMTDkdv[BrHg6T', | ||
'CM[RId@SYmHea(*)P7Cwbhr', | ||
'rGYjTK9cm^CtnX3xFMpOQn', | ||
')!5H*D%&S1&ygQoMd)y!C', | ||
'uN9RA)uSOukv7mfb]F5D', | ||
'vab8o00165Sf&AWi^@!', | ||
'HyheBxXyX1RVu$PICi', | ||
'0!41Pr5sKcM0FibGh', | ||
'c%VJxPLZ^ksSEN3p', | ||
'*fSvZl$&U7vUh#H' | ||
]) | ||
const expandedGenerator = generator.expand(value) | ||
expect(expandedGenerator(), 'to satisfy', [ | ||
'(n25SSlGlheH#ySk0Wbe)19*p', | ||
'n]nTwTMaFbvMTDkdv[BrHg6T', | ||
'CM[RId@SYmHea(*)P7Cwbhr', | ||
'rGYjTK9cm^CtnX3xFMpOQn', | ||
')!5H*D%&S1&ygQoMd)y!C', | ||
'uN9RA)uSOukv7mfb]F5D', | ||
'vab8o00165Sf&AWi^@!', | ||
'HyheBxXyX1RVu$PICi', | ||
'0!41Pr5sKcM0FibGh', | ||
'c%VJxPLZ^ksSEN3p', | ||
'*fSvZl$&U7vUh#H', | ||
'nE%$Ny7j%Ax^iu', | ||
'VFa8A@wamLNEJ', | ||
'Zitys*mxqMP0', | ||
'Ae)s)ssZK0w', | ||
'v]ctT[LEdc', | ||
'z^UrYkNKH', | ||
'OrRXf4Br', | ||
'17BIU[U', | ||
'N8g79l', | ||
'LnZd@', | ||
'yYqb', | ||
'L7q', | ||
'Vh', | ||
'*', | ||
'', | ||
'' | ||
]) | ||
}) | ||
}) | ||
}) | ||
}) |
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
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
59353
1332
10