@thomsbg/ot-fuzzer
Advanced tools
Comparing version 2.0.0 to 2.0.1
308
lib/index.js
@@ -1,19 +0,77 @@ | ||
/* | ||
* decaffeinate suggestions: | ||
* DS101: Remove unnecessary use of Array.from | ||
* DS102: Remove unnecessary code created because of implicit returns | ||
* DS202: Simplify dynamic range loops | ||
* DS205: Consider reworking code to avoid use of IIFEs | ||
* DS207: Consider shorter variations of null checks | ||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md | ||
*/ | ||
let randomReal; | ||
const assert = require('assert'); | ||
const util = require('util'); | ||
const fs = require('fs'); | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.transformX = exports.randomWord = exports.randomInt = exports.randomReal = undefined; | ||
exports.transformLists = transformLists; | ||
exports.default = function (type, genRandomOp, iterations) { | ||
if (iterations == null) { | ||
iterations = 2000; | ||
} | ||
_assert2.default.ok(type.transform); | ||
const [stats, restore] = collectStats(type); | ||
console.error(` Running ${iterations} randomized tests for type ${type.name}...`); | ||
if (seed != null) { | ||
console.error(` (seed: ${seed})`); | ||
} | ||
const warnUnless = fn => { | ||
if (type[fn] == null) { | ||
console.error(`NOTE: Not running ${fn} tests because ${type.name} does not have ${fn}() defined`); | ||
} | ||
}; | ||
warnUnless('invert'); | ||
warnUnless('compose'); | ||
let doc = type.create(); | ||
console.time('randomizer'); | ||
const iterationsPerPct = iterations / 100; | ||
for (let n = 0, end = iterations, asc = 0 <= end; asc ? n <= end : n >= end; asc ? n++ : n--) { | ||
if (n % (iterationsPerPct * 2) === 0) { | ||
process.stdout.write(n % (iterationsPerPct * 10) === 0 ? `${n / iterationsPerPct}` : '.'); | ||
} | ||
p('ITERATION', n); | ||
doc = testRandomOp(type, genRandomOp, doc); | ||
} | ||
console.log(); | ||
console.timeEnd('randomizer'); | ||
console.log("Performed:"); | ||
for (let fn in stats) { | ||
const number = stats[fn];console.log(`\t${fn}s: ${number}`); | ||
} | ||
return restore(); | ||
}; | ||
var _assert = require('assert'); | ||
var _assert2 = _interopRequireDefault(_assert); | ||
var _util = require('util'); | ||
var _util2 = _interopRequireDefault(_util); | ||
var _fs = require('fs'); | ||
var _fs2 = _interopRequireDefault(_fs); | ||
var _mersenne = require('./mersenne'); | ||
var mersenne = _interopRequireWildcard(_mersenne); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
// You can use this to enable debugging info in this file. | ||
// p = -> | ||
const p = () => {} // console.log; | ||
const i = (...args) => util.inspect(args, {colors:true, depth:null}); | ||
const p = () => {}; | ||
// const p = console.log; | ||
const i = (...args) => _util2.default.inspect(args, { colors: true, depth: null }); | ||
const pi = (...args) => p(i(...args)); | ||
@@ -23,18 +81,19 @@ | ||
// with avoiding obscure bugs caused by a rare seed. | ||
const seed = Math.floor(Date.now() / (1000*60*60*6)); | ||
const seed = Math.floor(Date.now() / (1000 * 60 * 60 * 6)); | ||
let randomReal; | ||
if (seed != null) { | ||
const mersenne = require('./mersenne'); | ||
mersenne.seed(seed); | ||
randomReal = (exports.randomReal = mersenne.rand_real); | ||
exports.randomReal = randomReal = mersenne.rand_real; | ||
} else { | ||
randomReal = (exports.randomReal = Math.random); | ||
exports.randomReal = randomReal = Math.random; | ||
} | ||
exports.randomReal = randomReal; | ||
// Generate a random int 0 <= k < n | ||
const randomInt = exports.randomInt = (n) => Math.floor(randomReal() * n); | ||
const randomInt = exports.randomInt = n => Math.floor(randomReal() * n); | ||
// Return a random word from a corpus each time the method is called | ||
const words = fs.readFileSync(__dirname + '/jabberwocky.txt').toString().split(/\W+/); | ||
const words = _fs2.default.readFileSync(__dirname + '/../jabberwocky.txt').toString().split(/\W+/); | ||
const randomWord = exports.randomWord = () => words[randomInt(words.length)]; | ||
@@ -49,9 +108,8 @@ | ||
// This is O(serverOps.length * clientOps.length) | ||
const transformLists = exports.transformLists = function(type, serverOps, clientOps) { | ||
// p "Transforming #{i serverOps} with #{i clientOps}" | ||
function transformLists(type, serverOps, clientOps) { | ||
p(`Transforming ${i(serverOps)} with ${i(clientOps)}`); | ||
serverOps = serverOps.map(s => { | ||
clientOps = clientOps.map(c => { | ||
// p "X #{i s} by #{i c}" | ||
[s, c_] = transformX(type, s, c); | ||
// p "=> #{i s} by #{i c_}" | ||
p(`X ${i(s)} by ${i(c)}`)[(s, c_)] = transformX(type, s, c); | ||
p(`=> ${i(s)} by ${i(c_)}`); | ||
return c_; | ||
@@ -72,3 +130,3 @@ }); | ||
// This is needed because calling apply() now destroys the original object. | ||
const clone = function(o, type) { | ||
const clone = function (o, type) { | ||
if (type.serialize) { | ||
@@ -87,6 +145,8 @@ o = type.serialize(o); | ||
// Returns client result | ||
const testRandomOp = function(type, genRandomOp, initialDoc) { | ||
const testRandomOp = function (type, genRandomOp, initialDoc) { | ||
let c_s, doc, op, s, s_c, testInvert; | ||
if (initialDoc == null) { initialDoc = type.create(); } | ||
const makeDoc = () => ({ops:[], result:initialDoc}); | ||
if (initialDoc == null) { | ||
initialDoc = type.create(); | ||
} | ||
const makeDoc = () => ({ ops: [], result: initialDoc }); | ||
const opSets = [0, 1, 2].map(makeDoc); | ||
@@ -101,19 +161,21 @@ const [client, client2, server] = opSets; | ||
// pi('client', client) | ||
// pi('client2', client2) | ||
// pi('server', server) | ||
pi('client', client); | ||
pi('client2', client2); | ||
pi('server', server); | ||
const checkSnapshotsEq = (a, b) => { | ||
if (type.serialize) { | ||
assert.deepStrictEqual(type.serialize(a), type.serialize(b)) | ||
_assert2.default.deepStrictEqual(type.serialize(a), type.serialize(b)); | ||
} else { | ||
assert.deepStrictEqual(a, b) | ||
_assert2.default.deepStrictEqual(a, b); | ||
} | ||
} | ||
}; | ||
// First, test type.apply. | ||
p('APPLY') | ||
p('APPLY'); | ||
for (var set of opSets) { | ||
s = clone(initialDoc, type); | ||
for (op of set.ops) { s = type.apply(s, op); } | ||
for (op of set.ops) { | ||
s = type.apply(s, op); | ||
} | ||
@@ -123,3 +185,3 @@ try { | ||
} catch (error) { | ||
// pi(set) | ||
pi(set); | ||
throw error; | ||
@@ -132,3 +194,3 @@ } | ||
if (type.shatter) { | ||
p('SHATTER') | ||
p('SHATTER'); | ||
for (set of opSets) { | ||
@@ -147,6 +209,8 @@ s = clone(initialDoc, type); | ||
if (type.invert != null) { | ||
p('INVERT') | ||
p('INVERT'); | ||
// Invert all the ops and apply them to result. Should end up with initialDoc. | ||
testInvert = function(doc, ops) { | ||
if (ops == null) { ({ ops } = doc); } | ||
testInvert = function (doc, ops) { | ||
if (ops == null) { | ||
({ ops } = doc); | ||
} | ||
let snapshot = clone(doc.result, type); | ||
@@ -162,25 +226,43 @@ | ||
return checkSnapshotsEq(snapshot, initialDoc); | ||
checkSnapshotsEq(snapshot, initialDoc); | ||
}; | ||
for (set of opSets) { testInvert(set); } | ||
for (set of opSets) { | ||
testInvert(set); | ||
} | ||
} | ||
if (type.diff != null) { | ||
p('DIFF') | ||
const testDiff = function(doc) { | ||
p('DIFF'); | ||
const testDiff = function (doc) { | ||
const op_ = type.diff(clone(initialDoc, type), doc.result); | ||
const result = type.apply(clone(initialDoc, type), op_); | ||
return checkSnapshotsEq(result, doc.result); | ||
checkSnapshotsEq(result, doc.result); | ||
}; | ||
for (set of opSets) { | ||
if (doc.ops.length > 0) { testDiff(set); } | ||
if (doc.ops.length > 0) { | ||
testDiff(set); | ||
} | ||
} | ||
} | ||
if (type.diffX) { | ||
const testDiffX = doc => { | ||
const [op1_, op2_] = type.diffX(initialDoc, doc.result); | ||
const result1 = type.apply(clone(doc.result), op1_); | ||
const result2 = type.apply(clone(initialDoc), op2_); | ||
checkSnapshotsEq(result1, initialDoc); | ||
checkSnapshotsEq(result2, doc.result); | ||
}; | ||
for (set of opSets) { | ||
testDiffX(set); | ||
} | ||
} | ||
// If all the ops are composed together, then applied, we should get the same result. | ||
if (type.compose != null) { | ||
p('COMPOSE') | ||
const compose = function(doc) { | ||
p('COMPOSE'); | ||
const compose = function (doc) { | ||
if (doc.ops.length > 0) { | ||
@@ -191,10 +273,10 @@ try { | ||
pi('initial', initialDoc); | ||
pi('composing', doc.ops) | ||
pi('composed', doc.composed) | ||
pi('composed applied', actual) | ||
pi('expected', doc.result) | ||
return checkSnapshotsEq(doc.result, actual); | ||
pi('composing', doc.ops); | ||
pi('composed', doc.composed); | ||
pi('composed applied', actual); | ||
pi('expected', doc.result); | ||
checkSnapshotsEq(doc.result, actual); | ||
// .... And this should match the expected document. | ||
} catch (e) { | ||
// pi('doc', doc) | ||
pi('doc', doc); | ||
throw e; | ||
@@ -205,3 +287,5 @@ } | ||
for (set of opSets) { compose(set); } | ||
for (set of opSets) { | ||
compose(set); | ||
} | ||
@@ -228,8 +312,8 @@ for (set of opSets) { | ||
pi('initial', initialDoc); | ||
pi('server delta', server.composed) | ||
pi('client delta', client.composed) | ||
pi('server delta xfmd', server_) | ||
pi('client delta xfmd', client_) | ||
pi('server then client', s_c) | ||
pi('client then server', c_s) | ||
pi('server delta', server.composed); | ||
pi('client delta', client.composed); | ||
pi('server delta xfmd', server_); | ||
pi('client delta xfmd', client_); | ||
pi('server then client', s_c); | ||
pi('client then server', c_s); | ||
checkSnapshotsEq(s_c, c_s); | ||
@@ -248,3 +332,5 @@ | ||
let x1 = server.composed; | ||
for (let c of client.ops) { x1 = type.transform(x1, c, 'left'); } | ||
for (let c of client.ops) { | ||
x1 = type.transform(x1, c, 'left'); | ||
} | ||
@@ -254,6 +340,6 @@ let x2 = server.composed; | ||
assert.deepStrictEqual(x1, x2); | ||
_assert2.default.deepStrictEqual(x1, x2); | ||
} | ||
if (type.tp2 && (client2.composed != null)) { | ||
if (type.tp2 && client2.composed != null) { | ||
// TP2 requires that T(op3, op1 . T(op2, op1)) == T(op3, op2 . T(op1, op2)). | ||
@@ -263,3 +349,3 @@ const lhs = type.transform(client2.composed, type.compose(client.composed, server_), 'left'); | ||
assert.deepStrictEqual(lhs, rhs); | ||
_assert2.default.deepStrictEqual(lhs, rhs); | ||
} | ||
@@ -270,6 +356,6 @@ } | ||
if (type.prune != null) { | ||
p('PRUNE') | ||
p('PRUNE'); | ||
const [op1] = Array.from(genRandomOp(initialDoc)); | ||
const [op2] = Array.from(genRandomOp(initialDoc)); | ||
const [op1] = genRandomOp(initialDoc); | ||
const [op2] = genRandomOp(initialDoc); | ||
@@ -280,3 +366,3 @@ for (let idDelta of ['left', 'right']) { | ||
assert.deepStrictEqual(op1, op1_pruned); | ||
_assert2.default.deepStrictEqual(op1, op1_pruned); | ||
} | ||
@@ -287,9 +373,9 @@ } | ||
if (false && client.ops.length > 0 && server.ops.length > 0) { | ||
p('TRANSFORM LIST') | ||
p(`s ${i(server.result)} c ${i(client.result)} XF ${i(server.ops)} x ${i(client.ops)}`) | ||
p('TRANSFORM LIST'); | ||
p(`s ${i(server.result)} c ${i(client.result)} XF ${i(server.ops)} x ${i(client.ops)}`); | ||
const [s_, c_] = transformLists(type, server.ops, client.ops); | ||
p(`XF result -> ${i(s_)} x ${i(c_)}`) | ||
// p(`applying ${i(c_)} to ${i(server.result)}`) | ||
p(`XF result -> ${i(s_)} x ${i(c_)}`); | ||
p(`applying ${i(c_)} to ${i(server.result)}`); | ||
s_c = c_.reduce(type.apply, clone(server.result, type)); | ||
// p "applying #{i s_} to #{i client.result}" | ||
p(`applying ${i(s_)} to ${i(client.result)}`); | ||
c_s = s_.reduce(type.apply, clone(client.result, type)); | ||
@@ -312,3 +398,3 @@ | ||
const collectStats = function(type) { | ||
const collectStats = function (type) { | ||
const functions = ['transform', 'compose', 'apply', 'prune']; | ||
@@ -318,16 +404,22 @@ | ||
for (var fn of functions) { | ||
if (type[fn] != null) { orig[fn] = type[fn]; } | ||
if (type[fn] != null) { | ||
orig[fn] = type[fn]; | ||
} | ||
} | ||
const restore = () => { | ||
for (fn of functions) { | ||
if (orig[fn] != null) { type[fn] = orig[fn]; } | ||
if (orig[fn] != null) { | ||
type[fn] = orig[fn]; | ||
} | ||
} | ||
} | ||
}; | ||
const stats = {}; | ||
for (fn of functions) { | ||
if (orig[fn] != null) { stats[fn] = 0; } | ||
if (orig[fn] != null) { | ||
stats[fn] = 0; | ||
} | ||
} | ||
const collect = (fn) => (...args) => { | ||
const collect = fn => (...args) => { | ||
stats[fn]++; | ||
@@ -338,3 +430,5 @@ return orig[fn].apply(null, args); | ||
for (fn of functions) { | ||
if (orig[fn] != null) { type[fn] = collect(fn); } | ||
if (orig[fn] != null) { | ||
type[fn] = collect(fn); | ||
} | ||
} | ||
@@ -346,42 +440,2 @@ | ||
// Run some iterations of the random op tester. Requires a random op generator for the type. | ||
module.exports = function(type, genRandomOp, iterations) { | ||
if (iterations == null) { iterations = 2000; } | ||
assert.ok(type.transform); | ||
const [stats, restore] = collectStats(type); | ||
console.error(` Running ${iterations} randomized tests for type ${type.name}...`); | ||
if (seed != null) { console.error(` (seed: ${seed})`); } | ||
const warnUnless = (fn) => { | ||
if (type[fn] == null) { | ||
console.error(`NOTE: Not running ${fn} tests because ${type.name} does not have ${fn}() defined`); | ||
} | ||
}; | ||
warnUnless('invert'); | ||
warnUnless('compose'); | ||
let doc = type.create(); | ||
console.time('randomizer'); | ||
const iterationsPerPct = iterations / 100; | ||
for (let n = 0, end = iterations, asc = 0 <= end; asc ? n <= end : n >= end; asc ? n++ : n--) { | ||
if ((n % (iterationsPerPct * 2)) === 0) { | ||
process.stdout.write(((n % (iterationsPerPct * 10)) === 0 ? `${n / iterationsPerPct}` : '.')); | ||
} | ||
// p('ITERATION', n) | ||
doc = testRandomOp(type, genRandomOp, doc); | ||
} | ||
console.log(); | ||
console.timeEnd('randomizer'); | ||
console.log("Performed:"); | ||
for (let fn in stats) { | ||
const number = stats[fn]; console.log(`\t${fn}s: ${number}`); | ||
} | ||
return restore(); | ||
}; | ||
Object.assign(module.exports, exports); | ||
; |
@@ -0,1 +1,10 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.rand = rand; | ||
exports.rand_real = rand_real; | ||
exports.seed = seed; | ||
exports.seed_array = seed_array; | ||
// copied from the npm module 'mersenne', may 2011 | ||
@@ -55,4 +64,3 @@ // | ||
function MersenneTwister19937() | ||
{ | ||
function MersenneTwister19937() { | ||
/* Period parameters */ | ||
@@ -64,13 +72,13 @@ //c//#define N 624 | ||
//c//#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ | ||
N = 624; | ||
M = 397; | ||
MATRIX_A = 0x9908b0df; /* constant vector a */ | ||
UPPER_MASK = 0x80000000; /* most significant w-r bits */ | ||
LOWER_MASK = 0x7fffffff; /* least significant r bits */ | ||
var N = 624; | ||
var M = 397; | ||
var MATRIX_A = 0x9908b0df; /* constant vector a */ | ||
var UPPER_MASK = 0x80000000; /* most significant w-r bits */ | ||
var LOWER_MASK = 0x7fffffff; /* least significant r bits */ | ||
//c//static unsigned long mt[N]; /* the array for the state vector */ | ||
//c//static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ | ||
var mt = new Array(N); /* the array for the state vector */ | ||
var mti = N+1; /* mti==N+1 means mt[N] is not initialized */ | ||
var mt = new Array(N); /* the array for the state vector */ | ||
var mti = N + 1; /* mti==N+1 means mt[N] is not initialized */ | ||
function unsigned32 (n1) // returns a 32-bits unsiged integer from an operand to which applied a bit operator. | ||
function unsigned32(n1) // returns a 32-bits unsiged integer from an operand to which applied a bit operator. | ||
{ | ||
@@ -80,17 +88,17 @@ return n1 < 0 ? (n1 ^ UPPER_MASK) + UPPER_MASK : n1; | ||
function subtraction32 (n1, n2) // emulates lowerflow of a c 32-bits unsiged integer variable, instead of the operator -. these both arguments must be non-negative integers expressible using unsigned 32 bits. | ||
function subtraction32(n1, n2) // emulates lowerflow of a c 32-bits unsiged integer variable, instead of the operator -. these both arguments must be non-negative integers expressible using unsigned 32 bits. | ||
{ | ||
return n1 < n2 ? unsigned32((0x100000000 - (n2 - n1)) & 0xffffffff) : n1 - n2; | ||
return n1 < n2 ? unsigned32(0x100000000 - (n2 - n1) & 0xffffffff) : n1 - n2; | ||
} | ||
function addition32 (n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator +. these both arguments must be non-negative integers expressible using unsigned 32 bits. | ||
function addition32(n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator +. these both arguments must be non-negative integers expressible using unsigned 32 bits. | ||
{ | ||
return unsigned32((n1 + n2) & 0xffffffff) | ||
return unsigned32(n1 + n2 & 0xffffffff); | ||
} | ||
function multiplication32 (n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator *. these both arguments must be non-negative integers expressible using unsigned 32 bits. | ||
function multiplication32(n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator *. these both arguments must be non-negative integers expressible using unsigned 32 bits. | ||
{ | ||
var sum = 0; | ||
for (var i = 0; i < 32; ++i){ | ||
if ((n1 >>> i) & 0x1){ | ||
for (var i = 0; i < 32; ++i) { | ||
if (n1 >>> i & 0x1) { | ||
sum = addition32(sum, unsigned32(n2 << i)); | ||
@@ -104,10 +112,9 @@ } | ||
//c//void init_genrand(unsigned long s) | ||
this.init_genrand = function (s) | ||
{ | ||
this.init_genrand = function (s) { | ||
//c//mt[0]= s & 0xffffffff; | ||
mt[0]= unsigned32(s & 0xffffffff); | ||
for (mti=1; mti<N; mti++) { | ||
mt[mti] = | ||
mt[0] = unsigned32(s & 0xffffffff); | ||
for (mti = 1; mti < N; mti++) { | ||
mt[mti] = | ||
//c//(1812433253 * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); | ||
addition32(multiplication32(1812433253, unsigned32(mt[mti-1] ^ (mt[mti-1] >>> 30))), mti); | ||
addition32(multiplication32(1812433253, unsigned32(mt[mti - 1] ^ mt[mti - 1] >>> 30)), mti); | ||
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ | ||
@@ -121,3 +128,3 @@ /* In the previous versions, MSBs of the seed affect */ | ||
} | ||
} | ||
}; | ||
@@ -129,4 +136,3 @@ /* initialize by an array with array-length */ | ||
//c//void init_by_array(unsigned long init_key[], int key_length) | ||
this.init_by_array = function (init_key, key_length) | ||
{ | ||
this.init_by_array = function (init_key, key_length) { | ||
//c//int i, j, k; | ||
@@ -136,34 +142,37 @@ var i, j, k; | ||
this.init_genrand(19650218); | ||
i=1; j=0; | ||
k = (N>key_length ? N : key_length); | ||
i = 1;j = 0; | ||
k = N > key_length ? N : key_length; | ||
for (; k; k--) { | ||
//c//mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525)) | ||
//c// + init_key[j] + j; /* non linear */ | ||
mt[i] = addition32(addition32(unsigned32(mt[i] ^ multiplication32(unsigned32(mt[i-1] ^ (mt[i-1] >>> 30)), 1664525)), init_key[j]), j); | ||
mt[i] = | ||
mt[i] = addition32(addition32(unsigned32(mt[i] ^ multiplication32(unsigned32(mt[i - 1] ^ mt[i - 1] >>> 30), 1664525)), init_key[j]), j); | ||
mt[i] = | ||
//c//mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */ | ||
unsigned32(mt[i] & 0xffffffff); | ||
i++; j++; | ||
if (i>=N) { mt[0] = mt[N-1]; i=1; } | ||
if (j>=key_length) j=0; | ||
i++;j++; | ||
if (i >= N) { | ||
mt[0] = mt[N - 1];i = 1; | ||
} | ||
if (j >= key_length) j = 0; | ||
} | ||
for (k=N-1; k; k--) { | ||
for (k = N - 1; k; k--) { | ||
//c//mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941)) | ||
//c//- i; /* non linear */ | ||
mt[i] = subtraction32(unsigned32((dbg=mt[i]) ^ multiplication32(unsigned32(mt[i-1] ^ (mt[i-1] >>> 30)), 1566083941)), i); | ||
mt[i] = subtraction32(unsigned32((dbg = mt[i]) ^ multiplication32(unsigned32(mt[i - 1] ^ mt[i - 1] >>> 30), 1566083941)), i); | ||
//c//mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */ | ||
mt[i] = unsigned32(mt[i] & 0xffffffff); | ||
i++; | ||
if (i>=N) { mt[0] = mt[N-1]; i=1; } | ||
if (i >= N) { | ||
mt[0] = mt[N - 1];i = 1; | ||
} | ||
} | ||
mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ | ||
} | ||
}; | ||
/* moved outside of genrand_int32() by jwatte 2010-11-17; generate less garbage */ | ||
var mag01 = [0x0, MATRIX_A]; | ||
/* moved outside of genrand_int32() by jwatte 2010-11-17; generate less garbage */ | ||
var mag01 = [0x0, MATRIX_A]; | ||
/* generates a random number on [0,0xffffffff]-interval */ | ||
//c//unsigned long genrand_int32(void) | ||
this.genrand_int32 = function () | ||
{ | ||
this.genrand_int32 = function () { | ||
//c//unsigned long y; | ||
@@ -174,26 +183,27 @@ //c//static unsigned long mag01[2]={0x0UL, MATRIX_A}; | ||
if (mti >= N) { /* generate N words at one time */ | ||
if (mti >= N) { | ||
/* generate N words at one time */ | ||
//c//int kk; | ||
var kk; | ||
if (mti == N+1) /* if init_genrand() has not been called, */ | ||
if (mti == N + 1) /* if init_genrand() has not been called, */ | ||
//c//init_genrand(5489); /* a default initial seed is used */ | ||
this.init_genrand(5489); /* a default initial seed is used */ | ||
for (kk=0;kk<N-M;kk++) { | ||
for (kk = 0; kk < N - M; kk++) { | ||
//c//y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); | ||
//c//mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1]; | ||
y = unsigned32((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK)); | ||
mt[kk] = unsigned32(mt[kk+M] ^ (y >>> 1) ^ mag01[y & 0x1]); | ||
y = unsigned32(mt[kk] & UPPER_MASK | mt[kk + 1] & LOWER_MASK); | ||
mt[kk] = unsigned32(mt[kk + M] ^ y >>> 1 ^ mag01[y & 0x1]); | ||
} | ||
for (;kk<N-1;kk++) { | ||
for (; kk < N - 1; kk++) { | ||
//c//y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); | ||
//c//mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1]; | ||
y = unsigned32((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK)); | ||
mt[kk] = unsigned32(mt[kk+(M-N)] ^ (y >>> 1) ^ mag01[y & 0x1]); | ||
y = unsigned32(mt[kk] & UPPER_MASK | mt[kk + 1] & LOWER_MASK); | ||
mt[kk] = unsigned32(mt[kk + (M - N)] ^ y >>> 1 ^ mag01[y & 0x1]); | ||
} | ||
//c//y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); | ||
//c//mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; | ||
y = unsigned32((mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK)); | ||
mt[N-1] = unsigned32(mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1]); | ||
y = unsigned32(mt[N - 1] & UPPER_MASK | mt[0] & LOWER_MASK); | ||
mt[N - 1] = unsigned32(mt[M - 1] ^ y >>> 1 ^ mag01[y & 0x1]); | ||
mti = 0; | ||
@@ -209,53 +219,49 @@ } | ||
//c//y ^= (y >> 18); | ||
y = unsigned32(y ^ (y >>> 11)); | ||
y = unsigned32(y ^ ((y << 7) & 0x9d2c5680)); | ||
y = unsigned32(y ^ ((y << 15) & 0xefc60000)); | ||
y = unsigned32(y ^ (y >>> 18)); | ||
y = unsigned32(y ^ y >>> 11); | ||
y = unsigned32(y ^ y << 7 & 0x9d2c5680); | ||
y = unsigned32(y ^ y << 15 & 0xefc60000); | ||
y = unsigned32(y ^ y >>> 18); | ||
return y; | ||
} | ||
}; | ||
/* generates a random number on [0,0x7fffffff]-interval */ | ||
//c//long genrand_int31(void) | ||
this.genrand_int31 = function () | ||
{ | ||
this.genrand_int31 = function () { | ||
//c//return (genrand_int32()>>1); | ||
return (this.genrand_int32()>>>1); | ||
} | ||
return this.genrand_int32() >>> 1; | ||
}; | ||
/* generates a random number on [0,1]-real-interval */ | ||
//c//double genrand_real1(void) | ||
this.genrand_real1 = function () | ||
{ | ||
this.genrand_real1 = function () { | ||
//c//return genrand_int32()*(1.0/4294967295.0); | ||
return this.genrand_int32()*(1.0/4294967295.0); | ||
return this.genrand_int32() * (1.0 / 4294967295.0); | ||
/* divided by 2^32-1 */ | ||
} | ||
}; | ||
/* generates a random number on [0,1)-real-interval */ | ||
//c//double genrand_real2(void) | ||
this.genrand_real2 = function () | ||
{ | ||
this.genrand_real2 = function () { | ||
//c//return genrand_int32()*(1.0/4294967296.0); | ||
return this.genrand_int32()*(1.0/4294967296.0); | ||
return this.genrand_int32() * (1.0 / 4294967296.0); | ||
/* divided by 2^32 */ | ||
} | ||
}; | ||
/* generates a random number on (0,1)-real-interval */ | ||
//c//double genrand_real3(void) | ||
this.genrand_real3 = function () | ||
{ | ||
this.genrand_real3 = function () { | ||
//c//return ((genrand_int32()) + 0.5)*(1.0/4294967296.0); | ||
return ((this.genrand_int32()) + 0.5)*(1.0/4294967296.0); | ||
return (this.genrand_int32() + 0.5) * (1.0 / 4294967296.0); | ||
/* divided by 2^32 */ | ||
} | ||
}; | ||
/* generates a random number on [0,1) with 53-bit resolution*/ | ||
//c//double genrand_res53(void) | ||
this.genrand_res53 = function () | ||
{ | ||
this.genrand_res53 = function () { | ||
//c//unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; | ||
var a=this.genrand_int32()>>>5, b=this.genrand_int32()>>>6; | ||
return(a*67108864.0+b)*(1.0/9007199254740992.0); | ||
} | ||
var a = this.genrand_int32() >>> 5, | ||
b = this.genrand_int32() >>> 6; | ||
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); | ||
}; | ||
/* These real versions are due to Isaku Wada, 2002/01/09 added */ | ||
@@ -270,29 +276,25 @@ } | ||
// Export a simplified function to generate random numbers | ||
var gen = new MersenneTwister19937; | ||
gen.init_genrand((new Date).getTime() % 1000000000); | ||
exports.rand = function(N) { | ||
if (!N) | ||
{ | ||
N = 32768; | ||
} | ||
return Math.floor(gen.genrand_real2() * N); | ||
var gen = new MersenneTwister19937(); | ||
gen.init_genrand(new Date().getTime() % 1000000000); | ||
function rand(N) { | ||
if (!N) { | ||
N = 32768; | ||
} | ||
return Math.floor(gen.genrand_real2() * N); | ||
} | ||
exports.rand_real = function () { | ||
return gen.genrand_real2() | ||
function rand_real() { | ||
return gen.genrand_real2(); | ||
} | ||
exports.seed = function(S) { | ||
if (typeof(S) != 'number') | ||
{ | ||
throw new Error("seed(S) must take numeric argument; is " + typeof(S)); | ||
} | ||
gen.init_genrand(S); | ||
function seed(S) { | ||
if (typeof S != 'number') { | ||
throw new Error("seed(S) must take numeric argument; is " + typeof S); | ||
} | ||
gen.init_genrand(S); | ||
} | ||
exports.seed_array = function(A) { | ||
if (typeof(A) != 'object') | ||
{ | ||
throw new Error("seed_array(A) must take array of numbers; is " + typeof(A)); | ||
} | ||
gen.init_by_array(A); | ||
} | ||
function seed_array(A) { | ||
if (typeof A != 'object') { | ||
throw new Error("seed_array(A) must take array of numbers; is " + typeof A); | ||
} | ||
gen.init_by_array(A); | ||
} |
{ | ||
"name": "@thomsbg/ot-fuzzer", | ||
"version": "2.0.0", | ||
"version": "2.0.1", | ||
"description": "Fuzzer for operational transformation data types", | ||
"main": "lib/index.js", | ||
"module": "src/index.js", | ||
"scripts": { | ||
"test": "mocha test" | ||
"test": "mocha test", | ||
"prepare": "babel -d lib src" | ||
}, | ||
@@ -27,4 +29,12 @@ "repository": { | ||
"devDependencies": { | ||
"babel-cli": "^6.26.0", | ||
"babel-preset-env": "^1.6.1", | ||
"babel-register": "^6.26.0", | ||
"mocha": "^4.0.1" | ||
}, | ||
"babel": { | ||
"presets": [ | ||
["env", { "targets": { "node": "current" } }] | ||
] | ||
} | ||
} |
@@ -93,8 +93,3 @@ # The OT Fuzzer | ||
The code is in coffeescript for purely historical reasons. I'd love to move it | ||
to javascript - I'm just strapped for time. I'd welcome a pull request if | ||
anyone is keen to help. (Please start with the coffeescript compiled output if | ||
so). | ||
There's also no unit tests - and there really should be. This code is | ||
There's no unit tests - and there really should be. This code is | ||
routinely tested by actually running it against things. But it could use some | ||
@@ -101,0 +96,0 @@ simple tests of its own to make sure it actually catches obvious bugs in a |
@@ -1,6 +0,1 @@ | ||
/* | ||
* decaffeinate suggestions: | ||
* DS102: Remove unnecessary code created because of implicit returns | ||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md | ||
*/ | ||
// This is a simple test for the fuzzer, using a trivial OT type. The type | ||
@@ -10,3 +5,3 @@ // is correct - we should add tests where types are not correct get caught by | ||
const fuzzer = require('../lib'); | ||
import fuzzer from '../src'; | ||
@@ -36,8 +31,7 @@ // Each op is [expectedSnapshot, increment]. | ||
describe('type count', () => | ||
describe('type count', () => { | ||
it('should pass the randomizer tests', function() { | ||
this.slow(200); | ||
return fuzzer(count, genOp); | ||
}) | ||
); | ||
fuzzer(count, genOp); | ||
}); | ||
}); |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
53725
9
1190
4
123
2
1