es6-fuzz 4.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Readme.md CHANGED
@@ -5,7 +5,6 @@
5
5
  [![npm](https://img.shields.io/npm/dt/es6-fuzz.svg)](https://www.npmjs.com/package/es6-fuzz)
6
6
  [![license](https://img.shields.io/github/license/sebs/es6-fuzz.svg)](https://github.com/sebs/es6-fuzz/blob/master/LICENSE.md)
7
7
  [![GitHub tag](https://img.shields.io/github/tag/sebs/es6-fuzz.svg)](https://github.com/sebs/es6-fuzz)
8
- [![Travis](https://img.shields.io/travis/sebs/es6-fuzz.svg)](https://travis-ci.org/sebs/es6-fuzz)
9
8
  [![GitHub issues](https://img.shields.io/github/issues/sebs/es6-fuzz.svg)](https://github.com/sebs/es6-fuzz/issues)
10
9
 
11
10
  Supported fuzzyfiers
@@ -19,8 +18,8 @@ Supported fuzzyfiers
19
18
  * Triangle
20
19
 
21
20
 
22
- * [api docs](https://github.com/sebs/es6-fuzz)
23
- * [changelog](./docs/changelog.md)
21
+ * [api docs](http://sebs.github.io/es6-fuzz)
22
+ * [changelog](https://github.com/sebs/es6-fuzz/blob/master/docs/CHANGELOG.md)
24
23
 
25
24
  ## Install and Usage
26
25
 
@@ -58,6 +57,61 @@ var res = logic
58
57
 
59
58
  * hot
60
59
 
60
+
61
+ ## Usage with boon-js
62
+
63
+ In order to combine 2 fuzzy functions with boolean logic, there is a compat layer for boon-js which allows the sauge of 'boolean expression language'.
64
+
65
+ Example of a monster biting when its cold and you are close to it:
66
+
67
+
68
+ Heat part:
69
+
70
+ ```js
71
+ var logicHeat = new Logic();
72
+ const optimalTemperature = new Triangle(10, 20, 30);
73
+ const toColdTemperature = new Triangle(0, 10, 15);
74
+ const toHotTemperature = new Triangle(25, 40, 60);
75
+
76
+ logicHeat.init('cold', toColdTemperature)
77
+ logicHeat.or('optimal', optimalTemperature)
78
+ logicHeat.or('hot', toHotTemperature);
79
+ ```
80
+
81
+ Distance Part
82
+
83
+ ```js
84
+
85
+ var logicDistance = new Logic();
86
+ const close = new Triangle(0, 10, 20);
87
+ const far = new Triangle(5, 50, 100);
88
+
89
+ logicDistance.init('close', close)
90
+ logicDistance.or('far', far)
91
+
92
+ ```
93
+
94
+ Now we marry the 2 and use boon js
95
+
96
+ ```js
97
+ const monsterBiteTest = getEvaluator(
98
+ 'heat.cold AND distance.close',
99
+ );
100
+ const resHeat = logicHeat.defuzzify(2, 'heat');
101
+ const resClose = logicDistance.defuzzify(2, 'distance');
102
+
103
+ const jsBoonInput = { ...resHeat.boonJsInputs, ...resClose.boonJsInputs }
104
+
105
+ monsterBiteTest(jsBoonInput)
106
+ // returns true
107
+ ```
108
+
109
+
110
+
111
+
112
+
113
+
114
+
61
115
  ## development
62
116
 
63
117
  **Tests** use mocha and a plugin for traceur
package/docs/CHANGELOG.md CHANGED
@@ -1,6 +1,34 @@
1
+ 2025-06-26
2
+ ==========
3
+
4
+ * 5.0.0
5
+ * (churn): changelog
6
+ * 4.0.4
7
+ * fix: edge cases
8
+ * 4.0.3
9
+ * refactor: cleaned up test structure
10
+ * 4.0.2
11
+ * docs: add a clearer test case for constant
12
+ * fix: [#76](https://github.com/sebs/es6-fuzz/issues/76) sigmoid implementation with weird microoptimizations
13
+ * added a different sigmoid function with easier to understand parameters
14
+
15
+ 2023-01-18
16
+ ==========
17
+
18
+ * test: find the bug with trapezoid special form square
19
+
20
+ 2023-01-17
21
+ ==========
22
+
23
+ * test: more tests for the trapezoid
24
+
1
25
  2022-06-14
2
26
  ==========
3
27
 
28
+ * chore: link docs
29
+ * (churn): changelog
30
+ * 4.0.1
31
+ * fix: update readme
4
32
  * 4.0.0
5
33
  * feature: make the api work with boonJsInputs
6
34
  * feature: add a test for outoput names only to consist of alphabet
@@ -132,21 +160,3 @@
132
160
  * 2.6.0
133
161
  * Added link to api docs
134
162
  * More docs
135
-
136
- 2017-04-04
137
- ==========
138
-
139
- * Added latest es5 export to dist
140
- * (churn): changelog
141
- * 2.5.10
142
- * Added curves
143
- * 2.5.9
144
- * add missing dep
145
- * 2.5.8
146
- * Pages
147
- * 2.5.7
148
- * 2.5.6
149
- * Added docs
150
- * Fix output ght pages
151
- * DOcs
152
- * Ghpages
package/jsdoc.json CHANGED
@@ -18,7 +18,6 @@
18
18
  "includePattern": ".+\\.js(doc)?$",
19
19
  "excludePattern": "(^|\\/|\\\\)_"
20
20
  },
21
- "analytics":{"ua":"UA-85700100-2", "domain":"https://sebs.github.io/es6-fuzz/"},
22
21
  "plugins": [],
23
22
  "templates": {
24
23
  "cleverLinks": true,
@@ -14,6 +14,13 @@ class Grade extends Shape {
14
14
  fuzzify(val) {
15
15
  let result = 0;
16
16
  const x = val;
17
+
18
+ // Handle case where x0 = x1 (vertical grade/step function)
19
+ if (this.x1 === this.x0) {
20
+ if (x < this.x0) return 0;
21
+ return 1; // x >= x0
22
+ }
23
+
17
24
  if (x <= this.x0) {
18
25
  result = 0;
19
26
  } else if (x >= this.x1) {
@@ -16,7 +16,12 @@ class ReverseGrade extends Shape {
16
16
  } else if (x >= this.x1) {
17
17
  result = 0;
18
18
  } else {
19
- result = (-x / (this.x1 - this.x0)) + (this.x1 / (this.x1 - this.x0));
19
+ // Handle case where x0 = x1 (vertical reverse grade)
20
+ if (this.x1 === this.x0) {
21
+ result = 0;
22
+ } else {
23
+ result = (-x / (this.x1 - this.x0)) + (this.x1 / (this.x1 - this.x0));
24
+ }
20
25
  }
21
26
  return result;
22
27
  }
@@ -9,20 +9,26 @@
9
9
  class Sigmoid {
10
10
  /**
11
11
  * Create a Sigmoid Function.
12
- * @param {number} treshhold
13
- * @param {number} slope
12
+ * @param {number} center - The center point of the sigmoid curve (where it outputs 0.5)
13
+ * @param {number} slope - The slope of the sigmoid curve (higher = steeper transition)
14
14
  */
15
- constructor(treshold=0, slope=1) {
16
- this.t = -treshold;
17
- this.s = slope;
15
+ constructor(center=0, slope=1) {
16
+ this.center = center;
17
+ this.slope = slope;
18
18
  }
19
19
  /**
20
20
  * Fuzzify
21
- * @param {number} - Point on X axis
21
+ * @param {number} x - Point on X axis
22
22
  * @return {number} fuzzy output 0..1
23
23
  */
24
24
  fuzzify(x) {
25
- return 1.0 / (1.0 + Math.exp((-x-this.t)/this.s));
25
+ if (this.slope === 0) {
26
+ // When slope is 0, sigmoid becomes a step function
27
+ if (x < this.center) return 0;
28
+ if (x > this.center) return 1;
29
+ return 0.5; // At center point
30
+ }
31
+ return 1.0 / (1.0 + Math.exp(-(x - this.center) / this.slope));
26
32
  }
27
33
  }
28
34
  module.exports = Sigmoid;
@@ -15,6 +15,19 @@ class Trapezoid extends Shape {
15
15
  let result = 0;
16
16
  const x = val;
17
17
 
18
+ // Special case: all points equal (spike at single point)
19
+ if (this.x0 === this.x1 && this.x1 === this.x2 && this.x2 === this.x3) {
20
+ return x === this.x0 ? 1 : 0;
21
+ }
22
+
23
+ // Special case: x0=x1 and x2=x3 (rectangle)
24
+ if (this.x0 === this.x1 && this.x2 === this.x3) {
25
+ if (x < this.x0) return 0;
26
+ if (x >= this.x0 && x <= this.x2) return 1;
27
+ if (x > this.x2) return 0;
28
+ return 0;
29
+ }
30
+
18
31
  if (x <= this.x0) {
19
32
  result = 0;
20
33
  } else if (x >= this.x3) {
@@ -22,9 +35,19 @@ class Trapezoid extends Shape {
22
35
  } else if ((x >= this.x1) && (x <= this.x2)) {
23
36
  result = 1;
24
37
  } else if ((x > this.x0) && (x < this.x1)) {
25
- result = (x / (this.x1 - this.x0)) - (this.x0 / (this.x1 - this.x0));
38
+ // Handle case where x0 = x1 (vertical left edge)
39
+ if (this.x1 === this.x0) {
40
+ result = 1;
41
+ } else {
42
+ result = (x / (this.x1 - this.x0)) - (this.x0 / (this.x1 - this.x0));
43
+ }
26
44
  } else {
27
- result = (-x / (this.x3 - this.x2)) + (this.x3 / (this.x3 - this.x2));
45
+ // Handle case where x2 = x3 (vertical right edge)
46
+ if (this.x3 === this.x2) {
47
+ result = 1;
48
+ } else {
49
+ result = (-x / (this.x3 - this.x2)) + (this.x3 / (this.x3 - this.x2));
50
+ }
28
51
  }
29
52
  return result;
30
53
  }
@@ -13,6 +13,33 @@ class Triangle extends Shape {
13
13
  */
14
14
  fuzzify(x) {
15
15
  let result = 0;
16
+
17
+ // Special case: all points equal (spike at single point)
18
+ if (this.x0 === this.x1 && this.x1 === this.x2) {
19
+ return x === this.x0 ? 1 : 0;
20
+ }
21
+
22
+ // Special case: x0 = x1 (vertical left edge)
23
+ if (this.x0 === this.x1) {
24
+ if (x < this.x0) return 0;
25
+ if (x === this.x0) return 1;
26
+ if (x >= this.x2) return 0;
27
+ if (x < this.x2) {
28
+ return (this.x2 - x) / (this.x2 - this.x1);
29
+ }
30
+ }
31
+
32
+ // Special case: x1 = x2 (vertical right edge)
33
+ if (this.x1 === this.x2) {
34
+ if (x <= this.x0) return 0;
35
+ if (x > this.x0 && x < this.x1) {
36
+ return (x - this.x0) / (this.x1 - this.x0);
37
+ }
38
+ if (x === this.x1) return 1;
39
+ if (x > this.x1) return 0;
40
+ }
41
+
42
+ // Normal triangle
16
43
  if (x <= this.x0) {
17
44
  result = 0;
18
45
  } else if (x >= this.x2) {
package/lib/logic.js CHANGED
@@ -112,8 +112,6 @@ class Logic {
112
112
  }
113
113
  });
114
114
 
115
-
116
-
117
115
  var namePrefix = '';
118
116
  if (!!as && typeof as === 'string') {
119
117
  namePrefix = as + '.';
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "es6-fuzz",
3
3
  "description": "fuzzy logic with and for es6",
4
- "version": "4.0.0",
4
+ "version": "5.0.0",
5
5
  "main": "lib/logic.js",
6
6
  "repository": "git@github.com:sebs/es6-fuzz.git",
7
7
  "homepage": "https://github.com/sebs/es6-fuzz",
8
8
  "scripts": {
9
9
  "changelog": "rm ./docs/CHANGELOG.md && npx changelog https://github.com/sebs/es6-fuzz all > ./docs/CHANGELOG.md && git add . && git commit . -m '(churn): changelog'",
10
- "test": "npx mocha",
11
- "test:watch": "npm test -- -w",
10
+ "test": "node --test",
11
+ "test:watch": "node --test --watch",
12
12
  "addpush": "git add . && git commit . -m 'docs'",
13
13
  "pages": "node ./scripts/publish-gh.js",
14
14
  "docs": "jsdoc -c ./jsdoc.json -t ./node_modules/ink-docstrap/template -R ./Readme.md -u ./docs",
@@ -25,11 +25,11 @@
25
25
  "author": "Sebastian Schürmann",
26
26
  "license": "MIT",
27
27
  "devDependencies": {
28
- "gh-pages": "4.0.0",
28
+ "gh-pages": "6.3.0",
29
29
  "ink-docstrap": "1.3.2",
30
- "jsdoc": "3.6.10"
30
+ "jsdoc": "4.0.4"
31
31
  },
32
32
  "dependencies": {
33
- "boon-js": "2.0.3"
33
+ "boon-js": "2.0.5"
34
34
  }
35
35
  }
@@ -0,0 +1,100 @@
1
+ const { describe, it } = require('node:test');
2
+ const assert = require('assert');
3
+ const Logic = require('../lib/logic');
4
+ const Triangle = require('../lib/curve/triangle');
5
+ const Trapezoid = require('../lib/curve/trapezoid');
6
+ const Grade = require('../lib/curve/grade');
7
+ const getEvaluator = require('boon-js').getEvaluator;
8
+
9
+ const assess = (likelihood, impact) => {
10
+ var logicLikelihood = new Logic();
11
+ const lowLikelihood = new Trapezoid(0, 0, 2, 3);
12
+ const moderateLikelihood = new Trapezoid(2, 3, 7, 8);
13
+ const highLikelihood = new Trapezoid(7, 8, 10, 10);
14
+
15
+ logicLikelihood.init('low', lowLikelihood)
16
+ logicLikelihood.or('moderate', moderateLikelihood)
17
+ logicLikelihood.or('high', highLikelihood);
18
+
19
+ var logicImpact = new Logic();
20
+ const publicImpact = new Trapezoid(0, 0, 1.5, 2.5);
21
+ const internalImpact = new Trapezoid(1.5, 2.5, 4.5, 5.5);
22
+ const confidentialImpact = new Trapezoid(4.5, 5.5, 7.5, 8.5);
23
+ const restrictedImpact = new Trapezoid(7.5, 8.5, 10, 10);
24
+
25
+ logicImpact.init('public', publicImpact)
26
+ logicImpact.or('internal', internalImpact)
27
+ logicImpact.or('confidential', confidentialImpact);
28
+ logicImpact.or('restricted', restrictedImpact);
29
+
30
+ const tests = [];
31
+ // assessment very low
32
+ const securityTest_low_public = getEvaluator('likelihood.low AND impact.public');
33
+ tests.push(securityTest_low_public);
34
+ // assessment low
35
+ const securityTest_low_internal = getEvaluator('likelihood.low AND impact.internal');
36
+ tests.push(securityTest_low_internal);
37
+ // assessment medium
38
+ const securityTest_low_confidential = getEvaluator('likelihood.low AND impact.confidential');
39
+ tests.push(securityTest_low_confidential);
40
+ // assessment high
41
+ const securityTest_low_restricted = getEvaluator('likelihood.low AND impact.restricted');
42
+ tests.push(securityTest_low_restricted);
43
+ // assessment low
44
+ const securityTest_moderate_public = getEvaluator('likelihood.moderate AND impact.public');
45
+ tests.push(securityTest_moderate_public);
46
+ // assessment medium
47
+ const securityTest_moderate_internal = getEvaluator('likelihood.moderate AND impact.internal');
48
+ tests.push(securityTest_moderate_internal);
49
+ // assessment high
50
+ const securityTest_moderate_confidential = getEvaluator('likelihood.moderate AND impact.confidential');
51
+ tests.push(securityTest_moderate_confidential);
52
+ // assessment very high
53
+ const securityTest_moderate_restricted = getEvaluator('likelihood.moderate AND impact.restricted');
54
+ tests.push(securityTest_moderate_restricted);
55
+ // assessment low
56
+ const securityTest_high_public = getEvaluator('likelihood.high AND impact.public');
57
+ tests.push(securityTest_high_public);
58
+ // assessment medium
59
+ const securityTest_high_internal = getEvaluator('likelihood.high AND impact.internal');
60
+ tests.push(securityTest_high_internal);
61
+ // assessment high
62
+ const securityTest_high_confidential = getEvaluator('likelihood.high AND impact.confidential');
63
+ tests.push(securityTest_high_confidential);
64
+ // assessment very high
65
+ const securityTest_high_restricted = getEvaluator('likelihood.high AND impact.restricted');
66
+ tests.push(securityTest_high_restricted);
67
+
68
+ const resLikelihood = logicLikelihood.defuzzify(likelihood, 'likelihood');
69
+ const resImpact = logicImpact.defuzzify(impact, 'impact');
70
+
71
+ const jsBoonInput = { ...resLikelihood.boonJsInputs, ...resImpact.boonJsInputs }
72
+
73
+ const results = [];
74
+ for(let i = 0; i < tests.length; i++){
75
+ results.push( tests[i](jsBoonInput) );
76
+ }
77
+
78
+ if(results[0]) return "very low";
79
+ else if(results[1]) return "low";
80
+ else if(results[2]) return "medium";
81
+ else if(results[3]) return "high";
82
+ else if(results[4]) return "low";
83
+ else if(results[5]) return "medium";
84
+ else if(results[6]) return "high";
85
+ else if(results[7]) return "high";
86
+ else if(results[8]) return "low";
87
+ else if(results[9]) return "medium";
88
+ else if(results[10]) return "high";
89
+ else if(results[11]) return "very high";
90
+ else return "Unknown";
91
+ }
92
+
93
+
94
+ describe('Bug #74 Wrong evaluation at limit of trapezoid', function() {
95
+ it.skip('asses', ()=>{
96
+ const restrictedImpact = new Trapezoid(7.5, 8.5, 10, 10);
97
+ var res = restrictedImpact.fuzzify(10);
98
+ assert.equal(res, 1);
99
+ })
100
+ });
@@ -0,0 +1,15 @@
1
+ const { describe, it } = require('node:test');
2
+ const Constant= require('../../lib/curve/constant');
3
+ const assert = require('assert');
4
+
5
+ describe('Constant', function() {
6
+ it('is a function', function() {
7
+ assert.equal(typeof Constant, 'function');
8
+ });
9
+ it('same value at 5 and 100', function() {
10
+ var shape = new Constant(1);
11
+ var resFive = shape.fuzzify(5);
12
+ var resHundret = shape.fuzzify(100);
13
+ assert.equal(resFive, resHundret);
14
+ });
15
+ });
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
- const FuzzyFunction= require('../lib/curve/fuzzy-function');
2
+ const { describe, it } = require('node:test');
3
+ const FuzzyFunction= require('../../lib/curve/fuzzy-function');
3
4
  const assert = require('assert');
4
5
 
5
6
  describe('FuzzyFunction', function() {
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
- const Grade = require('../lib/curve/grade');
2
+ const { describe, it } = require('node:test');
3
+ const Grade = require('../../lib/curve/grade');
3
4
  const assert = require('assert');
4
5
 
5
6
  describe('Grade', function() {
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
- const ReverseGrade = require('../lib/curve/reverse-grade');
2
+ const { describe, it } = require('node:test');
3
+ const ReverseGrade = require('../../lib/curve/reverse-grade');
3
4
  const assert = require('assert');
4
5
 
5
6
  describe('ReverseGrade', function() {
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
- const Shape = require('../lib/curve/shape');
2
+ const { describe, it } = require('node:test');
3
+ const Shape = require('../../lib/curve/shape');
3
4
  const assert = require('assert');
4
5
 
5
6
  describe('Shape', function() {
@@ -0,0 +1,93 @@
1
+ 'use strict';
2
+ const { describe, it } = require('node:test');
3
+ const Sigmoid = require('../../lib/curve/sigmoid');
4
+ const assert = require('assert');
5
+
6
+ describe('Sigmoid', function() {
7
+ it('is a function', function() {
8
+ assert.equal(typeof Sigmoid, 'function');
9
+ });
10
+ it('can create a new instance', function() {
11
+ var sigmoid = new Sigmoid();
12
+ var res = sigmoid.fuzzify(5);
13
+ assert.equal(res, 0.9933071490757153);
14
+ });
15
+
16
+ it('0', function() {
17
+ var sigmoid = new Sigmoid();
18
+ var res = sigmoid.fuzzify(0);
19
+ assert.equal(res, 0.5);
20
+ });
21
+
22
+ it('uses treshold', function() {
23
+ var sigmoid = new Sigmoid(1);
24
+ var res = sigmoid.fuzzify(1);
25
+ assert.equal(res, 0.5);
26
+ });
27
+
28
+ describe('slope', function() {
29
+ it('slope makes actually a difference', function() {
30
+ const fvalue = 10;
31
+ var sigmoid = new Sigmoid(0, 10);
32
+ var resSmall = sigmoid.fuzzify(fvalue);
33
+ var sigmoid2 = new Sigmoid(0, 100000);
34
+ var resBig = sigmoid2.fuzzify(fvalue);
35
+ assert.notEqual(resSmall, resBig);
36
+ });
37
+ });
38
+
39
+ describe('center parameter behavior', function() {
40
+ it('should correctly handle positive center values', function() {
41
+ // This test verifies that the sigmoid is properly centered
42
+ var sigmoid = new Sigmoid(2, 1);
43
+
44
+ // With center=2, the sigmoid is centered at x=2
45
+ // So sigmoid.fuzzify(2) should return 0.5
46
+ var res = sigmoid.fuzzify(2);
47
+ assert.equal(res, 0.5);
48
+
49
+ // Values to the right of the center should approach 1
50
+ var rightOfCenter = sigmoid.fuzzify(4);
51
+ assert(rightOfCenter > 0.5);
52
+ assert(rightOfCenter < 1);
53
+
54
+ // Values to the left of the center should approach 0
55
+ var leftOfCenter = sigmoid.fuzzify(0);
56
+ assert(leftOfCenter < 0.5);
57
+ assert(leftOfCenter > 0);
58
+ });
59
+
60
+ it('should correctly handle negative center values', function() {
61
+ var sigmoid = new Sigmoid(-3, 1);
62
+
63
+ // With center=-3, the sigmoid is centered at x=-3
64
+ // So sigmoid.fuzzify(-3) should return 0.5
65
+ var res = sigmoid.fuzzify(-3);
66
+ assert.equal(res, 0.5);
67
+ });
68
+
69
+ it('sigmoid should be 0.075 at zero', function() {
70
+ // Test that verifies the sigmoid value at x=0 when center=5
71
+ var sigmoid = new Sigmoid(5, 2);
72
+ var atZero = sigmoid.fuzzify(0);
73
+ assert.equal(atZero, 0.07585818002124355);
74
+ });
75
+
76
+ it('verifies sigmoid symmetry', function() {
77
+ // Test that verifies the sigmoid curve is symmetric around its center
78
+ var sigmoid = new Sigmoid(5, 2);
79
+
80
+ // Test symmetry around the center point
81
+ var atCenter = sigmoid.fuzzify(5);
82
+ assert.equal(atCenter, 0.5);
83
+
84
+ // Test points equidistant from center
85
+ var rightPoint = sigmoid.fuzzify(7); // 2 units right of center
86
+ var leftPoint = sigmoid.fuzzify(3); // 2 units left of center
87
+
88
+ // Due to sigmoid symmetry: f(center+d) + f(center-d) should equal 1
89
+ var sum = rightPoint + leftPoint;
90
+ assert(Math.abs(sum - 1) < 0.0000001, `Sum ${sum} should be approximately 1`);
91
+ });
92
+ });
93
+ });
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+ const { describe, it } = require('node:test');
3
+ const Trapezoid = require('../../lib/curve/trapezoid');
4
+ const assert = require('assert');
5
+
6
+ describe('Trapezoid', function() {
7
+ it('is a function', function() {
8
+ assert.equal(typeof Trapezoid, 'function');
9
+ });
10
+ it('can create a new instance', function() {
11
+ var trapez = new Trapezoid(0, 10, 20);
12
+ assert.equal(trapez.x0, 0);
13
+ assert.equal(trapez.x1, 10);
14
+ assert.equal(trapez.x2, 20);
15
+ });
16
+ it('fuzzify', function() {
17
+ var trapez = new Trapezoid(20, 30, 90);
18
+ var res = trapez.fuzzify(25);
19
+ assert.equal(res, 0.5);
20
+ });
21
+ it('avoid NaN if going over max', function() {
22
+ var trapez = new Trapezoid(20, 30, 90, 100);
23
+ var res = trapez.fuzzify(99);
24
+ assert.equal(res, 0.09999999999999964);
25
+ });
26
+
27
+ it('edge case triangle', function() {
28
+ var trapez = new Trapezoid(0, 0, 1.5, 2.5);
29
+ var res = trapez.fuzzify(0);
30
+ assert.equal(res, 0);
31
+ });
32
+
33
+ it('edge case triangle right bounds', function() {
34
+ var trapez = new Trapezoid(0, 0, 1.5, 2.5);
35
+ var res = trapez.fuzzify(2.5);
36
+ assert.equal(res, 0);
37
+ });
38
+
39
+ it('edge case triangle right top', function() {
40
+ var trapez = new Trapezoid(0, 0, 1.5, 2.5);
41
+ var res = trapez.fuzzify(1.5);
42
+ assert.equal(res, 1);
43
+ });
44
+
45
+
46
+ describe('bounds', ()=>{
47
+ it('trapezoid left bounds 0', function() {
48
+ var trapez = new Trapezoid(20, 30, 90, 100);
49
+ var res = trapez.fuzzify(20);
50
+ assert.equal(res, 0);
51
+ });
52
+
53
+ it('trapezoid right bounds 0', function() {
54
+ var trapez = new Trapezoid(20, 30, 90, 100);
55
+ var res = trapez.fuzzify(100);
56
+ assert.equal(res, 0);
57
+ });
58
+
59
+ it('trapezoid left top = 1', function() {
60
+ var trapez = new Trapezoid(20, 30, 90, 100);
61
+ var res = trapez.fuzzify(30);
62
+ assert.equal(res, 1);
63
+ });
64
+
65
+ it('trapezoid right top = 1', function() {
66
+ var trapez = new Trapezoid(20, 30, 90, 100);
67
+ var res = trapez.fuzzify(90);
68
+ assert.equal(res, 1);
69
+ });
70
+ });
71
+ });
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
- const Triangle = require('../lib/curve/triangle');
2
+ const { describe, it } = require('node:test');
3
+ const Triangle = require('../../lib/curve/triangle');
3
4
  const assert = require('assert');
4
5
 
5
6
  describe('Triangle', function() {