Skip to content
This repository has been archived by the owner on Oct 1, 2021. It is now read-only.

Commit

Permalink
Expressions with expr-eval added
Browse files Browse the repository at this point in the history
  • Loading branch information
al66 committed May 25, 2017
1 parent e6d5ecc commit 1d5ce90
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 10 deletions.
59 changes: 58 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ for (let i=0; i< testData.length; i++) {
```

## More Examples
### Initiate and compile in separate steps
```js
// create an instance direct..
let table = new Table(testTable);
Expand All @@ -88,4 +89,60 @@ let table = new Table(testTable);
let table = new Table();
table.compile(testTable);
```

### Formular expressions in input
```js
let testTable = {
description: 'Simple table',
hitPolicy: 'Unique',
input: {
'x': {
description: 'Input x',
type: 'number'
},
'y': {
description: 'Input y',
type: 'number',
default: 2
},
'a': {
description: 'Formula Input',
type: 'expression', // optional
expression: '2 * x + y' // check expr-eval for syntax
}
},
output: {
'z': {},
't': {}
},
rules: {
'First rule': {
'x': '< 5, [20..30]',
'y': '> 6,[30..40]',
'a': '< 15', // uses the calculated value
'z': '7',
't': 'first'
},
'Second rule': {
'x': '> 5',
'a': '> 15',
'z': '2',
't': 'second'
}
}
};
```
### Set default values for input (if value is not provided in data sets)
```js
input: {
'x': {
description: 'Input x',
type: 'number',
default: '0' // 0 must be in quotes
},
'y': {
description: 'Input y',
type: 'number',
default: 2 // with or without quotes
}
}
```
37 changes: 32 additions & 5 deletions lib/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

const compiler = require('checkcond').Compiler;
const check = require('checkcond').Check;

const Parser = require('expr-eval').Parser;
const parser = new Parser();

class Table {
constructor(table) {
Expand All @@ -14,9 +15,24 @@ class Table {
let compiled = [];
let inputs = [];
let outputs = [];
table.calculate = [];
table.defaults = {};

if (table.input) {
Object.keys(table.input).forEach(function(key) {inputs.push(key)});
Object.keys(table.input).forEach(function(key) {
inputs.push(key);
// input parameter calculated based on expressions
if (table.input[key].expression) {
let calc = [];
calc[0] = key;
calc[1] = parser.parse(table.input[key].expression);
table.calculate.push(calc);
};
// default values for input parameter
if (table.input[key].default) {
table.defaults[key] = table.input[key].default;
};
});
};
if (table.output) {
Object.keys(table.output).forEach(function(key) {outputs.push(key)});
Expand All @@ -28,6 +44,7 @@ class Table {
rule.output = [];
rule.desc = desc;

// bild array of input variables with the assigned compiled(!) condition for this rule
let addInput = function(item) {
let input = [];
let condString = table.rules[desc][item];
Expand All @@ -40,10 +57,9 @@ class Table {
}
inputs.forEach(addInput);

// build array of output variables for this rule
let addOutput = function(item) {
let output = [];
output[item] = table.rules[desc][item];
rule.output = output;
rule.output[item] = table.rules[desc][item];
}
outputs.forEach(addOutput);

Expand All @@ -63,6 +79,17 @@ class Table {
let self = this;
let res = data;
let output = {};

// assign default values
Object.keys(this._table.defaults).forEach(function(key) {
if (!data[key]) data[key] = self._table.defaults[key];
});

// calculate expressions
let calcExpr = function(calc) {
data[calc[0]] = calc[1].evaluate(data);
};
this._table.calculate.forEach(calcExpr);

if (this._table.output) {
Object.keys(this._table.output).forEach(function(key) {res[key] = null});
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cond-table",
"version": "0.0.2",
"version": "0.0.3",
"description": "decision table",
"main": "index.js",
"scripts": {
Expand All @@ -12,7 +12,8 @@
"url": "git+https://github.com/al66/cond-table.git"
},
"keywords": [
"rule", "rules",
"rule",
"rules",
"rules-engine",
"decision",
"decision-engine",
Expand All @@ -36,6 +37,7 @@
"test": "test"
},
"dependencies": {
"checkcond": "0.0.5"
"checkcond": "0.0.5",
"expr-eval": "1.0.0"
}
}
68 changes: 67 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ describe('Test table 1', function() {
'y': {
description: 'Input y',
type: 'number',
default: 2
default: '0'
},
'a': {
description: 'Formula Input',
type: 'expression',
expression: '2 * x + y'
}
},
output: {
Expand All @@ -83,10 +88,12 @@ describe('Test table 1', function() {
'First rule': {
'x': '< 5, [20..30]',
'y': '> 6,[30..40]',
'a': '< 15',
'z': '7'
},
'Second rule': {
'x': '> 5',
'a': '> 15',
'z': '2'
}
}
Expand Down Expand Up @@ -176,6 +183,65 @@ describe('Test table 2', function() {
}
});

describe('Multiple output', function() {
let testTable = {
description: 'Simple table',
hitPolicy: 'Unique',
input: {
'x': {
description: 'Input x',
type: 'number'
},
'y': {
description: 'Input y',
type: 'number',
default: 2
},
'a': {
description: 'Formula Input',
type: 'expression',
expression: '2 * x + y'
}
},
output: {
'z': {},
't': {}
},
rules: {
'First rule': {
'x': '< 5, [20..30]',
'y': '> 6,[30..40]',
'a': '< 15',
'z': '7',
't': 'first'
},
'Second rule': {
'x': '> 5',
'a': '> 15',
'z': '2',
't': 'second'
}
}
};
let testData = [
{ 'x': '3', 'y':'2', 'z':null, 't':null},
{ 'x': '3', 'y':'7', 'z':'7', 't':'first'},
{ 'x': '6', 'y':'7', 'z':'2', 't':'second'},
{ 'x': '20', 'y':'37', 'z':'7', 't':'first'},
{ 'x': '6', 'z':'2', 't':'second'}
];

let table = new Table();
table.compile(testTable);
for (let i=0; i< testData.length; i++) {
it('Test data line ' + i, function(done){
let result = table.result(testData[i]);
expect(result.z).to.be.equals(testData[i].z);
expect(result.t).to.be.equals(testData[i].t);
done();
});
}
});

describe('Incomplete Table', function() {
let testTable = {
Expand Down

0 comments on commit 1d5ce90

Please sign in to comment.