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

ESM version #13

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
node_modules
package-lock.json
.DS_Store
.DS_Store
.nyc_output
pnpm-lock.yaml
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ console.log(value);
You can customize the [Pseudorandom number generator](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) which is `Math.random` by default.

```javascript
const n = h.value({choices: ['white', 'yellow'], prng: <custom prng>})
const n = h.value({choices: ['white', 'yellow'], prng: <custom prng>})
```

## Basic types
Expand Down Expand Up @@ -351,7 +351,7 @@ Example of use
const refA = h.reference(h.number(0, 1));
const refB = h.reference(h.number(0, 1));

const addHasard = h.fn((a, b) =&gt; {
const addHasard = h.fn((a, b) => {
return a + b;
});

Expand Down
12 changes: 6 additions & 6 deletions examples/random-object-generator.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
const h = require('..');
import h from '../index.js';

const randomValue = h.value();

const randomInteger = h.integer({type: 'poisson', lambda: 4});

const randomString = h.string({
size: h.add(randomInteger, 5),
value: h.value('abcdefghijklmnopkrstuvw'.split(''))
value: h.value('abcdefghijklmnopkrstuvw'.split('')),
});

const randomNumber = h.number([0, 100]);

const randomKeys = h.array({
size: randomInteger,
value: randomString
value: randomString,
});

const randomObject = h.object(
randomKeys,
randomValue
randomValue,
);

randomValue.set({
choices: [
randomString,
randomObject,
randomNumber,
randomInteger
]
randomInteger,
],
});

console.log(JSON.stringify(randomObject.run(1), null, 2));
24 changes: 8 additions & 16 deletions examples/random-usa-users.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const h = require('..');
import h from '../index.js';

const givenNames = ['Veronica',
'Mercedes',
Expand Down Expand Up @@ -252,7 +252,7 @@ const streets = [
' Briarwood Drive',
' 2nd Avenue',
' Park Place',
' Taylor Street'
' Taylor Street',
];

const cityState = ['Warner, NH',
Expand Down Expand Up @@ -315,18 +315,10 @@ const domainName = h.reference(h.value(domains));
const location = h.reference(h.value(cityState));
const street = h.reference(h.value(streets));

const eMail = h.fn((a, b, c) => {
return a + '.' + b + '@invalid' + c;
});
const preferredName = h.fn((a, b) => {
return a + '_' + b;
});
const locality = h.fn(a => {
return (a.split(',')[0].trim());
});
const region = h.fn(a => {
return (a.split(',')[1].trim());
});
const eMail = h.fn((a, b, c) => a + '.' + b + '@invalid' + c);
const preferredName = h.fn((a, b) => a + '_' + b);
const locality = h.fn(a => (a.split(',')[0].trim()));
const region = h.fn(a => (a.split(',')[1].trim()));

// User object
/* eslint camelcase: ["error", {properties: "never"}] */
Expand All @@ -335,9 +327,9 @@ const user = h.object({
family_name: lastName,
email: eMail(firstName, lastName, domainName),
preferred_username: preferredName(firstName, lastName),
street: h.add(h.integer(100, 65535), street),
street: h.add(h.integer(100, 65_535), street),
locality: locality(location),
region: region(location)
region: region(location),
});

// Generate 10 random users and print to console
Expand Down
111 changes: 89 additions & 22 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,113 @@
const Abstract = require('./lib/hasard/abstract');
const Function = require('./lib/hasard/function');
const operators = require('./lib/operators');
import AbstractHasard from './lib/hasard/abstract.js';
import operators from './lib/operators.js';
import HasardInteger from './lib/hasard/integer.js';
import HasardValue from './lib/hasard/value.js';
import HasardArray from './lib/hasard/array.js';
import HasardObject from './lib/hasard/object.js';
import HasardNumber from './lib/hasard/number.js';
import HasardMatrix from './lib/hasard/matrix.js';
import HasardString from './lib/hasard/string.js';
import HasardBoolean from './lib/hasard/boolean.js';
import HasardReference from './lib/hasard/reference.js';
import HasardFunction from './lib/hasard/function.js';

const cstrs = {
Integer: require('./lib/hasard/integer'),
Value: require('./lib/hasard/value'),
Array: require('./lib/hasard/array'),
Object: require('./lib/hasard/object'),
Number: require('./lib/hasard/number'),
Matrix: require('./lib/hasard/matrix'),
String: require('./lib/hasard/string'),
Boolean: require('./lib/hasard/boolean'),
Reference: require('./lib/hasard/reference'),
Function
Integer: HasardInteger,
Value: HasardValue,
Array: HasardArray,
Object: HasardObject,
Number: HasardNumber,
Matrix: HasardMatrix,
String: HasardString,
Boolean: HasardBoolean,
Reference: HasardReference,
Function: HasardFunction,
};

/**
* Lowercaed version of cstrs
*/
const shortcuts = {};
Object.keys(cstrs).forEach(key => {
for (const key of Object.keys(cstrs)) {
shortcuts[key.toLowerCase()] = cstrs[key].build.bind(cstrs[key], this);
});
}

const helpers = {
isHasard: Abstract.isHasard,
isHasard: AbstractHasard.isHasard,
fn: shortcuts.function,
int: shortcuts.integer,
num: shortcuts.number,
str: shortcuts.string,
ref: shortcuts.reference
ref: shortcuts.reference,
};

const methods = function (hasardContext) {
return Object.assign({}, cstrs, shortcuts, operators(hasardContext), helpers);
// Return Object.assign({}, cstrs, shortcuts, operators(hasardContext), helpers);
return {
...cstrs, ...shortcuts, ...operators(hasardContext), ...helpers,
};
};

class Hasard {
export class Hasard {
constructor(prng = Math.random.bind(Math)) {
this.prng = prng;
const meths = methods(this);
Object.keys(meths).forEach(m => {
for (const m of Object.keys(meths)) {
this[m] = meths[m].bind(this);
});
}
}
}

module.exports = Object.assign(Hasard, methods(null));
const HasardLibrary = {...Hasard, ...methods(null)};

// Exports from operators.js
export const multiply = HasardLibrary.multiply;
export const divide = HasardLibrary.divide;
export const add = HasardLibrary.add;
export const substract = HasardLibrary.substract;
// Can not export symbol 'if'
// export const if = HasardLib.if;
export const round = HasardLibrary.round;
export const ceil = HasardLibrary.ceil;
export const floor = HasardLibrary.floor;
export const concat = HasardLibrary.concat;
export const getProperty = HasardLibrary.getProperty;
// End of exports from operators.js

// exports from helpers
export const isHasard = HasardLibrary.isHasard;
export const fn = HasardLibrary.fn;
export const int = HasardLibrary.int;
export const num = HasardLibrary.num;
export const str = HasardLibrary.str;
export const ref = HasardLibrary.ref;
// End of exports from helpers

// export from cstrs
export const Integer = HasardLibrary.Integer;
export const Value = HasardLibrary.Value;
export const Array = HasardLibrary.Array;
// Export const Object = HasardLib.Object;
export const Number = HasardLibrary.Number;
export const Matrix = HasardLibrary.Matrix;
export const String = HasardLibrary.String;
export const Boolean = HasardLibrary.Boolean;
export const Reference = HasardLibrary.Reference;
export const Function = HasardLibrary.Function;
// End of export from cstrs

// export from lowercased cstrs
export const integer = HasardLibrary.Integer;
export const value = HasardLibrary.Value;
export const array = HasardLibrary.Array;
export const object = HasardLibrary.Object;
export const number = HasardLibrary.Number;
export const matrix = HasardLibrary.Matrix;
export const string = HasardLibrary.String;
export const boolean = HasardLibrary.Boolean;
export const reference = HasardLibrary.Reference;
// Export const function = HasardLib.Function;
// end of export from lowercased cstrs

// export default
export default HasardLibrary;
74 changes: 38 additions & 36 deletions lib/hasard/abstract.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
const HasardReadableStream = require('../helpers/readable-stream.js');
import HasardReadableStream from '../helpers/readable-stream.js';

class AbstractHasard {
constructor(...args) {
constructor(...arguments_) {
this._hasard = true;
if (args.length === 0) {
if (arguments_.length === 0) {
return;
}

this.set(...args);
this.set(...arguments_);
}

set(opts) {
set(options) {
this._set = true;
this._opts = opts;
const all = this.getOpts(opts);
this._opts = options;
const all = this.getOpts(options);
this._unresolved = {};
this._resolved = {};
if (opts && (typeof (opts.prng) === 'function')) {
this._prng = opts.prng.bind(opts);
if (options && (typeof (options.prng) === 'function')) {
this._prng = options.prng.bind(options);
}

this._contextName = opts && opts.contextName;
Object.keys(all).forEach(k => {
this._contextName = options && options.contextName;
for (const k of Object.keys(all)) {
if (AbstractHasard.isHasard(all[k])) {
this._unresolved[k] = all[k];
} else {
this.check(k, all[k]);
this._resolved[k] = all[k];
}
});
}
}

static build(hasardContext, ...args) {
const instance = new this(...args);
static build(hasardContext, ...arguments_) {
const instance = new this(...arguments_);
if (hasardContext && hasardContext.prng) {
hasardContext._prng = hasardContext.prng;
}
Expand All @@ -52,63 +52,65 @@ class AbstractHasard {
return Promise.resolve(this.run(n));
}

stream(number, runOpts) {
stream(number, runOptions) {
return new HasardReadableStream({
hasardInstance: this,
number,
runOpts
runOpts: runOptions,
});
}

resolve(unresolved, runOpts) {
resolve(unresolved, runOptions) {
const ctxt = {};
if (typeof (unresolved) === 'undefined') {
if ((unresolved) === undefined) {
throw (new TypeError('This instance of hasard has not been set properly'));
}

Object.keys(unresolved).forEach(k => {
ctxt[k] = unresolved[k].runOnce(runOpts);
for (const k of Object.keys(unresolved)) {
ctxt[k] = unresolved[k].runOnce(runOptions);
this.check(k, ctxt[k]);
});
}

return ctxt;
}

_runOnce(runOpts) {
const ctxt = Object.assign({}, this.resolve(this._unresolved, runOpts), this._resolved);
_runOnce(runOptions) {
const ctxt = Object.assign({}, this.resolve(this._unresolved, runOptions), this._resolved);

const res = this.generate(ctxt, runOpts);
if (this._contextName && runOpts.refs && runOpts.refs[this._contextName]) {
delete runOpts.refs[this._contextName];
const res = this.generate(ctxt, runOptions);
if (this._contextName && runOptions.refs && runOptions.refs[this._contextName]) {
delete runOptions.refs[this._contextName];
}

return res;
}

run(n, runOpts) {
run(n, runOptions) {
const res = [];
for (let i = 0; i < n; i++) {
res.push(this.runOnce(runOpts));
res.push(this.runOnce(runOptions));
}

return res;
}

runOnce(runOpts = {}) {
return this._runOnce(runOpts);
runOnce(runOptions = {}) {
return this._runOnce(runOptions);
}

generate() {
generate(_ctxt, _runOptions) {
throw (new Error('override me'));
}

getOpts(opts) {
delete opts.prng;
return opts;
getOpts(options) {
delete options.prng;
return options;
}

check() {
// abstract
check(..._values) {
// Do nothing, override me to do sthg
}
}

module.exports = AbstractHasard;
export default AbstractHasard;