85 lines
3.7 KiB
JavaScript
85 lines
3.7 KiB
JavaScript
|
|
// Input-validation tests for the Wickra Node bindings: malformed constructor
|
||
|
|
// parameters and mismatched batch inputs must raise a JS Error (the napi
|
||
|
|
// wrapper turns the Rust `Err` into a thrown Error), not crash the process.
|
||
|
|
// Node counterpart of bindings/python/tests/test_input_validation.py.
|
||
|
|
|
||
|
|
const test = require('node:test');
|
||
|
|
const assert = require('node:assert/strict');
|
||
|
|
const wickra = require('..');
|
||
|
|
|
||
|
|
// --- Constructors reject invalid periods / parameters ---
|
||
|
|
|
||
|
|
test('ATR rejects a zero period at construction', () => {
|
||
|
|
// ATR validates its period (it drives the Wilder-smoothing length). The
|
||
|
|
// plain moving averages (SMA/EMA/RSI/StdDev) instead treat period 0 as a
|
||
|
|
// warmup-1 pass-through rather than an error, so they are not asserted here.
|
||
|
|
assert.throws(() => new wickra.ATR(0), /.*/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('MACD rejects zero and non-increasing fast/slow periods', () => {
|
||
|
|
assert.throws(() => new wickra.MACD(0, 0, 0), /.*/);
|
||
|
|
// fast must be strictly less than slow.
|
||
|
|
assert.throws(() => new wickra.MACD(26, 12, 9), /.*/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('BollingerBands rejects a negative standard-deviation multiplier', () => {
|
||
|
|
assert.throws(() => new wickra.BollingerBands(20, -1), /.*/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('PSAR rejects a step greater than its maximum', () => {
|
||
|
|
assert.throws(() => new wickra.PSAR(0.3, 0.02, 0.2), /.*/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('ValueArea rejects zero periods and out-of-range value-area percentages', () => {
|
||
|
|
assert.throws(() => new wickra.ValueArea(0, 50, 0.7), /.*/);
|
||
|
|
assert.throws(() => new wickra.ValueArea(20, 0, 0.7), /.*/);
|
||
|
|
assert.throws(() => new wickra.ValueArea(20, 50, 0.0), /.*/);
|
||
|
|
assert.throws(() => new wickra.ValueArea(20, 50, 1.5), /.*/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('InitialBalance and OpeningRange reject a zero period', () => {
|
||
|
|
assert.throws(() => new wickra.InitialBalance(0), /.*/);
|
||
|
|
assert.throws(() => new wickra.OpeningRange(0), /.*/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('Ichimoku rejects zero and non-increasing periods', () => {
|
||
|
|
assert.throws(() => new wickra.Ichimoku(0, 26, 52, 26), /.*/);
|
||
|
|
assert.throws(() => new wickra.Ichimoku(9, 26, 52, 0), /.*/);
|
||
|
|
// Periods must satisfy tenkan < kijun < senkouB.
|
||
|
|
assert.throws(() => new wickra.Ichimoku(26, 9, 52, 26), /.*/);
|
||
|
|
assert.throws(() => new wickra.Ichimoku(9, 52, 52, 26), /.*/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('Family 10 (Ehlers / cycle) indicators reject invalid parameters', () => {
|
||
|
|
// InverseFisherTransform needs a non-zero scaling factor.
|
||
|
|
assert.throws(() => new wickra.InverseFisherTransform(0.0), /.*/);
|
||
|
|
// DecyclerOscillator / RoofingFilter need the short cutoff below the long one.
|
||
|
|
assert.throws(() => new wickra.DecyclerOscillator(30, 10), /.*/);
|
||
|
|
assert.throws(() => new wickra.RoofingFilter(48, 10), /.*/);
|
||
|
|
// MAMA needs fast limit > slow limit.
|
||
|
|
assert.throws(() => new wickra.MAMA(0.05, 0.5), /.*/);
|
||
|
|
// EmpiricalModeDecomposition needs a positive fraction.
|
||
|
|
assert.throws(() => new wickra.EmpiricalModeDecomposition(20, 0.0), /.*/);
|
||
|
|
// NOTE: SuperSmoother(0) / FisherTransform(0) are NOT asserted: the Node
|
||
|
|
// binding treats their period 0 as a warmup-1 pass-through (same as the
|
||
|
|
// simple moving averages) rather than an error.
|
||
|
|
});
|
||
|
|
|
||
|
|
// --- Batch methods reject mismatched input lengths ---
|
||
|
|
|
||
|
|
test('candle batch methods reject unequal-length columns', () => {
|
||
|
|
const high = [10, 11, 12];
|
||
|
|
const low = [9, 10]; // one short
|
||
|
|
const close = [9.5, 10.5, 11.5];
|
||
|
|
assert.throws(() => new wickra.ATR(14).batch(high, low, close), /.*/);
|
||
|
|
assert.throws(() => new wickra.WilliamsR(14).batch(high, low, close), /.*/);
|
||
|
|
assert.throws(() => new wickra.Aroon(14).batch(high, low), /.*/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('ValueArea batch rejects unequal-length columns', () => {
|
||
|
|
const high = [1, 2, 3];
|
||
|
|
const low = [0.5, 1.5]; // short
|
||
|
|
const volume = [10, 10, 10];
|
||
|
|
assert.throws(() => new wickra.ValueArea(2, 10, 0.7).batch(high, low, volume), /.*/);
|
||
|
|
});
|