es6-fuzz 5.0.0 → 5.0.1
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 +1 -1
- package/docs/CHANGELOG.md +5 -5
- package/package.json +3 -3
- package/test/curve/{grade.js → grade.test.js} +7 -0
- package/test/curve/{reverse-grade.js → reverse-grade.test.js} +7 -0
- package/test/curve/{shape.js → shape.test.js} +13 -0
- package/test/curve/sigmoid/sigmoid-basic.test.js +27 -0
- package/test/curve/sigmoid/sigmoid-center-behavior.test.js +66 -0
- package/test/curve/sigmoid/sigmoid-slope.test.js +15 -0
- package/test/curve/{trapezoid.js → trapezoid/trapezoid-basic.test.js} +11 -28
- package/test/curve/trapezoid/trapezoid-bounds.test.js +30 -0
- package/test/edge-cases/constant-edge-values.test.js +56 -0
- package/test/edge-cases/fuzzy-function-edge-cases.test.js +71 -0
- package/test/edge-cases/grade-edge-cases.test.js +42 -0
- package/test/edge-cases/reverse-grade-edge-cases.test.js +42 -0
- package/test/edge-cases/shapes-large-values.test.js +78 -0
- package/test/edge-cases/shapes-negative-values.test.js +75 -0
- package/test/edge-cases/sigmoid-edge-cases.test.js +70 -0
- package/test/edge-cases/trapezoid-special-cases.test.js +94 -0
- package/test/edge-cases/triangle-degenerate-cases.test.js +62 -0
- package/test/error-handling/empty-rules-handling.test.js +25 -0
- package/test/error-handling/es6-class-instantiation.test.js +52 -0
- package/test/error-handling/fuzzy-function-validation.test.js +66 -0
- package/test/error-handling/invalid-chaining-sequences.test.js +40 -0
- package/test/error-handling/logic-validation.test.js +78 -0
- package/test/error-handling/property-immutability.test.js +29 -0
- package/test/error-handling/shape-constructor-validation.test.js +70 -0
- package/test/integration/and-or-not-combinations.test.js +42 -0
- package/test/integration/complex-logic-chains.test.js +85 -0
- package/test/integration/edge-case-combinations.test.js +55 -0
- package/test/integration/mixing-shape-types.test.js +44 -0
- package/test/integration/performance-many-rules.test.js +42 -0
- package/test/integration/real-world-scenarios.test.js +50 -0
- package/test/integration/state-management.test.js +47 -0
- package/test/logic/attack-rage-calculation.test.js +22 -0
- package/test/logic/behaves-like-number.test.js +22 -0
- package/test/logic/interface.test.js +20 -0
- package/test/logic/not-operation.test.js +17 -0
- package/test/bug-74-test.js +0 -100
- package/test/curve/sigmoid.js +0 -93
- package/test/edge-cases.js +0 -244
- package/test/error-handling.js +0 -229
- package/test/integration.js +0 -343
- package/test/logic-test.js +0 -67
- /package/test/curve/{constant.js → constant.test.js} +0 -0
- /package/test/curve/{fuzzy-function.js → fuzzy-function.test.js} +0 -0
- /package/test/curve/{triangle.js → triangle.test.js} +0 -0
- /package/test/{example-test.js → example.test.js} +0 -0
package/Readme.md
CHANGED
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
2025-06-26
|
|
2
2
|
==========
|
|
3
3
|
|
|
4
|
-
* 5.0.
|
|
4
|
+
* 5.0.1
|
|
5
|
+
* refactor: cleanup of test files
|
|
6
|
+
* chore: remove unused test
|
|
7
|
+
* docs: add correct name of test framework
|
|
5
8
|
* (churn): changelog
|
|
9
|
+
* 5.0.0
|
|
6
10
|
* 4.0.4
|
|
7
11
|
* fix: edge cases
|
|
8
12
|
* 4.0.3
|
|
@@ -156,7 +160,3 @@
|
|
|
156
160
|
* Changelog
|
|
157
161
|
* Added changelog link
|
|
158
162
|
* 2.6.1
|
|
159
|
-
* Docs
|
|
160
|
-
* 2.6.0
|
|
161
|
-
* Added link to api docs
|
|
162
|
-
* More docs
|
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": "5.0.
|
|
4
|
+
"version": "5.0.1",
|
|
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": "node --test",
|
|
11
|
-
"test:watch": "node --test --watch",
|
|
10
|
+
"test": "node --test ./test/*.test.js ./test/**/*.test.js ./test/curve/**/*.test.js",
|
|
11
|
+
"test:watch": "node --test --watch ./test/*.test.js ./test/**/*.test.js ./test/curve/**/*.test.js",
|
|
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",
|
|
@@ -8,8 +8,15 @@ describe('Grade', function() {
|
|
|
8
8
|
assert.equal(typeof Grade, 'function');
|
|
9
9
|
});
|
|
10
10
|
it('can create a new instance', function() {
|
|
11
|
+
var grade = new Grade(0, 1);
|
|
12
|
+
assert.ok(grade instanceof Grade);
|
|
13
|
+
});
|
|
14
|
+
it('sets x0 property correctly', function() {
|
|
11
15
|
var grade = new Grade(0, 1);
|
|
12
16
|
assert.equal(grade.x0, 0);
|
|
17
|
+
});
|
|
18
|
+
it('sets x1 property correctly', function() {
|
|
19
|
+
var grade = new Grade(0, 1);
|
|
13
20
|
assert.equal(grade.x1, 1);
|
|
14
21
|
});
|
|
15
22
|
it('fuzzify', function() {
|
|
@@ -8,8 +8,15 @@ describe('ReverseGrade', function() {
|
|
|
8
8
|
assert.equal(typeof ReverseGrade, 'function');
|
|
9
9
|
});
|
|
10
10
|
it('can create a new instance', function() {
|
|
11
|
+
var reverseGrade = new ReverseGrade(0, 1);
|
|
12
|
+
assert.ok(reverseGrade instanceof ReverseGrade);
|
|
13
|
+
});
|
|
14
|
+
it('sets x0 property correctly', function() {
|
|
11
15
|
var reverseGrade = new ReverseGrade(0, 1);
|
|
12
16
|
assert.equal(reverseGrade.x0, 0);
|
|
17
|
+
});
|
|
18
|
+
it('sets x1 property correctly', function() {
|
|
19
|
+
var reverseGrade = new ReverseGrade(0, 1);
|
|
13
20
|
assert.equal(reverseGrade.x1, 1);
|
|
14
21
|
});
|
|
15
22
|
it('fuzzify', function() {
|
|
@@ -8,10 +8,23 @@ describe('Shape', function() {
|
|
|
8
8
|
assert.equal(typeof Shape, 'function');
|
|
9
9
|
});
|
|
10
10
|
it('can create a new instance', function() {
|
|
11
|
+
var shape = new Shape(0, 1, 2, 3);
|
|
12
|
+
assert.ok(shape instanceof Shape);
|
|
13
|
+
});
|
|
14
|
+
it('sets x0 property correctly', function() {
|
|
11
15
|
var shape = new Shape(0, 1, 2, 3);
|
|
12
16
|
assert.equal(shape.x0, 0);
|
|
17
|
+
});
|
|
18
|
+
it('sets x1 property correctly', function() {
|
|
19
|
+
var shape = new Shape(0, 1, 2, 3);
|
|
13
20
|
assert.equal(shape.x1, 1);
|
|
21
|
+
});
|
|
22
|
+
it('sets x2 property correctly', function() {
|
|
23
|
+
var shape = new Shape(0, 1, 2, 3);
|
|
14
24
|
assert.equal(shape.x2, 2);
|
|
25
|
+
});
|
|
26
|
+
it('sets x3 property correctly', function() {
|
|
27
|
+
var shape = new Shape(0, 1, 2, 3);
|
|
15
28
|
assert.equal(shape.x3, 3);
|
|
16
29
|
});
|
|
17
30
|
});
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
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('center parameter behavior', function() {
|
|
7
|
+
it('should return 0.5 at the center for positive center values', function() {
|
|
8
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
9
|
+
var res = sigmoid.fuzzify(2);
|
|
10
|
+
assert.equal(res, 0.5);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should return value greater than 0.5 for values right of positive center', function() {
|
|
14
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
15
|
+
var rightOfCenter = sigmoid.fuzzify(4);
|
|
16
|
+
assert(rightOfCenter > 0.5);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should return value less than 1 for values right of positive center', function() {
|
|
20
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
21
|
+
var rightOfCenter = sigmoid.fuzzify(4);
|
|
22
|
+
assert(rightOfCenter < 1);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should return value less than 0.5 for values left of positive center', function() {
|
|
26
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
27
|
+
var leftOfCenter = sigmoid.fuzzify(0);
|
|
28
|
+
assert(leftOfCenter < 0.5);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should return value greater than 0 for values left of positive center', function() {
|
|
32
|
+
var sigmoid = new Sigmoid(2, 1);
|
|
33
|
+
var leftOfCenter = sigmoid.fuzzify(0);
|
|
34
|
+
assert(leftOfCenter > 0);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should correctly handle negative center values', function() {
|
|
38
|
+
var sigmoid = new Sigmoid(-3, 1);
|
|
39
|
+
|
|
40
|
+
// With center=-3, the sigmoid is centered at x=-3
|
|
41
|
+
// So sigmoid.fuzzify(-3) should return 0.5
|
|
42
|
+
var res = sigmoid.fuzzify(-3);
|
|
43
|
+
assert.equal(res, 0.5);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('sigmoid should be 0.075 at zero', function() {
|
|
47
|
+
// Test that verifies the sigmoid value at x=0 when center=5
|
|
48
|
+
var sigmoid = new Sigmoid(5, 2);
|
|
49
|
+
var atZero = sigmoid.fuzzify(0);
|
|
50
|
+
assert.equal(atZero, 0.07585818002124355);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should return 0.5 at center point for symmetry', function() {
|
|
54
|
+
var sigmoid = new Sigmoid(5, 2);
|
|
55
|
+
var atCenter = sigmoid.fuzzify(5);
|
|
56
|
+
assert.equal(atCenter, 0.5);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should be symmetric around center point', function() {
|
|
60
|
+
var sigmoid = new Sigmoid(5, 2);
|
|
61
|
+
var rightPoint = sigmoid.fuzzify(7); // 2 units right of center
|
|
62
|
+
var leftPoint = sigmoid.fuzzify(3); // 2 units left of center
|
|
63
|
+
var sum = rightPoint + leftPoint;
|
|
64
|
+
assert(Math.abs(sum - 1) < 0.0000001, `Sum ${sum} should be approximately 1`);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
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('slope', function() {
|
|
7
|
+
it('slope makes actually a difference', function() {
|
|
8
|
+
const fvalue = 10;
|
|
9
|
+
var sigmoid = new Sigmoid(0, 10);
|
|
10
|
+
var resSmall = sigmoid.fuzzify(fvalue);
|
|
11
|
+
var sigmoid2 = new Sigmoid(0, 100000);
|
|
12
|
+
var resBig = sigmoid2.fuzzify(fvalue);
|
|
13
|
+
assert.notEqual(resSmall, resBig);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const { describe, it } = require('node:test');
|
|
3
|
-
const Trapezoid = require('
|
|
3
|
+
const Trapezoid = require('../../../lib/curve/trapezoid');
|
|
4
4
|
const assert = require('assert');
|
|
5
5
|
|
|
6
6
|
describe('Trapezoid', function() {
|
|
@@ -8,9 +8,19 @@ describe('Trapezoid', function() {
|
|
|
8
8
|
assert.equal(typeof Trapezoid, 'function');
|
|
9
9
|
});
|
|
10
10
|
it('can create a new instance', function() {
|
|
11
|
+
var trapez = new Trapezoid(0, 10, 20);
|
|
12
|
+
assert.ok(trapez instanceof Trapezoid);
|
|
13
|
+
});
|
|
14
|
+
it('sets x0 property correctly', function() {
|
|
11
15
|
var trapez = new Trapezoid(0, 10, 20);
|
|
12
16
|
assert.equal(trapez.x0, 0);
|
|
17
|
+
});
|
|
18
|
+
it('sets x1 property correctly', function() {
|
|
19
|
+
var trapez = new Trapezoid(0, 10, 20);
|
|
13
20
|
assert.equal(trapez.x1, 10);
|
|
21
|
+
});
|
|
22
|
+
it('sets x2 property correctly', function() {
|
|
23
|
+
var trapez = new Trapezoid(0, 10, 20);
|
|
14
24
|
assert.equal(trapez.x2, 20);
|
|
15
25
|
});
|
|
16
26
|
it('fuzzify', function() {
|
|
@@ -41,31 +51,4 @@ describe('Trapezoid', function() {
|
|
|
41
51
|
var res = trapez.fuzzify(1.5);
|
|
42
52
|
assert.equal(res, 1);
|
|
43
53
|
});
|
|
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
54
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
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('bounds', ()=>{
|
|
7
|
+
it('trapezoid left bounds 0', function() {
|
|
8
|
+
var trapez = new Trapezoid(20, 30, 90, 100);
|
|
9
|
+
var res = trapez.fuzzify(20);
|
|
10
|
+
assert.equal(res, 0);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('trapezoid right bounds 0', function() {
|
|
14
|
+
var trapez = new Trapezoid(20, 30, 90, 100);
|
|
15
|
+
var res = trapez.fuzzify(100);
|
|
16
|
+
assert.equal(res, 0);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('trapezoid left top = 1', function() {
|
|
20
|
+
var trapez = new Trapezoid(20, 30, 90, 100);
|
|
21
|
+
var res = trapez.fuzzify(30);
|
|
22
|
+
assert.equal(res, 1);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('trapezoid right top = 1', function() {
|
|
26
|
+
var trapez = new Trapezoid(20, 30, 90, 100);
|
|
27
|
+
var res = trapez.fuzzify(90);
|
|
28
|
+
assert.equal(res, 1);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const Constant = require('../../lib/curve/constant');
|
|
5
|
+
|
|
6
|
+
describe('Constant edge values', function() {
|
|
7
|
+
describe('all possible constant values', function() {
|
|
8
|
+
it('should return 0 for constant value 0', function() {
|
|
9
|
+
assert.equal(new Constant(0).fuzzify(), 0);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should return 0.5 for constant value 0.5', function() {
|
|
13
|
+
assert.equal(new Constant(0.5).fuzzify(), 0.5);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return 1 for constant value 1', function() {
|
|
17
|
+
assert.equal(new Constant(1).fuzzify(), 1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should return -1 for constant value -1', function() {
|
|
21
|
+
assert.equal(new Constant(-1).fuzzify(), -1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should return 2 for constant value 2', function() {
|
|
25
|
+
assert.equal(new Constant(2).fuzzify(), 2);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should return -0.5 for constant value -0.5', function() {
|
|
29
|
+
assert.equal(new Constant(-0.5).fuzzify(), -0.5);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should return 1.5 for constant value 1.5', function() {
|
|
33
|
+
assert.equal(new Constant(1.5).fuzzify(), 1.5);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('ignoring x parameter in fuzzify', function() {
|
|
38
|
+
const constant = new Constant(0.7);
|
|
39
|
+
|
|
40
|
+
it('should return constant value for x=0', function() {
|
|
41
|
+
assert.equal(constant.fuzzify(0), 0.7);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should return constant value for x=100', function() {
|
|
45
|
+
assert.equal(constant.fuzzify(100), 0.7);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should return constant value for x=-100', function() {
|
|
49
|
+
assert.equal(constant.fuzzify(-100), 0.7);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should return constant value for x=Infinity', function() {
|
|
53
|
+
assert.equal(constant.fuzzify(Infinity), 0.7);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const FuzzyFunction = require('../../lib/curve/fuzzy-function');
|
|
5
|
+
|
|
6
|
+
describe('FuzzyFunction edge cases', function() {
|
|
7
|
+
describe('functions returning values outside [0,1]', function() {
|
|
8
|
+
describe('function returning > 1 for x > 0.5', function() {
|
|
9
|
+
const func1 = new FuzzyFunction(x => x * 2);
|
|
10
|
+
|
|
11
|
+
it('should return valid value for x=0.3', function() {
|
|
12
|
+
assert.equal(func1.fuzzify(0.3), 0.6);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should return exactly 1 for x=0.5', function() {
|
|
16
|
+
assert.equal(func1.fuzzify(0.5), 1);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should throw error for x=0.7', function() {
|
|
20
|
+
assert.throws(() => func1.fuzzify(0.7), /fuzzified result must be smaller than 1/);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('function returning < 0 for x < 1', function() {
|
|
25
|
+
const func2 = new FuzzyFunction(x => x - 1);
|
|
26
|
+
|
|
27
|
+
it('should throw error for x=0.5', function() {
|
|
28
|
+
assert.throws(() => func2.fuzzify(0.5), /fuzzified result must be smaller than 1/);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should return exactly 0 for x=1', function() {
|
|
32
|
+
assert.equal(func2.fuzzify(1), 0);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should throw error for x=0.8', function() {
|
|
36
|
+
assert.throws(() => func2.fuzzify(0.8), /fuzzified result must be smaller than 1/);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('complex mathematical functions', function() {
|
|
42
|
+
const sinFunc = new FuzzyFunction(x => (Math.sin(x) + 1) / 2);
|
|
43
|
+
|
|
44
|
+
it('should return 0.5 for x=0', function() {
|
|
45
|
+
assert(sinFunc.fuzzify(0) === 0.5);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should return 1 for x=PI/2', function() {
|
|
49
|
+
assert(sinFunc.fuzzify(Math.PI / 2) === 1);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should return 0 for x=3*PI/2', function() {
|
|
53
|
+
assert(sinFunc.fuzzify(3 * Math.PI / 2) === 0);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('functions that throw errors', function() {
|
|
58
|
+
const errorFunc = new FuzzyFunction(x => {
|
|
59
|
+
if (x < 0) throw new Error('Negative input');
|
|
60
|
+
return x;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should return valid value for x=0.5', function() {
|
|
64
|
+
assert.equal(errorFunc.fuzzify(0.5), 0.5);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should throw error for negative input', function() {
|
|
68
|
+
assert.throws(() => errorFunc.fuzzify(-1), /Negative input/);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const Grade = require('../../lib/curve/grade');
|
|
5
|
+
|
|
6
|
+
describe('Grade edge cases', function() {
|
|
7
|
+
describe('vertical grade (x0=x1)', function() {
|
|
8
|
+
const grade = new Grade(5, 5);
|
|
9
|
+
|
|
10
|
+
it('should return 0 for value before x0', function() {
|
|
11
|
+
assert.equal(grade.fuzzify(4.9), 0);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should return 1 for value at x0=x1', function() {
|
|
15
|
+
assert.equal(grade.fuzzify(5), 1);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should return 1 for value after x1', function() {
|
|
19
|
+
assert.equal(grade.fuzzify(5.1), 1);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should return 1 for very large value', function() {
|
|
23
|
+
assert.equal(grade.fuzzify(100), 1);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('very steep grade', function() {
|
|
28
|
+
const grade = new Grade(5, 5.0001);
|
|
29
|
+
|
|
30
|
+
it('should return 0 for value before x0', function() {
|
|
31
|
+
assert.equal(grade.fuzzify(4.9), 0);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should return greater than 0.4 for value at midpoint', function() {
|
|
35
|
+
assert(grade.fuzzify(5.00005) > 0.4);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return 1 for value well after x1', function() {
|
|
39
|
+
assert.equal(grade.fuzzify(5.1), 1);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const ReverseGrade = require('../../lib/curve/reverse-grade');
|
|
5
|
+
|
|
6
|
+
describe('ReverseGrade edge cases', function() {
|
|
7
|
+
describe('vertical reverse grade (x0=x1)', function() {
|
|
8
|
+
const reverseGrade = new ReverseGrade(5, 5);
|
|
9
|
+
|
|
10
|
+
it('should return 1 for value before x0', function() {
|
|
11
|
+
assert.equal(reverseGrade.fuzzify(4.9), 1);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should return 1 for value at x0=x1', function() {
|
|
15
|
+
assert.equal(reverseGrade.fuzzify(5), 1);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should return 0 for value after x1', function() {
|
|
19
|
+
assert.equal(reverseGrade.fuzzify(5.1), 0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should return 0 for very large value', function() {
|
|
23
|
+
assert.equal(reverseGrade.fuzzify(100), 0);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('very steep reverse grade', function() {
|
|
28
|
+
const reverseGrade = new ReverseGrade(5, 5.0001);
|
|
29
|
+
|
|
30
|
+
it('should return 1 for value before x0', function() {
|
|
31
|
+
assert.equal(reverseGrade.fuzzify(4.9), 1);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should return less than 0.6 for value at midpoint', function() {
|
|
35
|
+
assert(reverseGrade.fuzzify(5.00005) < 0.6);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return 0 for value well after x1', function() {
|
|
39
|
+
assert.equal(reverseGrade.fuzzify(5.1), 0);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const Triangle = require('../../lib/curve/triangle');
|
|
5
|
+
const Trapezoid = require('../../lib/curve/trapezoid');
|
|
6
|
+
const Grade = require('../../lib/curve/grade');
|
|
7
|
+
const ReverseGrade = require('../../lib/curve/reverse-grade');
|
|
8
|
+
const Sigmoid = require('../../lib/curve/sigmoid');
|
|
9
|
+
|
|
10
|
+
describe('Shapes with very large x values', function() {
|
|
11
|
+
describe('Infinity handling', function() {
|
|
12
|
+
const triangle = new Triangle(0, 10, 20);
|
|
13
|
+
const trapezoid = new Trapezoid(0, 10, 20, 30);
|
|
14
|
+
const grade = new Grade(0, 10);
|
|
15
|
+
const reverseGrade = new ReverseGrade(0, 10);
|
|
16
|
+
const sigmoid = new Sigmoid(10, 1);
|
|
17
|
+
|
|
18
|
+
it('should return 0 for triangle with positive Infinity', function() {
|
|
19
|
+
assert.equal(triangle.fuzzify(Infinity), 0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should return 0 for triangle with negative Infinity', function() {
|
|
23
|
+
assert.equal(triangle.fuzzify(-Infinity), 0);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return 0 for trapezoid with positive Infinity', function() {
|
|
27
|
+
assert.equal(trapezoid.fuzzify(Infinity), 0);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should return 0 for trapezoid with negative Infinity', function() {
|
|
31
|
+
assert.equal(trapezoid.fuzzify(-Infinity), 0);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should return 1 for grade with positive Infinity', function() {
|
|
35
|
+
assert.equal(grade.fuzzify(Infinity), 1);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return 0 for grade with negative Infinity', function() {
|
|
39
|
+
assert.equal(grade.fuzzify(-Infinity), 0);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should return 0 for reverseGrade with positive Infinity', function() {
|
|
43
|
+
assert.equal(reverseGrade.fuzzify(Infinity), 0);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should return 1 for reverseGrade with negative Infinity', function() {
|
|
47
|
+
assert.equal(reverseGrade.fuzzify(-Infinity), 1);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should return 1 for sigmoid with positive Infinity', function() {
|
|
51
|
+
assert.equal(sigmoid.fuzzify(Infinity), 1);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should return 0 for sigmoid with negative Infinity', function() {
|
|
55
|
+
assert.equal(sigmoid.fuzzify(-Infinity), 0);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('very large numbers', function() {
|
|
60
|
+
const triangle = new Triangle(0, 1e10, 2e10);
|
|
61
|
+
|
|
62
|
+
it('should return 0 for value at x0', function() {
|
|
63
|
+
assert.equal(triangle.fuzzify(0), 0);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should return 1 for value at x1', function() {
|
|
67
|
+
assert.equal(triangle.fuzzify(1e10), 1);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should return 0 for value at x2', function() {
|
|
71
|
+
assert.equal(triangle.fuzzify(2e10), 0);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should return 0.5 for value at midpoint', function() {
|
|
75
|
+
assert.equal(triangle.fuzzify(1.5e10), 0.5);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { describe, it } = require('node:test');
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const Triangle = require('../../lib/curve/triangle');
|
|
5
|
+
const Trapezoid = require('../../lib/curve/trapezoid');
|
|
6
|
+
|
|
7
|
+
describe('Shapes with negative x values', function() {
|
|
8
|
+
describe('triangle with negative x values', function() {
|
|
9
|
+
const triangle = new Triangle(-10, -5, 0);
|
|
10
|
+
|
|
11
|
+
it('should return 0 for value far before x0', function() {
|
|
12
|
+
assert.equal(triangle.fuzzify(-15), 0);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should return 0 for value at x0', function() {
|
|
16
|
+
assert.equal(triangle.fuzzify(-10), 0);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should return 0.5 for value at midpoint of left slope', function() {
|
|
20
|
+
assert.equal(triangle.fuzzify(-7.5), 0.5);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should return 1 for value at x1', function() {
|
|
24
|
+
assert.equal(triangle.fuzzify(-5), 1);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should return 0.5 for value at midpoint of right slope', function() {
|
|
28
|
+
assert.equal(triangle.fuzzify(-2.5), 0.5);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should return 0 for value at x2', function() {
|
|
32
|
+
assert.equal(triangle.fuzzify(0), 0);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should return 0 for value after x2', function() {
|
|
36
|
+
assert.equal(triangle.fuzzify(5), 0);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('trapezoid with negative x values', function() {
|
|
41
|
+
const trapezoid = new Trapezoid(-20, -15, -5, 0);
|
|
42
|
+
|
|
43
|
+
it('should return 0 for value before x0', function() {
|
|
44
|
+
assert.equal(trapezoid.fuzzify(-25), 0);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should return 0 for value at x0', function() {
|
|
48
|
+
assert.equal(trapezoid.fuzzify(-20), 0);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should return 0.5 for value at midpoint of left slope', function() {
|
|
52
|
+
assert.equal(trapezoid.fuzzify(-17.5), 0.5);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should return 1 for value at x1', function() {
|
|
56
|
+
assert.equal(trapezoid.fuzzify(-15), 1);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should return 1 for value in middle plateau', function() {
|
|
60
|
+
assert.equal(trapezoid.fuzzify(-10), 1);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should return 1 for value at x2', function() {
|
|
64
|
+
assert.equal(trapezoid.fuzzify(-5), 1);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should return 0.5 for value at midpoint of right slope', function() {
|
|
68
|
+
assert.equal(trapezoid.fuzzify(-2.5), 0.5);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should return 0 for value at x3', function() {
|
|
72
|
+
assert.equal(trapezoid.fuzzify(0), 0);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|