#define _POSIX_C_SOURCE 200809L #include #include #include #include "ts.h" bool ts_test_edge_cases( void ) { bool result = true; /* === NULL input === */ /* average with NULL input should return -1 */ { uint_t k = 3; int ret = ts_average(NULL, 0, NULL, 0, 5, (ts_constant_t *)&k); result &= (ret == -1); } /* rsi with NULL input should return -1 */ { uint_t k = 3; int ret = ts_rsi(NULL, 0, NULL, 0, 5, (ts_constant_t *)&k); result &= (ret == -1); } /* === n = 0 (empty input) === */ /* average with n=0 should return early, no crash */ { uint_t k = 3; int ret = ts_average(NULL, 0, NULL, 0, 0, (ts_constant_t *)&k); result &= (ret == -1); } /* rsi with n=0 should not crash */ { uint_t k = 3; int ret = ts_rsi(NULL, 0, NULL, 0, 0, (ts_constant_t *)&k); result &= (ret == -1); } /* deviation_standard with n=0 should return early */ { uint_t k = 3; int ret = ts_deviation_standard(NULL, 0, NULL, 0, 0, (ts_constant_t *)&k); result &= (ret == -1); } /* variance with n=0 should return early */ { uint_t k = 3; int ret = ts_variance(NULL, 0, NULL, 0, 0, (ts_constant_t *)&k); result &= (ret == -1); } /* === n = 1 (single element) === */ /* average with n=1, k=1 should produce the element itself */ { fp_t const x[] = {5}; fp_t const e[] = {5}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 1; result &= ts_test(ts_average, ts_average_offset, inp, exp, 1, (ts_constant_t *)&k, &ts_average_p); } /* deviation_standard with n=1, k=1 should produce 0 */ { fp_t const x[] = {5}; fp_t const e[] = {0}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 1; result &= ts_test(ts_deviation_standard, ts_deviation_standard_offset, inp, exp, 1, (ts_constant_t *)&k, &ts_deviation_standard_p); } /* variance with n=1, k=1 should produce 0 */ { fp_t const x[] = {5}; fp_t const e[] = {0}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 1; result &= ts_test(ts_variance, ts_variance_offset, inp, exp, 1, (ts_constant_t *)&k, &ts_variance_p); } /* === k = 0 (zero period) === */ /* average with k=0 should return early */ { fp_t x[] = {1, 2, 3, 4, 5}; fp_t y[5] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 0; int ret = ts_average(out, 1, inp, 1, 5, (ts_constant_t *)&k); result &= (ret == -1); } /* rsi with k=0 should return early */ { fp_t x[] = {1, 2, 3, 4, 5}; fp_t y[5] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 0; int ret = ts_rsi(out, 1, inp, 1, 5, (ts_constant_t *)&k); result &= (ret == -1); } /* deviation_standard with k=0 should return early */ { fp_t x[] = {1, 2, 3, 4, 5}; fp_t y[5] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 0; int ret = ts_deviation_standard(out, 1, inp, 1, 5, (ts_constant_t *)&k); result &= (ret == -1); } /* variance with k=0 should return early */ { fp_t x[] = {1, 2, 3, 4, 5}; fp_t y[5] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 0; int ret = ts_variance(out, 1, inp, 1, 5, (ts_constant_t *)&k); result &= (ret == -1); } /* === k > n (period exceeds data) === */ /* average with k > n should return early */ { fp_t x[] = {1, 2, 3}; fp_t y[3] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 10; int ret = ts_average(out, 1, inp, 1, 3, (ts_constant_t *)&k); result &= (ret == -1); } /* deviation_standard with k > n should return early */ { fp_t x[] = {1, 2, 3}; fp_t y[3] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 10; int ret = ts_deviation_standard(out, 1, inp, 1, 3, (ts_constant_t *)&k); result &= (ret == -1); } /* variance with k > n should return early */ { fp_t x[] = {1, 2, 3}; fp_t y[3] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 10; int ret = ts_variance(out, 1, inp, 1, 3, (ts_constant_t *)&k); result &= (ret == -1); } /* === All-zero input === */ /* average with all-zero input should produce zeros */ { fp_t const x[] = {0, 0, 0, 0, 0}; fp_t const e[] = {0, 0, 0}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 3; result &= ts_test(ts_average, ts_average_offset, inp, exp, 5, (ts_constant_t *)&k, &ts_average_p); } /* rsi with all-zero input should not crash (all gains/losses are 0) */ { fp_t const x[] = {0, 0, 0, 0, 0, 0, 0}; fp_t const e[] = {100, 100, 100, 100, 100}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 2; result &= ts_test(ts_rsi, ts_rsi_offset, inp, exp, 7, (ts_constant_t *)&k, &ts_rsi_p); } /* deviation_standard with all-zero input should produce 0 */ { fp_t const x[] = {0, 0, 0, 0, 0}; fp_t const e[] = {0, 0, 0}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 3; result &= ts_test(ts_deviation_standard, ts_deviation_standard_offset, inp, exp, 5, (ts_constant_t *)&k, &ts_deviation_standard_p); } /* variance with all-zero input should produce 0 */ { fp_t const x[] = {0, 0, 0, 0, 0}; fp_t const e[] = {0, 0, 0}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 3; result &= ts_test(ts_variance, ts_variance_offset, inp, exp, 5, (ts_constant_t *)&k, &ts_variance_p); } /* === All-same input (zero variance) === */ /* average with all-same input should produce that value */ { fp_t const x[] = {7, 7, 7, 7, 7}; fp_t const e[] = {7, 7, 7}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 3; result &= ts_test(ts_average, ts_average_offset, inp, exp, 5, (ts_constant_t *)&k, &ts_average_p); } /* rsi with all-same input should produce 100 (no losses) */ { fp_t const x[] = {5, 5, 5, 5, 5, 5, 5}; fp_t const e[] = {100, 100, 100, 100, 100}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 2; result &= ts_test(ts_rsi, ts_rsi_offset, inp, exp, 7, (ts_constant_t *)&k, &ts_rsi_p); } /* deviation_standard with all-same input should produce 0 */ { fp_t const x[] = {3, 3, 3, 3, 3}; fp_t const e[] = {0, 0, 0}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 3; result &= ts_test(ts_deviation_standard, ts_deviation_standard_offset, inp, exp, 5, (ts_constant_t *)&k, &ts_deviation_standard_p); } /* variance with all-same input should produce 0 */ { fp_t const x[] = {3, 3, 3, 3, 3}; fp_t const e[] = {0, 0, 0}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 3; result &= ts_test(ts_variance, ts_variance_offset, inp, exp, 5, (ts_constant_t *)&k, &ts_variance_p); } /* === n == k boundary === */ /* average with n==k should succeed (produces 1 output) */ { fp_t const x[] = {1, 2, 3}; fp_t const e[] = {2}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 3; result &= ts_test(ts_average, ts_average_offset, inp, exp, 3, (ts_constant_t *)&k, &ts_average_p); } /* rsi with n==k should fail (requires n > k) */ { fp_t x[] = {1, 2, 3}; fp_t y[3] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 3; int ret = ts_rsi(out, 1, inp, 1, 3, (ts_constant_t *)&k); result &= (ret == -1); } /* === NaN input === */ /* average with NaN input should return -1 (invalid input) */ { fp_t x[] = {NAN, 1.0, 2.0, 3.0, 4.0}; fp_t y[5] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 3; int ret = ts_average(out, 1, inp, 1, 5, (ts_constant_t *)&k); result &= (ret == -1); } /* === Monotonic input (RSI edge cases) === */ /* rsi with strictly ascending input should produce 100 */ { fp_t const x[] = {1, 2, 3, 4, 5, 6, 7}; fp_t const e[] = {100, 100, 100, 100, 100}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 2; result &= ts_test(ts_rsi, ts_rsi_offset, inp, exp, 7, (ts_constant_t *)&k, &ts_rsi_p); } /* rsi with strictly descending input should produce 0 */ { fp_t const x[] = {7, 6, 5, 4, 3, 2, 1}; fp_t const e[] = {0, 0, 0, 0, 0}; fp_t const * const inp[1] = {x}; fp_t const * const exp[1] = {e}; uint_t k = 2; result &= ts_test(ts_rsi, ts_rsi_offset, inp, exp, 7, (ts_constant_t *)&k, &ts_rsi_p); } /* === rsi with k > n === */ { fp_t x[] = {1, 2, 3}; fp_t y[3] = {0}; fp_t const * const inp[1] = {x}; fp_t * const out[1] = {y}; uint_t k = 10; int ret = ts_rsi(out, 1, inp, 1, 3, (ts_constant_t *)&k); result &= (ret == -1); } return result; }