Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
eisenivan committed Jun 5, 2019
2 parents db55c6a + 934fcea commit 9ffdeff
Show file tree
Hide file tree
Showing 37 changed files with 11,656 additions and 7,806 deletions.
2 changes: 1 addition & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"presets": [
["env", {
["@babel/preset-env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
}
Expand Down
5 changes: 4 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"extends": "airbnb",
"parser": "babel-eslint"
"parser": "babel-eslint",
"env": {
"jest": true
}
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,6 @@ settings.json

lib
dist

# stryker
reports/
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Regent: A JavaScript Rule Engine

![regent logo](https://northwesternmutual.github.io/regent/regent-logo-small.png)

Regent provides a lightweight framework aimed at helping you organize your application’s business logic by separating the “how” from the “why”. At the lowest level, Regent logic is written in tiny, single responsibility rules that are both self-documenting and human readable.

## Installation
Expand Down
15,736 changes: 9,834 additions & 5,902 deletions package-lock.json

Large diffs are not rendered by default.

33 changes: 20 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
"description": "Javascript logic framework",
"main": "lib/regent.js",
"scripts": {
"test": "tape -r babel-register src/**/*spec.js src/*spec.js | tap-difflet -p",
"test-watch": "tape-watch src/**/*spec.js src/*spec.js -p 'tap-summary' -c -r babel-register",
"test": "jest",
"test-watch": "jest --watchAll",
"build": "webpack --env dev && webpack --env build && npm run test",
"lint": "eslint './src/**/*.js'",
"prepublish": "npm run build",
"test-coverage": "nyc --check-coverage --statements 100 --lines 100 --functions 100 --branches 100 --per-file npm test",
"test-coverage": "jest --coverage",
"stryker": "stryker run",
"perf": "node ./performance/regent-find-perf.js"
},
"pre-push": [
Expand All @@ -34,8 +35,13 @@
},
"homepage": "https://github.com/northwesternmutual/regent/blob/master/README.md",
"devDependencies": {
"@babel/preset-env": "^7.4.3",
"@stryker-mutator/core": "^1.2.0",
"@stryker-mutator/html-reporter": "^1.2.0",
"@stryker-mutator/javascript-mutator": "^1.2.0",
"@stryker-mutator/jest-runner": "^1.2.0",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-core": "^7.0.0-0",
"babel-eslint": "^8.1.2",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
Expand All @@ -48,12 +54,8 @@
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-react": "^7.5.1",
"nyc": "^14.1.1",
"jest": "^24.7.1",
"pre-push": "^0.1.1",
"tap-difflet": "^0.7.0",
"tap-summary": "^4.0.0",
"tape": "^4.8.0",
"tape-watch": "^2.3.0",
"webpack": "^3.10.0"
},
"dependencies": {
Expand All @@ -68,9 +70,14 @@
"lodash.set": "^4.3.2",
"lodash.some": "^4.6.0"
},
"nyc": {
"exclude": [
"**/*spec.js"
]
"jest": {
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 100,
"lines": 100,
"statements": 100
}
}
}
}
82 changes: 40 additions & 42 deletions src/fn.spec.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,49 @@
import test from 'tape';
import FN from './fn';

test('FN should be a function', (assert) => {
assert.equal(typeof FN, 'function');
assert.end();
});
describe('FN', () => {
it('FN should be a function', () => {
expect(typeof FN).toEqual('function');
});

test('FN test api: calling equals', (assert) => {
const left = 'hello';
const right = 'hello';
const actual = FN('equals')(left, right);
const expected = true;
assert.equal(actual, expected);
assert.end();
});
it('FN test api: calling equals', () => {
const left = 'hello';
const right = 'hello';
const actual = FN('equals')(left, right);
const expected = true;
expect(actual).toEqual(expected);
});

test('FN test api: calling !equals', (assert) => {
const left = 'hello';
const right = 'hello';
const actual = FN('!equals')(left, right);
const expected = false;
assert.equal(actual, expected);
assert.end();
});
it('FN test api: calling !equals', () => {
const left = 'hello';
const right = 'hello';
const actual = FN('!equals')(left, right);
const expected = false;
expect(actual).toEqual(expected);
});

test('FN should accept a custom eval function', (assert) => {
const custom = {
equalsSquirm: left => left === 'squirm',
};
let left = 'squirm';
let actual = FN('equalsSquirm', custom)(left);
let expected = true;
assert.equal(actual, expected);
it('FN should accept a custom eval function', () => {
const custom = {
equalsSquirm: left => left === 'squirm',
};
let left = 'squirm';
let actual = FN('equalsSquirm', custom)(left);
let expected = true;
expect(actual).toEqual(expected);

left = 'notsquirm';
actual = FN('equalsSquirm', custom)(left);
expected = false;
assert.equal(actual, expected, 'custom FN should return false if it is false');
left = 'notsquirm';
actual = FN('equalsSquirm', custom)(left);
expected = false;
expect(actual).toEqual(expected);

left = 'squirm';
actual = FN('!equalsSquirm', custom)(left); /* ? */
expected = false;
assert.equal(actual, expected, 'custom FN should accept the ! param to invert the response');
assert.end();
});
left = 'squirm';
actual = FN('!equalsSquirm', custom)(left);
expected = false;
expect(actual).toEqual(expected);
});

test('FN should catch and console.log if there is an error', (assert) => {
assert.doesNotThrow(() => FN()(), 'Does not throw if called with nothing');
assert.end();
it('should log if there is an error', () => {
global.console = { log: jest.fn() };
FN('nah')('left', 'right'); // function does not exist
expect(console.log).toBeCalled(); // eslint-disable-line
});
});
4 changes: 2 additions & 2 deletions src/functions/date-after-inclusive.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export default (left, right) => {
if (!left || !right) {
throw new Error('Expecting a date as the left argument and a date to compare.');
throw new Error('date-after-inclusive: Left and right are both required for the date-after-inclusive predicate');
}
const leftDate = Date.parse(left);
const rightDate = Date.parse(right);
[leftDate, rightDate].forEach((arg) => {
if (Number.isNaN(arg)) {
throw new Error('Expecting right argument to be date formatted string.');
throw new Error('date-after-inclusive: Left and right must both be date formatted strings');
}
});
return (leftDate >= rightDate);
Expand Down
84 changes: 44 additions & 40 deletions src/functions/date-after-inclusive.spec.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,48 @@
import test from 'tape';
import dateAfterInclusive from './date-after-inclusive';

test('dateAfterInclusive should return true if left is greater than the right.', (assert) => {
const examine = '01/02/1975';
const constraint = '01/01/1975';
const expected = true;
const actual = dateAfterInclusive(examine, [constraint]);
assert.equal(actual, expected);
assert.end();
});
test('dateAfterInclusive should return true for equal dates', (assert) => {
const examine = '01/02/1975';
const constraint = '01/02/1975';
const expected = true;
const actual = dateAfterInclusive(examine, [constraint]);
assert.equal(actual, expected);
assert.end();
});
test('dateAfterInclusive should return false for a date greater than the left date.', (assert) => {
const examine = '01/02/1975';
const constraint = '01/03/1975';
const expected = false;
const actual = dateAfterInclusive(examine, [constraint]);
assert.equal(actual, expected);
assert.end();
});
test('dateAfterInclusive should throw an error for invalid arguments.', (assert) => {
const nonDateString = 'not a date';
const number = 3513513155;
const bool = true;
const valid = '01/01/1975';
assert.throws(() => dateAfterInclusive(nonDateString, [valid]), `${nonDateString} should throw an error.`);
assert.throws(() => dateAfterInclusive(number, [valid]), `${number} should throw an error.`);
assert.throws(() => dateAfterInclusive(bool, [valid]), `${bool} should throw an error.`);
assert.end();
});
describe('dateAfterInclusive', () => {
it('dateAfterInclusive should return true if left is greater than the right.', () => {
const examine = '01/02/1975';
const constraint = '01/01/1975';
const expected = true;
const actual = dateAfterInclusive(examine, [constraint]);
expect(actual).toEqual(expected);
});

it('dateAfterInclusive should return true for equal dates', () => {
const examine = '01/02/1975';
const constraint = '01/02/1975';
const expected = true;
const actual = dateAfterInclusive(examine, [constraint]);
expect(actual).toEqual(expected);
});

it('dateAfterInclusive should return false for a date greater than the left date.', () => {
const examine = '01/02/1975';
const constraint = '01/03/1975';
const expected = false;
const actual = dateAfterInclusive(examine, [constraint]);
expect(actual).toEqual(expected);
});

it('dateAfterInclusive should throw an error for invalid arguments.', () => {
const nonDateString = 'not a date';
const number = 3513513155;
const bool = true;
const valid = '01/01/1975';
expect(() => dateAfterInclusive(nonDateString, [valid])).toThrow('date-after-inclusive: Left and right must both be date formatted strings');
expect(() => dateAfterInclusive(number, [valid])).toThrow('date-after-inclusive: Left and right must both be date formatted strings');
expect(() => dateAfterInclusive(bool, [valid])).toThrow('date-after-inclusive: Left and right must both be date formatted strings');
});

it('dateAfterInclusive should throw if there is no input and/or no params', () => {
const input = undefined;
const args = [''];
expect(() => dateAfterInclusive(input, args)).toThrow('date-after-inclusive: Left and right are both required for the date-after-inclusive predicate');
});

test('dateAfterInclusive should throw if there is no input and/or no params', (assert) => {
const input = undefined;
const args = [''];
assert.throws(() => dateAfterInclusive(input, args));
assert.end();
it('dateAfterInclusive should throw if either left or only right are undefined', () => {
expect(() => dateAfterInclusive(undefined, '01/02/1975')).toThrow('date-after-inclusive: Left and right are both required for the date-after-inclusive predicate');
expect(() => dateAfterInclusive('01/02/1975', undefined)).toThrow('date-after-inclusive: Left and right are both required for the date-after-inclusive predicate');
});
});
4 changes: 2 additions & 2 deletions src/functions/date-before-inclusive.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export default (left, right) => {
if (!left || !right) {
throw new Error('Expecting a date for the left argument and a date to compare.');
throw new Error('date-before-inclusive: Left and right are both required for the date-before-inclusive predicate');
}
const leftDate = Date.parse(left);
const rightDate = Date.parse(right);
[leftDate, rightDate].forEach((arg) => {
if (Number.isNaN(arg)) {
throw new Error('Expecting the right argument to be date formatted string.');
throw new Error('date-before-inclusive: Left and right must both be date formatted strings');
}
});
return (leftDate <= rightDate);
Expand Down
76 changes: 40 additions & 36 deletions src/functions/date-before-inclusive.spec.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
import test from 'tape';
import dateBeforeInclusive from './date-before-inclusive';

test('dateBeforeInclusive should return true if left is less than the constraint.', (assert) => {
const examine = '01/01/1975';
const constraint = '01/02/1975';
const expected = true;
const actual = dateBeforeInclusive(examine, constraint);
assert.equal(actual, expected);
assert.end();
});
test('dateBeforeInclusive should return true for equal dates', (assert) => {
const examine = '01/02/1975';
const constraint = '01/02/1975';
const expected = true;
const actual = dateBeforeInclusive(examine, constraint);
assert.equal(actual, expected);
assert.end();
});
test('dateBeforeInclusive should return false for a date greater than the left date.', (assert) => {
const examine = '01/02/1975';
const constraint = '01/01/1975';
const expected = false;
const actual = dateBeforeInclusive(examine, constraint);
assert.equal(actual, expected);
assert.end();
});
test('dateBeforeInclusive should throw an error for invalid arguments.', (assert) => {
const nonDateString = 'not a date';
const number = 3513513155;
const bool = true;
const valid = '01/01/1975';
assert.throws(() => dateBeforeInclusive(nonDateString, valid), `${nonDateString} should throw an error. Case 1`);
assert.throws(() => dateBeforeInclusive(number, valid), `${number} should throw an error. Case 2`);
assert.throws(() => dateBeforeInclusive(bool, valid), `${bool} should throw an error. Case 3`);
assert.throws(() => dateBeforeInclusive(undefined, valid), 'Should throw an error. Case 4');
assert.throws(() => dateBeforeInclusive(valid, undefined), 'Should throw an error. Case 5');
assert.end();
describe('dateBeforeInclusive', () => {
it('dateBeforeInclusive should return true if left is less than the constraint.', () => {
const examine = '01/01/1975';
const constraint = '01/02/1975';
const expected = true;
const actual = dateBeforeInclusive(examine, constraint);
expect(actual).toEqual(expected);
});
it('dateBeforeInclusive should return true for equal dates', () => {
const examine = '01/02/1975';
const constraint = '01/02/1975';
const expected = true;
const actual = dateBeforeInclusive(examine, constraint);
expect(actual).toEqual(expected);
});
it('dateBeforeInclusive should return false for a date greater than the left date.', () => {
const examine = '01/02/1975';
const constraint = '01/01/1975';
const expected = false;
const actual = dateBeforeInclusive(examine, constraint);
expect(actual).toEqual(expected);
});
it('dateBeforeInclusive should throw an error for invalid arguments.', () => {
const nonDateString = 'not a date';
const number = 3513513155;
const bool = true;
const valid = '01/01/1975';
expect(() => dateBeforeInclusive(nonDateString, valid)).toThrow('date-before-inclusive: Left and right must both be date formatted strings');
expect(() => dateBeforeInclusive(number, valid)).toThrow('date-before-inclusive: Left and right must both be date formatted strings');
expect(() => dateBeforeInclusive(bool, valid)).toThrow('date-before-inclusive: Left and right must both be date formatted strings');
expect(() => dateBeforeInclusive(undefined, valid)).toThrow('date-before-inclusive: Left and right are both required for the date-before-inclusive predicate');
expect(() => dateBeforeInclusive(valid, undefined)).toThrow('date-before-inclusive: Left and right are both required for the date-before-inclusive predicate');
});

it('dateBeforeInclusive should throw if there is no input and/or no params', () => {
const input = undefined;
const args = [''];
expect(() => dateBeforeInclusive(input, args)).toThrow('date-before-inclusive: Left and right are both required for the date-before-inclusive predicate');
});
});

Loading

0 comments on commit 9ffdeff

Please sign in to comment.