@reicek/neataptic-ts 0.1.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/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +27 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +28 -0
- package/.github/workflows/ci.yml +41 -0
- package/.github/workflows/deploy-pages.yml +29 -0
- package/.github/workflows/manual_release_pipeline.yml +62 -0
- package/.github/workflows/publish.yml +85 -0
- package/.github/workflows/release_dispatch.yml +38 -0
- package/.travis.yml +5 -0
- package/CONTRIBUTING.md +92 -0
- package/LICENSE +24 -0
- package/ONNX_EXPORT.md +87 -0
- package/README.md +1173 -0
- package/RELEASE.md +54 -0
- package/dist-docs/package.json +1 -0
- package/dist-docs/scripts/generate-docs.d.ts +2 -0
- package/dist-docs/scripts/generate-docs.d.ts.map +1 -0
- package/dist-docs/scripts/generate-docs.js +536 -0
- package/dist-docs/scripts/generate-docs.js.map +1 -0
- package/dist-docs/scripts/render-docs-html.d.ts +2 -0
- package/dist-docs/scripts/render-docs-html.d.ts.map +1 -0
- package/dist-docs/scripts/render-docs-html.js +148 -0
- package/dist-docs/scripts/render-docs-html.js.map +1 -0
- package/docs/FOLDERS.md +14 -0
- package/docs/README.md +1173 -0
- package/docs/architecture/README.md +1391 -0
- package/docs/architecture/index.html +938 -0
- package/docs/architecture/network/README.md +1210 -0
- package/docs/architecture/network/index.html +908 -0
- package/docs/assets/ascii-maze.bundle.js +16542 -0
- package/docs/assets/ascii-maze.bundle.js.map +7 -0
- package/docs/index.html +1419 -0
- package/docs/methods/README.md +670 -0
- package/docs/methods/index.html +477 -0
- package/docs/multithreading/README.md +274 -0
- package/docs/multithreading/index.html +215 -0
- package/docs/multithreading/workers/README.md +23 -0
- package/docs/multithreading/workers/browser/README.md +39 -0
- package/docs/multithreading/workers/browser/index.html +70 -0
- package/docs/multithreading/workers/index.html +57 -0
- package/docs/multithreading/workers/node/README.md +33 -0
- package/docs/multithreading/workers/node/index.html +66 -0
- package/docs/neat/README.md +1284 -0
- package/docs/neat/index.html +906 -0
- package/docs/src/README.md +2659 -0
- package/docs/src/index.html +1579 -0
- package/jest.config.ts +32 -0
- package/package.json +99 -0
- package/plans/HyperMorphoNEAT.md +293 -0
- package/plans/ONNX_EXPORT_PLAN.md +46 -0
- package/scripts/generate-docs.ts +486 -0
- package/scripts/render-docs-html.ts +138 -0
- package/scripts/types.d.ts +2 -0
- package/src/README.md +2659 -0
- package/src/architecture/README.md +1391 -0
- package/src/architecture/activationArrayPool.ts +135 -0
- package/src/architecture/architect.ts +635 -0
- package/src/architecture/connection.ts +148 -0
- package/src/architecture/group.ts +406 -0
- package/src/architecture/layer.ts +804 -0
- package/src/architecture/network/README.md +1210 -0
- package/src/architecture/network/network.activate.ts +223 -0
- package/src/architecture/network/network.connect.ts +157 -0
- package/src/architecture/network/network.deterministic.ts +167 -0
- package/src/architecture/network/network.evolve.ts +426 -0
- package/src/architecture/network/network.gating.ts +186 -0
- package/src/architecture/network/network.genetic.ts +247 -0
- package/src/architecture/network/network.mutate.ts +624 -0
- package/src/architecture/network/network.onnx.ts +463 -0
- package/src/architecture/network/network.prune.ts +216 -0
- package/src/architecture/network/network.remove.ts +96 -0
- package/src/architecture/network/network.serialize.ts +309 -0
- package/src/architecture/network/network.slab.ts +262 -0
- package/src/architecture/network/network.standalone.ts +246 -0
- package/src/architecture/network/network.stats.ts +59 -0
- package/src/architecture/network/network.topology.ts +86 -0
- package/src/architecture/network/network.training.ts +1278 -0
- package/src/architecture/network.ts +1302 -0
- package/src/architecture/node.ts +1288 -0
- package/src/architecture/onnx.ts +3 -0
- package/src/config.ts +83 -0
- package/src/methods/README.md +670 -0
- package/src/methods/activation.ts +372 -0
- package/src/methods/connection.ts +31 -0
- package/src/methods/cost.ts +347 -0
- package/src/methods/crossover.ts +63 -0
- package/src/methods/gating.ts +43 -0
- package/src/methods/methods.ts +8 -0
- package/src/methods/mutation.ts +300 -0
- package/src/methods/rate.ts +257 -0
- package/src/methods/selection.ts +65 -0
- package/src/multithreading/README.md +274 -0
- package/src/multithreading/multi.ts +339 -0
- package/src/multithreading/workers/README.md +23 -0
- package/src/multithreading/workers/browser/README.md +39 -0
- package/src/multithreading/workers/browser/testworker.ts +99 -0
- package/src/multithreading/workers/node/README.md +33 -0
- package/src/multithreading/workers/node/testworker.ts +72 -0
- package/src/multithreading/workers/node/worker.ts +70 -0
- package/src/multithreading/workers/workers.ts +22 -0
- package/src/neat/README.md +1284 -0
- package/src/neat/neat.adaptive.ts +544 -0
- package/src/neat/neat.compat.ts +164 -0
- package/src/neat/neat.constants.ts +20 -0
- package/src/neat/neat.diversity.ts +217 -0
- package/src/neat/neat.evaluate.ts +328 -0
- package/src/neat/neat.evolve.ts +1026 -0
- package/src/neat/neat.export.ts +249 -0
- package/src/neat/neat.helpers.ts +235 -0
- package/src/neat/neat.lineage.ts +220 -0
- package/src/neat/neat.multiobjective.ts +260 -0
- package/src/neat/neat.mutation.ts +718 -0
- package/src/neat/neat.objectives.ts +157 -0
- package/src/neat/neat.pruning.ts +190 -0
- package/src/neat/neat.selection.ts +269 -0
- package/src/neat/neat.speciation.ts +460 -0
- package/src/neat/neat.species.ts +151 -0
- package/src/neat/neat.telemetry.exports.ts +469 -0
- package/src/neat/neat.telemetry.ts +933 -0
- package/src/neat/neat.types.ts +275 -0
- package/src/neat.ts +1042 -0
- package/src/neataptic.ts +10 -0
- package/test/architecture/activationArrayPool.capacity.test.ts +19 -0
- package/test/architecture/activationArrayPool.test.ts +46 -0
- package/test/architecture/connection.test.ts +290 -0
- package/test/architecture/group.test.ts +950 -0
- package/test/architecture/layer.test.ts +1535 -0
- package/test/architecture/network.pruning.test.ts +65 -0
- package/test/architecture/node.test.ts +1602 -0
- package/test/examples/asciiMaze/asciiMaze.e2e.test.ts +499 -0
- package/test/examples/asciiMaze/asciiMaze.ts +41 -0
- package/test/examples/asciiMaze/browser-entry.ts +164 -0
- package/test/examples/asciiMaze/browserLogger.ts +221 -0
- package/test/examples/asciiMaze/browserTerminalUtility.ts +48 -0
- package/test/examples/asciiMaze/colors.ts +119 -0
- package/test/examples/asciiMaze/dashboardManager.ts +968 -0
- package/test/examples/asciiMaze/evolutionEngine.ts +1248 -0
- package/test/examples/asciiMaze/fitness.ts +136 -0
- package/test/examples/asciiMaze/index.html +128 -0
- package/test/examples/asciiMaze/index.ts +26 -0
- package/test/examples/asciiMaze/interfaces.ts +235 -0
- package/test/examples/asciiMaze/mazeMovement.ts +996 -0
- package/test/examples/asciiMaze/mazeUtils.ts +278 -0
- package/test/examples/asciiMaze/mazeVision.ts +402 -0
- package/test/examples/asciiMaze/mazeVisualization.ts +585 -0
- package/test/examples/asciiMaze/mazes.ts +245 -0
- package/test/examples/asciiMaze/networkRefinement.ts +76 -0
- package/test/examples/asciiMaze/networkVisualization.ts +901 -0
- package/test/examples/asciiMaze/terminalUtility.ts +73 -0
- package/test/methods/activation.test.ts +1142 -0
- package/test/methods/connection.test.ts +146 -0
- package/test/methods/cost.test.ts +1123 -0
- package/test/methods/crossover.test.ts +202 -0
- package/test/methods/gating.test.ts +144 -0
- package/test/methods/mutation.test.ts +451 -0
- package/test/methods/optimizers.advanced.test.ts +80 -0
- package/test/methods/optimizers.behavior.test.ts +105 -0
- package/test/methods/optimizers.formula.test.ts +89 -0
- package/test/methods/rate.cosineWarmRestarts.test.ts +44 -0
- package/test/methods/rate.linearWarmupDecay.test.ts +41 -0
- package/test/methods/rate.reduceOnPlateau.test.ts +45 -0
- package/test/methods/rate.test.ts +684 -0
- package/test/methods/selection.test.ts +245 -0
- package/test/multithreading/activations.functions.test.ts +54 -0
- package/test/multithreading/multi.test.ts +290 -0
- package/test/multithreading/worker.node.process.test.ts +39 -0
- package/test/multithreading/workers.coverage.test.ts +36 -0
- package/test/multithreading/workers.dynamic.import.test.ts +8 -0
- package/test/neat/neat.adaptive.complexityBudget.test.ts +34 -0
- package/test/neat/neat.adaptive.criterion.complexity.test.ts +50 -0
- package/test/neat/neat.adaptive.mutation.strategy.test.ts +37 -0
- package/test/neat/neat.adaptive.operator.decay.test.ts +31 -0
- package/test/neat/neat.adaptive.phasedComplexity.test.ts +25 -0
- package/test/neat/neat.adaptive.pruning.test.ts +25 -0
- package/test/neat/neat.adaptive.targetSpecies.test.ts +43 -0
- package/test/neat/neat.additional.coverage.test.ts +126 -0
- package/test/neat/neat.advanced.enhancements.test.ts +85 -0
- package/test/neat/neat.advanced.test.ts +589 -0
- package/test/neat/neat.diversity.autocompat.test.ts +47 -0
- package/test/neat/neat.diversity.metrics.test.ts +21 -0
- package/test/neat/neat.diversity.stats.test.ts +44 -0
- package/test/neat/neat.enhancements.test.ts +79 -0
- package/test/neat/neat.entropy.ancestorAdaptive.test.ts +133 -0
- package/test/neat/neat.entropy.compat.csv.test.ts +108 -0
- package/test/neat/neat.evolution.pruning.test.ts +39 -0
- package/test/neat/neat.fastmode.autotune.test.ts +42 -0
- package/test/neat/neat.innovation.test.ts +134 -0
- package/test/neat/neat.lineage.antibreeding.test.ts +35 -0
- package/test/neat/neat.lineage.entropy.test.ts +56 -0
- package/test/neat/neat.lineage.inbreeding.test.ts +49 -0
- package/test/neat/neat.lineage.pressure.test.ts +29 -0
- package/test/neat/neat.multiobjective.adaptive.test.ts +57 -0
- package/test/neat/neat.multiobjective.dynamic.schedule.test.ts +46 -0
- package/test/neat/neat.multiobjective.dynamic.test.ts +31 -0
- package/test/neat/neat.multiobjective.fastsort.delegation.test.ts +51 -0
- package/test/neat/neat.multiobjective.prune.test.ts +39 -0
- package/test/neat/neat.multiobjective.test.ts +21 -0
- package/test/neat/neat.mutation.undefined.pool.test.ts +24 -0
- package/test/neat/neat.objective.events.test.ts +26 -0
- package/test/neat/neat.objective.importance.test.ts +21 -0
- package/test/neat/neat.objective.lifetimes.test.ts +33 -0
- package/test/neat/neat.offspring.allocation.test.ts +22 -0
- package/test/neat/neat.operator.bandit.test.ts +17 -0
- package/test/neat/neat.operator.phases.test.ts +38 -0
- package/test/neat/neat.pruneInactive.behavior.test.ts +54 -0
- package/test/neat/neat.reenable.adaptation.test.ts +18 -0
- package/test/neat/neat.rng.state.test.ts +22 -0
- package/test/neat/neat.spawn.add.test.ts +123 -0
- package/test/neat/neat.speciation.test.ts +96 -0
- package/test/neat/neat.species.allocation.telemetry.test.ts +26 -0
- package/test/neat/neat.species.history.csv.test.ts +24 -0
- package/test/neat/neat.telemetry.advanced.test.ts +226 -0
- package/test/neat/neat.telemetry.csv.lineage.test.ts +19 -0
- package/test/neat/neat.telemetry.parity.test.ts +42 -0
- package/test/neat/neat.telemetry.stream.test.ts +19 -0
- package/test/neat/neat.telemetry.test.ts +16 -0
- package/test/neat/neat.test.ts +422 -0
- package/test/neat/neat.utilities.test.ts +44 -0
- package/test/network/__suppress_console.ts +9 -0
- package/test/network/acyclic.topoorder.test.ts +17 -0
- package/test/network/checkpoint.metricshook.test.ts +36 -0
- package/test/network/error.handling.test.ts +581 -0
- package/test/network/evolution.test.ts +285 -0
- package/test/network/genetic.test.ts +208 -0
- package/test/network/learning.capability.test.ts +244 -0
- package/test/network/mutation.effects.test.ts +492 -0
- package/test/network/network.activate.test.ts +115 -0
- package/test/network/network.activateBatch.test.ts +30 -0
- package/test/network/network.deterministic.test.ts +64 -0
- package/test/network/network.evolve.branches.test.ts +75 -0
- package/test/network/network.evolve.multithread.branches.test.ts +83 -0
- package/test/network/network.evolve.test.ts +100 -0
- package/test/network/network.gating.removal.test.ts +93 -0
- package/test/network/network.mutate.additional.test.ts +145 -0
- package/test/network/network.mutate.edgecases.test.ts +101 -0
- package/test/network/network.mutate.test.ts +101 -0
- package/test/network/network.prune.earlyexit.test.ts +38 -0
- package/test/network/network.remove.errors.test.ts +45 -0
- package/test/network/network.slab.fallbacks.test.ts +22 -0
- package/test/network/network.stats.test.ts +45 -0
- package/test/network/network.training.advanced.test.ts +149 -0
- package/test/network/network.training.basic.test.ts +228 -0
- package/test/network/network.training.helpers.test.ts +183 -0
- package/test/network/onnx.export.test.ts +310 -0
- package/test/network/onnx.import.test.ts +129 -0
- package/test/network/pruning.topology.test.ts +282 -0
- package/test/network/regularization.determinism.test.ts +83 -0
- package/test/network/regularization.dropconnect.test.ts +17 -0
- package/test/network/regularization.dropconnect.validation.test.ts +18 -0
- package/test/network/regularization.stochasticdepth.test.ts +27 -0
- package/test/network/regularization.test.ts +843 -0
- package/test/network/regularization.weightnoise.test.ts +30 -0
- package/test/network/setupTests.ts +2 -0
- package/test/network/standalone.test.ts +332 -0
- package/test/network/structure.serialization.test.ts +660 -0
- package/test/training/training.determinism.mixed-precision.test.ts +134 -0
- package/test/training/training.earlystopping.test.ts +91 -0
- package/test/training/training.edge-cases.test.ts +91 -0
- package/test/training/training.extensions.test.ts +47 -0
- package/test/training/training.gradient.features.test.ts +110 -0
- package/test/training/training.gradient.refinements.test.ts +170 -0
- package/test/training/training.gradient.separate-bias.test.ts +41 -0
- package/test/training/training.optimizer.test.ts +48 -0
- package/test/training/training.plateau.smoothing.test.ts +58 -0
- package/test/training/training.smoothing.types.test.ts +174 -0
- package/test/training/training.train.options.coverage.test.ts +52 -0
- package/test/utils/console-helper.ts +76 -0
- package/test/utils/jest-setup.ts +60 -0
- package/test/utils/test-helpers.ts +175 -0
- package/tsconfig.docs.json +12 -0
- package/tsconfig.json +21 -0
- package/webpack.config.js +49 -0
|
@@ -0,0 +1,684 @@
|
|
|
1
|
+
import Rate from '../../src/methods/rate';
|
|
2
|
+
|
|
3
|
+
describe('Rate', () => {
|
|
4
|
+
const baseRate = 0.1;
|
|
5
|
+
|
|
6
|
+
describe('fixed()', () => {
|
|
7
|
+
const fixedRateFn = Rate.fixed();
|
|
8
|
+
|
|
9
|
+
describe('Scenario: At iteration 0', () => {
|
|
10
|
+
it('should return the base rate', () => {
|
|
11
|
+
// Act
|
|
12
|
+
const rate = fixedRateFn(baseRate, 0);
|
|
13
|
+
// Assert
|
|
14
|
+
expect(rate).toBe(baseRate);
|
|
15
|
+
});
|
|
16
|
+
it('should be non-negative', () => {
|
|
17
|
+
// Act
|
|
18
|
+
const rate = fixedRateFn(baseRate, 0);
|
|
19
|
+
// Assert
|
|
20
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('Scenario: At iteration 100', () => {
|
|
25
|
+
it('should return the base rate', () => {
|
|
26
|
+
// Act
|
|
27
|
+
const rate = fixedRateFn(baseRate, 100);
|
|
28
|
+
// Assert
|
|
29
|
+
expect(rate).toBe(baseRate);
|
|
30
|
+
});
|
|
31
|
+
it('should be non-negative', () => {
|
|
32
|
+
// Act
|
|
33
|
+
const rate = fixedRateFn(baseRate, 100);
|
|
34
|
+
// Assert
|
|
35
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('step()', () => {
|
|
41
|
+
const gamma = 0.9;
|
|
42
|
+
const stepSize = 10;
|
|
43
|
+
const stepRateFnCustom = Rate.step(gamma, stepSize);
|
|
44
|
+
const stepRateFnDefault = Rate.step();
|
|
45
|
+
|
|
46
|
+
describe('Custom parameters', () => {
|
|
47
|
+
it('should return the base rate before the first step', () => {
|
|
48
|
+
// Act
|
|
49
|
+
const rate = stepRateFnCustom(baseRate, 9);
|
|
50
|
+
// Assert
|
|
51
|
+
expect(rate).toBe(baseRate);
|
|
52
|
+
});
|
|
53
|
+
it('should be non-negative before the first step', () => {
|
|
54
|
+
// Act
|
|
55
|
+
const rate = stepRateFnCustom(baseRate, 9);
|
|
56
|
+
// Assert
|
|
57
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
58
|
+
});
|
|
59
|
+
it('should return the decayed rate at the first step', () => {
|
|
60
|
+
// Act
|
|
61
|
+
const rate = stepRateFnCustom(baseRate, 10);
|
|
62
|
+
// Assert
|
|
63
|
+
expect(rate).toBeCloseTo(baseRate * Math.pow(gamma, 1));
|
|
64
|
+
});
|
|
65
|
+
it('should be non-negative at the first step', () => {
|
|
66
|
+
// Act
|
|
67
|
+
const rate = stepRateFnCustom(baseRate, 10);
|
|
68
|
+
// Assert
|
|
69
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
70
|
+
});
|
|
71
|
+
it('should be less than or equal to baseRate at the first step', () => {
|
|
72
|
+
// Act
|
|
73
|
+
const rate = stepRateFnCustom(baseRate, 10);
|
|
74
|
+
// Assert
|
|
75
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
76
|
+
});
|
|
77
|
+
it('should return the decayed rate after multiple steps', () => {
|
|
78
|
+
// Act
|
|
79
|
+
const rate = stepRateFnCustom(baseRate, 25);
|
|
80
|
+
// Assert
|
|
81
|
+
expect(rate).toBeCloseTo(baseRate * Math.pow(gamma, 2));
|
|
82
|
+
});
|
|
83
|
+
it('should be non-negative after multiple steps', () => {
|
|
84
|
+
// Act
|
|
85
|
+
const rate = stepRateFnCustom(baseRate, 25);
|
|
86
|
+
// Assert
|
|
87
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
88
|
+
});
|
|
89
|
+
it('should be less than or equal to baseRate after multiple steps', () => {
|
|
90
|
+
// Act
|
|
91
|
+
const rate = stepRateFnCustom(baseRate, 25);
|
|
92
|
+
// Assert
|
|
93
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('Default parameters', () => {
|
|
98
|
+
it('should return the base rate before the first step', () => {
|
|
99
|
+
// Act
|
|
100
|
+
const rate = stepRateFnDefault(baseRate, 99);
|
|
101
|
+
// Assert
|
|
102
|
+
expect(rate).toBe(baseRate);
|
|
103
|
+
});
|
|
104
|
+
it('should be non-negative before the first step', () => {
|
|
105
|
+
// Act
|
|
106
|
+
const rate = stepRateFnDefault(baseRate, 99);
|
|
107
|
+
// Assert
|
|
108
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
109
|
+
});
|
|
110
|
+
it('should return the decayed rate at the first step', () => {
|
|
111
|
+
// Act
|
|
112
|
+
const rate = stepRateFnDefault(baseRate, 100);
|
|
113
|
+
// Assert
|
|
114
|
+
expect(rate).toBeCloseTo(baseRate * Math.pow(0.9, 1));
|
|
115
|
+
});
|
|
116
|
+
it('should be non-negative at the first step', () => {
|
|
117
|
+
// Act
|
|
118
|
+
const rate = stepRateFnDefault(baseRate, 100);
|
|
119
|
+
// Assert
|
|
120
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
121
|
+
});
|
|
122
|
+
it('should be less than or equal to baseRate at the first step', () => {
|
|
123
|
+
// Act
|
|
124
|
+
const rate = stepRateFnDefault(baseRate, 100);
|
|
125
|
+
// Assert
|
|
126
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe('exp()', () => {
|
|
132
|
+
const gamma = 0.95;
|
|
133
|
+
const expRateFnCustom = Rate.exp(gamma);
|
|
134
|
+
const expRateFnDefault = Rate.exp();
|
|
135
|
+
|
|
136
|
+
describe('Custom gamma', () => {
|
|
137
|
+
it('should return the base rate at iteration 0', () => {
|
|
138
|
+
// Act
|
|
139
|
+
const rate = expRateFnCustom(baseRate, 0);
|
|
140
|
+
// Assert
|
|
141
|
+
expect(rate).toBe(baseRate);
|
|
142
|
+
});
|
|
143
|
+
it('should be non-negative at iteration 0', () => {
|
|
144
|
+
// Act
|
|
145
|
+
const rate = expRateFnCustom(baseRate, 0);
|
|
146
|
+
// Assert
|
|
147
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
148
|
+
});
|
|
149
|
+
it('should return the decayed rate at iteration 1', () => {
|
|
150
|
+
// Act
|
|
151
|
+
const rate = expRateFnCustom(baseRate, 1);
|
|
152
|
+
// Assert
|
|
153
|
+
expect(rate).toBeCloseTo(baseRate * Math.pow(gamma, 1));
|
|
154
|
+
});
|
|
155
|
+
it('should be non-negative at iteration 1', () => {
|
|
156
|
+
// Act
|
|
157
|
+
const rate = expRateFnCustom(baseRate, 1);
|
|
158
|
+
// Assert
|
|
159
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
160
|
+
});
|
|
161
|
+
it('should be less than or equal to baseRate at iteration 1', () => {
|
|
162
|
+
// Act
|
|
163
|
+
const rate = expRateFnCustom(baseRate, 1);
|
|
164
|
+
// Assert
|
|
165
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
166
|
+
});
|
|
167
|
+
it('should return the decayed rate at iteration 10', () => {
|
|
168
|
+
// Act
|
|
169
|
+
const rate = expRateFnCustom(baseRate, 10);
|
|
170
|
+
// Assert
|
|
171
|
+
expect(rate).toBeCloseTo(baseRate * Math.pow(gamma, 10));
|
|
172
|
+
});
|
|
173
|
+
it('should be non-negative at iteration 10', () => {
|
|
174
|
+
// Act
|
|
175
|
+
const rate = expRateFnCustom(baseRate, 10);
|
|
176
|
+
// Assert
|
|
177
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
178
|
+
});
|
|
179
|
+
it('should be less than or equal to baseRate at iteration 10', () => {
|
|
180
|
+
// Act
|
|
181
|
+
const rate = expRateFnCustom(baseRate, 10);
|
|
182
|
+
// Assert
|
|
183
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('Default gamma', () => {
|
|
188
|
+
it('should return the base rate at iteration 0', () => {
|
|
189
|
+
// Act
|
|
190
|
+
const rate = expRateFnDefault(baseRate, 0);
|
|
191
|
+
// Assert
|
|
192
|
+
expect(rate).toBe(baseRate);
|
|
193
|
+
});
|
|
194
|
+
it('should be non-negative at iteration 0', () => {
|
|
195
|
+
// Act
|
|
196
|
+
const rate = expRateFnDefault(baseRate, 0);
|
|
197
|
+
// Assert
|
|
198
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
199
|
+
});
|
|
200
|
+
it('should return the decayed rate at iteration 10', () => {
|
|
201
|
+
// Act
|
|
202
|
+
const rate = expRateFnDefault(baseRate, 10);
|
|
203
|
+
// Assert
|
|
204
|
+
expect(rate).toBeCloseTo(baseRate * Math.pow(0.999, 10));
|
|
205
|
+
});
|
|
206
|
+
it('should be non-negative at iteration 10', () => {
|
|
207
|
+
// Act
|
|
208
|
+
const rate = expRateFnDefault(baseRate, 10);
|
|
209
|
+
// Assert
|
|
210
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
211
|
+
});
|
|
212
|
+
it('should be less than or equal to baseRate at iteration 10', () => {
|
|
213
|
+
// Act
|
|
214
|
+
const rate = expRateFnDefault(baseRate, 10);
|
|
215
|
+
// Assert
|
|
216
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
describe('inv()', () => {
|
|
222
|
+
const gamma = 0.01;
|
|
223
|
+
const power = 1.5;
|
|
224
|
+
const invRateFnCustom = Rate.inv(gamma, power);
|
|
225
|
+
const invRateFnDefault = Rate.inv();
|
|
226
|
+
|
|
227
|
+
describe('Custom parameters', () => {
|
|
228
|
+
it('should return the base rate at iteration 0', () => {
|
|
229
|
+
// Act
|
|
230
|
+
const rate = invRateFnCustom(baseRate, 0);
|
|
231
|
+
// Assert
|
|
232
|
+
expect(rate).toBeCloseTo(baseRate, 5);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('should be non-negative at iteration 0', () => {
|
|
236
|
+
// Act
|
|
237
|
+
const rate = invRateFnCustom(baseRate, 0);
|
|
238
|
+
// Assert
|
|
239
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it('should return the decayed rate at iteration 1', () => {
|
|
243
|
+
// Act
|
|
244
|
+
const rate = invRateFnCustom(baseRate, 1);
|
|
245
|
+
const expected = baseRate / (1 + gamma * Math.pow(1, power));
|
|
246
|
+
// Assert
|
|
247
|
+
expect(rate).toBeCloseTo(expected, 5);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it('should be non-negative at iteration 1', () => {
|
|
251
|
+
// Act
|
|
252
|
+
const rate = invRateFnCustom(baseRate, 1);
|
|
253
|
+
// Assert
|
|
254
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('should be less than or equal to baseRate at iteration 1', () => {
|
|
258
|
+
// Act
|
|
259
|
+
const rate = invRateFnCustom(baseRate, 1);
|
|
260
|
+
// Assert
|
|
261
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('should return the decayed rate at iteration 10', () => {
|
|
265
|
+
// Act
|
|
266
|
+
const rate = invRateFnCustom(baseRate, 10);
|
|
267
|
+
const expected = baseRate / (1 + gamma * Math.pow(10, power));
|
|
268
|
+
// Assert
|
|
269
|
+
expect(rate).toBeCloseTo(expected, 5);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('should be non-negative at iteration 10', () => {
|
|
273
|
+
// Act
|
|
274
|
+
const rate = invRateFnCustom(baseRate, 10);
|
|
275
|
+
// Assert
|
|
276
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('should be less than or equal to baseRate at iteration 10', () => {
|
|
280
|
+
// Act
|
|
281
|
+
const rate = invRateFnCustom(baseRate, 10);
|
|
282
|
+
// Assert
|
|
283
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
describe('Default parameters', () => {
|
|
288
|
+
it('should return the base rate at iteration 0', () => {
|
|
289
|
+
// Act
|
|
290
|
+
const rate = invRateFnDefault(baseRate, 0);
|
|
291
|
+
// Assert
|
|
292
|
+
expect(rate).toBeCloseTo(baseRate, 5);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('should be non-negative at iteration 0', () => {
|
|
296
|
+
// Act
|
|
297
|
+
const rate = invRateFnDefault(baseRate, 0);
|
|
298
|
+
// Assert
|
|
299
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('should return the decayed rate at iteration 10', () => {
|
|
303
|
+
// Act
|
|
304
|
+
const rate = invRateFnDefault(baseRate, 10);
|
|
305
|
+
const expected = baseRate / (1 + 0.001 * Math.pow(10, 2));
|
|
306
|
+
// Assert
|
|
307
|
+
expect(rate).toBeCloseTo(expected, 5);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('should be non-negative at iteration 10', () => {
|
|
311
|
+
// Act
|
|
312
|
+
const rate = invRateFnDefault(baseRate, 10);
|
|
313
|
+
// Assert
|
|
314
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it('should be less than or equal to baseRate at iteration 10', () => {
|
|
318
|
+
// Act
|
|
319
|
+
const rate = invRateFnDefault(baseRate, 10);
|
|
320
|
+
// Assert
|
|
321
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
describe('cosineAnnealing()', () => {
|
|
327
|
+
const period = 100;
|
|
328
|
+
const minRate = 0.01;
|
|
329
|
+
const cosineFnCustom = Rate.cosineAnnealing(period, minRate);
|
|
330
|
+
const cosineFnDefault = Rate.cosineAnnealing();
|
|
331
|
+
|
|
332
|
+
describe('Custom parameters', () => {
|
|
333
|
+
describe('At the start of the cycle', () => {
|
|
334
|
+
it('should return the base rate', () => {
|
|
335
|
+
// Arrange
|
|
336
|
+
// Act
|
|
337
|
+
const rate = cosineFnCustom(baseRate, 0);
|
|
338
|
+
// Assert
|
|
339
|
+
expect(rate).toBeCloseTo(baseRate);
|
|
340
|
+
});
|
|
341
|
+
it('should be greater than or equal to minRate', () => {
|
|
342
|
+
// Arrange
|
|
343
|
+
// Act
|
|
344
|
+
const rate = cosineFnCustom(baseRate, 0);
|
|
345
|
+
// Assert
|
|
346
|
+
expect(rate).toBeGreaterThanOrEqual(minRate);
|
|
347
|
+
});
|
|
348
|
+
it('should be less than or equal to baseRate', () => {
|
|
349
|
+
// Arrange
|
|
350
|
+
// Act
|
|
351
|
+
const rate = cosineFnCustom(baseRate, 0);
|
|
352
|
+
// Assert
|
|
353
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
describe('At the middle of the cycle', () => {
|
|
357
|
+
it('should return the average rate', () => {
|
|
358
|
+
// Arrange
|
|
359
|
+
// Act
|
|
360
|
+
const rate = cosineFnCustom(baseRate, period / 2);
|
|
361
|
+
// Assert
|
|
362
|
+
expect(rate).toBeCloseTo(minRate + (baseRate - minRate) * 0.5);
|
|
363
|
+
});
|
|
364
|
+
it('should be greater than or equal to minRate', () => {
|
|
365
|
+
// Arrange
|
|
366
|
+
// Act
|
|
367
|
+
const rate = cosineFnCustom(baseRate, period / 2);
|
|
368
|
+
// Assert
|
|
369
|
+
expect(rate).toBeGreaterThanOrEqual(minRate);
|
|
370
|
+
});
|
|
371
|
+
it('should be less than or equal to baseRate', () => {
|
|
372
|
+
// Arrange
|
|
373
|
+
// Act
|
|
374
|
+
const rate = cosineFnCustom(baseRate, period / 2);
|
|
375
|
+
// Assert
|
|
376
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
describe('Near the end of the cycle', () => {
|
|
380
|
+
it('should return the min rate', () => {
|
|
381
|
+
// Arrange
|
|
382
|
+
// Act
|
|
383
|
+
const rate = cosineFnCustom(baseRate, period - 1);
|
|
384
|
+
// Assert
|
|
385
|
+
expect(rate).toBeCloseTo(minRate, 2);
|
|
386
|
+
});
|
|
387
|
+
it('should be greater than or equal to minRate', () => {
|
|
388
|
+
// Arrange
|
|
389
|
+
// Act
|
|
390
|
+
const rate = cosineFnCustom(baseRate, period - 1);
|
|
391
|
+
// Assert
|
|
392
|
+
expect(rate).toBeGreaterThanOrEqual(minRate);
|
|
393
|
+
});
|
|
394
|
+
it('should be less than or equal to baseRate', () => {
|
|
395
|
+
// Arrange
|
|
396
|
+
// Act
|
|
397
|
+
const rate = cosineFnCustom(baseRate, period - 1);
|
|
398
|
+
// Assert
|
|
399
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
describe('At the start of the second cycle', () => {
|
|
403
|
+
it('should return the base rate', () => {
|
|
404
|
+
// Arrange
|
|
405
|
+
// Act
|
|
406
|
+
const rate = cosineFnCustom(baseRate, period);
|
|
407
|
+
// Assert
|
|
408
|
+
expect(rate).toBeCloseTo(baseRate);
|
|
409
|
+
});
|
|
410
|
+
it('should be greater than or equal to minRate', () => {
|
|
411
|
+
// Arrange
|
|
412
|
+
// Act
|
|
413
|
+
const rate = cosineFnCustom(baseRate, period);
|
|
414
|
+
// Assert
|
|
415
|
+
expect(rate).toBeGreaterThanOrEqual(minRate);
|
|
416
|
+
});
|
|
417
|
+
it('should be less than or equal to baseRate', () => {
|
|
418
|
+
// Arrange
|
|
419
|
+
// Act
|
|
420
|
+
const rate = cosineFnCustom(baseRate, period);
|
|
421
|
+
// Assert
|
|
422
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
describe('Default parameters', () => {
|
|
427
|
+
describe('At the start of the cycle', () => {
|
|
428
|
+
it('should return the base rate', () => {
|
|
429
|
+
// Arrange
|
|
430
|
+
// Act
|
|
431
|
+
const rate = cosineFnDefault(baseRate, 0);
|
|
432
|
+
// Assert
|
|
433
|
+
expect(rate).toBeCloseTo(baseRate);
|
|
434
|
+
});
|
|
435
|
+
it('should be greater than or equal to 0', () => {
|
|
436
|
+
// Arrange
|
|
437
|
+
// Act
|
|
438
|
+
const rate = cosineFnDefault(baseRate, 0);
|
|
439
|
+
// Assert
|
|
440
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
441
|
+
});
|
|
442
|
+
it('should be less than or equal to baseRate', () => {
|
|
443
|
+
// Arrange
|
|
444
|
+
// Act
|
|
445
|
+
const rate = cosineFnDefault(baseRate, 0);
|
|
446
|
+
// Assert
|
|
447
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
describe('At the middle of the cycle', () => {
|
|
451
|
+
it('should return half the base rate', () => {
|
|
452
|
+
// Arrange
|
|
453
|
+
// Act
|
|
454
|
+
const rate = cosineFnDefault(baseRate, 500);
|
|
455
|
+
// Assert
|
|
456
|
+
expect(rate).toBeCloseTo(baseRate * 0.5);
|
|
457
|
+
});
|
|
458
|
+
it('should be greater than or equal to 0', () => {
|
|
459
|
+
// Arrange
|
|
460
|
+
// Act
|
|
461
|
+
const rate = cosineFnDefault(baseRate, 500);
|
|
462
|
+
// Assert
|
|
463
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
464
|
+
});
|
|
465
|
+
it('should be less than or equal to baseRate', () => {
|
|
466
|
+
// Arrange
|
|
467
|
+
// Act
|
|
468
|
+
const rate = cosineFnDefault(baseRate, 500);
|
|
469
|
+
// Assert
|
|
470
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
describe('Near the end of the cycle', () => {
|
|
474
|
+
it('should return close to zero', () => {
|
|
475
|
+
// Arrange
|
|
476
|
+
// Act
|
|
477
|
+
const rate = cosineFnDefault(baseRate, 999);
|
|
478
|
+
// Assert
|
|
479
|
+
expect(rate).toBeCloseTo(0, 2);
|
|
480
|
+
});
|
|
481
|
+
it('should be greater than or equal to 0', () => {
|
|
482
|
+
// Arrange
|
|
483
|
+
// Act
|
|
484
|
+
const rate = cosineFnDefault(baseRate, 999);
|
|
485
|
+
// Assert
|
|
486
|
+
expect(rate).toBeGreaterThanOrEqual(0);
|
|
487
|
+
});
|
|
488
|
+
it('should be less than or equal to baseRate', () => {
|
|
489
|
+
// Arrange
|
|
490
|
+
// Act
|
|
491
|
+
const rate = cosineFnDefault(baseRate, 999);
|
|
492
|
+
// Assert
|
|
493
|
+
expect(rate).toBeLessThanOrEqual(baseRate);
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
describe('Rate utility methods', () => {
|
|
500
|
+
describe('fixed()', () => {
|
|
501
|
+
it('should always return the base rate regardless of iteration', () => {
|
|
502
|
+
// Arrange
|
|
503
|
+
const fn = Rate.fixed();
|
|
504
|
+
// Act
|
|
505
|
+
const result1 = fn(0.5, 0);
|
|
506
|
+
const result2 = fn(0.5, 100);
|
|
507
|
+
// Assert
|
|
508
|
+
expect(result1).toBe(0.5);
|
|
509
|
+
expect(result2).toBe(0.5);
|
|
510
|
+
});
|
|
511
|
+
});
|
|
512
|
+
describe('step()', () => {
|
|
513
|
+
it('should decay at correct steps', () => {
|
|
514
|
+
// Arrange
|
|
515
|
+
const fn = Rate.step(0.5, 10);
|
|
516
|
+
// Act
|
|
517
|
+
const r0 = fn(1, 0);
|
|
518
|
+
const r10 = fn(1, 10);
|
|
519
|
+
const r20 = fn(1, 20);
|
|
520
|
+
// Assert
|
|
521
|
+
expect(r0).toBe(1);
|
|
522
|
+
expect(r10).toBeCloseTo(0.5);
|
|
523
|
+
expect(r20).toBeCloseTo(0.25);
|
|
524
|
+
});
|
|
525
|
+
});
|
|
526
|
+
describe('exp()', () => {
|
|
527
|
+
it('should decay exponentially', () => {
|
|
528
|
+
// Arrange
|
|
529
|
+
const fn = Rate.exp(0.5);
|
|
530
|
+
// Act
|
|
531
|
+
const r0 = fn(1, 0);
|
|
532
|
+
const r1 = fn(1, 1);
|
|
533
|
+
const r2 = fn(1, 2);
|
|
534
|
+
// Assert
|
|
535
|
+
expect(r0).toBe(1);
|
|
536
|
+
expect(r1).toBeCloseTo(0.5);
|
|
537
|
+
expect(r2).toBeCloseTo(0.25);
|
|
538
|
+
});
|
|
539
|
+
});
|
|
540
|
+
describe('inv()', () => {
|
|
541
|
+
it('should decay inversely', () => {
|
|
542
|
+
// Arrange
|
|
543
|
+
const fn = Rate.inv(1, 1);
|
|
544
|
+
// Act
|
|
545
|
+
const r0 = fn(1, 0);
|
|
546
|
+
const r1 = fn(1, 1);
|
|
547
|
+
const r2 = fn(1, 2);
|
|
548
|
+
// Assert
|
|
549
|
+
expect(r0).toBe(1);
|
|
550
|
+
expect(r1).toBeCloseTo(0.5);
|
|
551
|
+
expect(r2).toBeCloseTo(0.333333, 5);
|
|
552
|
+
});
|
|
553
|
+
});
|
|
554
|
+
describe('cosineAnnealing()', () => {
|
|
555
|
+
it('should cycle between baseRate and minRate', () => {
|
|
556
|
+
// Arrange
|
|
557
|
+
const fn = Rate.cosineAnnealing(4, 0);
|
|
558
|
+
// Act
|
|
559
|
+
const r0 = fn(1, 0);
|
|
560
|
+
const r2 = fn(1, 2);
|
|
561
|
+
const r4 = fn(1, 4);
|
|
562
|
+
// Assert
|
|
563
|
+
expect(r0).toBeCloseTo(1);
|
|
564
|
+
expect(r2).toBeCloseTo(0.5);
|
|
565
|
+
expect(r4).toBeCloseTo(1);
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
describe('Invalid and edge input scenarios', () => {
|
|
571
|
+
const period = 100;
|
|
572
|
+
const minRate = 0.01;
|
|
573
|
+
const cosineFnCustom = Rate.cosineAnnealing(period, minRate);
|
|
574
|
+
const stepFn = Rate.step(0.9, 10);
|
|
575
|
+
const expFn = Rate.exp(0.95);
|
|
576
|
+
const invFn = Rate.inv(0.01, 1.5);
|
|
577
|
+
const fixedFn = Rate.fixed();
|
|
578
|
+
it('should return a valid rate for negative iteration', () => {
|
|
579
|
+
// Arrange
|
|
580
|
+
// Act
|
|
581
|
+
const rate = cosineFnCustom(baseRate, -1);
|
|
582
|
+
// Assert
|
|
583
|
+
expect(typeof rate).toBe('number');
|
|
584
|
+
});
|
|
585
|
+
it('should return a valid rate for negative baseRate', () => {
|
|
586
|
+
// Arrange
|
|
587
|
+
// Act
|
|
588
|
+
const rate = cosineFnCustom(-0.1, 0);
|
|
589
|
+
// Assert
|
|
590
|
+
expect(typeof rate).toBe('number');
|
|
591
|
+
});
|
|
592
|
+
it('should return a valid rate for non-integer iteration', () => {
|
|
593
|
+
// Arrange
|
|
594
|
+
// Act
|
|
595
|
+
const rate = cosineFnCustom(baseRate, 1.5);
|
|
596
|
+
// Assert
|
|
597
|
+
expect(typeof rate).toBe('number');
|
|
598
|
+
});
|
|
599
|
+
it('step: should return a valid rate for negative iteration', () => {
|
|
600
|
+
// Arrange
|
|
601
|
+
// Act
|
|
602
|
+
const rate = stepFn(baseRate, -5);
|
|
603
|
+
// Assert
|
|
604
|
+
expect(typeof rate).toBe('number');
|
|
605
|
+
});
|
|
606
|
+
it('exp: should return a valid rate for negative iteration', () => {
|
|
607
|
+
// Arrange
|
|
608
|
+
// Act
|
|
609
|
+
const rate = expFn(baseRate, -5);
|
|
610
|
+
// Assert
|
|
611
|
+
expect(typeof rate).toBe('number');
|
|
612
|
+
});
|
|
613
|
+
it('inv: should return a valid rate for negative iteration', () => {
|
|
614
|
+
// Arrange
|
|
615
|
+
// Act
|
|
616
|
+
const rate = invFn(baseRate, -5);
|
|
617
|
+
// Assert
|
|
618
|
+
expect(typeof rate).toBe('number');
|
|
619
|
+
});
|
|
620
|
+
it('step: should return a valid rate for negative baseRate', () => {
|
|
621
|
+
// Arrange
|
|
622
|
+
// Act
|
|
623
|
+
const rate = stepFn(-0.1, 0);
|
|
624
|
+
// Assert
|
|
625
|
+
expect(typeof rate).toBe('number');
|
|
626
|
+
});
|
|
627
|
+
it('exp: should return a valid rate for negative baseRate', () => {
|
|
628
|
+
// Arrange
|
|
629
|
+
// Act
|
|
630
|
+
const rate = expFn(-0.1, 0);
|
|
631
|
+
// Assert
|
|
632
|
+
expect(typeof rate).toBe('number');
|
|
633
|
+
});
|
|
634
|
+
it('inv: should return a valid rate for negative baseRate', () => {
|
|
635
|
+
// Arrange
|
|
636
|
+
// Act
|
|
637
|
+
const rate = invFn(-0.1, 0);
|
|
638
|
+
// Assert
|
|
639
|
+
expect(typeof rate).toBe('number');
|
|
640
|
+
});
|
|
641
|
+
it('step: should return a valid rate for non-integer iteration', () => {
|
|
642
|
+
// Arrange
|
|
643
|
+
// Act
|
|
644
|
+
const rate = stepFn(baseRate, 1.5);
|
|
645
|
+
// Assert
|
|
646
|
+
expect(typeof rate).toBe('number');
|
|
647
|
+
});
|
|
648
|
+
it('exp: should return a valid rate for non-integer iteration', () => {
|
|
649
|
+
// Arrange
|
|
650
|
+
// Act
|
|
651
|
+
const rate = expFn(baseRate, 1.5);
|
|
652
|
+
// Assert
|
|
653
|
+
expect(typeof rate).toBe('number');
|
|
654
|
+
});
|
|
655
|
+
it('inv: should return a valid rate for non-integer iteration', () => {
|
|
656
|
+
// Arrange
|
|
657
|
+
// Act
|
|
658
|
+
const rate = invFn(baseRate, 1.5);
|
|
659
|
+
// Assert
|
|
660
|
+
expect(typeof rate).toBe('number');
|
|
661
|
+
});
|
|
662
|
+
it('fixed: should return the base rate for negative iteration', () => {
|
|
663
|
+
// Arrange
|
|
664
|
+
// Act
|
|
665
|
+
const rate = fixedFn(baseRate, -10);
|
|
666
|
+
// Assert
|
|
667
|
+
expect(rate).toBe(baseRate);
|
|
668
|
+
});
|
|
669
|
+
it('fixed: should return the base rate for negative baseRate', () => {
|
|
670
|
+
// Arrange
|
|
671
|
+
// Act
|
|
672
|
+
const rate = fixedFn(-0.1, 0);
|
|
673
|
+
// Assert
|
|
674
|
+
expect(rate).toBe(-0.1);
|
|
675
|
+
});
|
|
676
|
+
it('fixed: should return the base rate for non-integer iteration', () => {
|
|
677
|
+
// Arrange
|
|
678
|
+
// Act
|
|
679
|
+
const rate = fixedFn(baseRate, 1.5);
|
|
680
|
+
// Assert
|
|
681
|
+
expect(rate).toBe(baseRate);
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
});
|