Added tests for XYShape validator

This commit is contained in:
Ozzie Gooen 2022-04-28 14:52:44 -04:00
parent 1cca9bde38
commit 5dd0292b52
4 changed files with 59 additions and 46 deletions

View File

@ -19,6 +19,24 @@ let pointSetDist3: PointSetTypes.xyShape = {
} }
describe("XYShapes", () => { describe("XYShapes", () => {
describe("Validator", () => {
makeTest("with no errors", XYShape.T.Validator.validate(pointSetDist1), None)
makeTest(
"when empty",
XYShape.T.Validator.validate({xs: [], ys: []})->E.O2.fmap(Errors.toString),
Some("XYShape validate Xs is empty"),
)
makeTest(
"when not sorted, different lengths, and not finite",
XYShape.T.Validator.validate({xs: [2.0, 1.0, infinity, 0.0], ys: [3.0, infinity]})->E.O2.fmap(
Errors.toString,
),
Some(
"Multiple Errors: [XYShape validate Xs is not sorted], [XYShape validate Xs and Ys have different lengths. Xs has length 4 and Ys has length 2], [XYShape validate Xs is not finite. Example value: Infinity], [XYShape validate Ys is not finite. Example value: Infinity]",
),
)
})
describe("logScorePoint", () => { describe("logScorePoint", () => {
makeTest("When identical", XYShape.logScorePoint(30, pointSetDist1, pointSetDist1), Some(0.0)) makeTest("When identical", XYShape.logScorePoint(30, pointSetDist1, pointSetDist1), Some(0.0))
makeTest( makeTest(
@ -32,16 +50,6 @@ describe("XYShapes", () => {
Some(210.3721280423322), Some(210.3721280423322),
) )
}) })
// describe("transverse", () => {
// makeTest(
// "When very different",
// XYShape.Transversal._transverse(
// (aCurrent, aLast) => aCurrent +. aLast,
// [|1.0, 2.0, 3.0, 4.0|],
// ),
// [|1.0, 3.0, 6.0, 10.0|],
// )
// });
describe("integrateWithTriangles", () => describe("integrateWithTriangles", () =>
makeTest( makeTest(
"integrates correctly", "integrates correctly",

View File

@ -500,7 +500,11 @@ module A = {
let getBelowZero = (t: t) => Belt.Array.getBy(t, r => r < 0.0) let getBelowZero = (t: t) => Belt.Array.getBy(t, r => r < 0.0)
let isSorted = (t: t): bool => let isSorted = (t: t): bool =>
if Array.length(t) < 1 {
true
} else {
reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second) reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second)
}
//Passing true for the exclusive parameter excludes both endpoints of the range. //Passing true for the exclusive parameter excludes both endpoints of the range.
//https://jstat.github.io/all.html //https://jstat.github.io/all.html

View File

@ -25,5 +25,7 @@ let rec toString = (t: error) =>
`${fnName} ${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString( `${fnName} ${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString(
p1Length, p1Length,
)} and ${p2Name} has length ${E.I.toString(p2Length)}` )} and ${p2Name} has length ${E.I.toString(p2Length)}`
| Multiple(errors) => `Multiple Errors: ${E.A2.fmap(errors, toString) |> E.A.joinWith(", ")}` | Multiple(errors) =>
`Multiple Errors: ${E.A2.fmap(errors, toString)->E.A2.fmap(r => `[${r}]`)
|> E.A.joinWith(", ")}`
} }

View File

@ -60,10 +60,8 @@ module T = {
let fromZippedArray = (pairs: array<(float, float)>): t => pairs |> Belt.Array.unzip |> fromArray let fromZippedArray = (pairs: array<(float, float)>): t => pairs |> Belt.Array.unzip |> fromArray
let equallyDividedXs = (t: t, newLength) => E.A.Floats.range(minX(t), maxX(t), newLength) let equallyDividedXs = (t: t, newLength) => E.A.Floats.range(minX(t), maxX(t), newLength)
let toJs = (t: t) => {"xs": t.xs, "ys": t.ys} let toJs = (t: t) => {"xs": t.xs, "ys": t.ys}
}
module Validator = { module Validator = {
type t = T.t
let fnName = "XYShape validate" let fnName = "XYShape validate"
let property = (propertyName: string): Errors.property => { let property = (propertyName: string): Errors.property => {
fnName: fnName, fnName: fnName,
@ -76,20 +74,20 @@ module Validator = {
fnName: fnName, fnName: fnName,
p1Name: "Xs", p1Name: "Xs",
p2Name: "Ys", p2Name: "Ys",
p1Length: E.A.length(T.xs(t)), p1Length: E.A.length(xs(t)),
p2Length: E.A.length(T.ys(t)), p2Length: E.A.length(ys(t)),
}) })
let areXsSorted = (t: t) => E.A.Floats.isSorted(T.xs(t)) let areXsSorted = (t: t) => E.A.Floats.isSorted(xs(t))
let areXsEmpty = (t: t) => E.A.length(t.xs) == 0 let areXsEmpty = (t: t) => E.A.length(xs(t)) == 0
let getNonFiniteXs = (t: t) => t->T.xs->E.A.Floats.getNonFinite let getNonFiniteXs = (t: t) => t->xs->E.A.Floats.getNonFinite
let getNonFiniteYs = (t: t) => t->T.ys->E.A.Floats.getNonFinite let getNonFiniteYs = (t: t) => t->ys->E.A.Floats.getNonFinite
let validate = (t: t) => { let validate = (t: t) => {
let xsNotSorted = areXsSorted(t) ? None : Some(notSortedError("Xs")) let xsNotSorted = areXsSorted(t) ? None : Some(notSortedError("Xs"))
let xsEmpty = areXsEmpty(t) ? None : Some(isEmptyError("Xs")) let xsEmpty = areXsEmpty(t) ? Some(isEmptyError("Xs")) : None
let differentLengths = let differentLengths =
E.A.length(T.xs(t)) !== E.A.length(T.ys(t)) ? Some(differentLengthsError(t)) : None E.A.length(xs(t)) !== E.A.length(ys(t)) ? Some(differentLengthsError(t)) : None
let xsNotFinite = getNonFiniteXs(t)->E.O2.fmap(notFiniteError("Xs")) let xsNotFinite = getNonFiniteXs(t)->E.O2.fmap(notFiniteError("Xs"))
let ysNotFinite = getNonFiniteYs(t)->E.O2.fmap(notFiniteError("Ys")) let ysNotFinite = getNonFiniteYs(t)->E.O2.fmap(notFiniteError("Ys"))
[xsNotSorted, xsEmpty, differentLengths, xsNotFinite, ysNotFinite] [xsNotSorted, xsEmpty, differentLengths, xsNotFinite, ysNotFinite]
@ -97,6 +95,7 @@ module Validator = {
->Errors.mapErrorArrayToError ->Errors.mapErrorArrayToError
} }
} }
}
module Ts = { module Ts = {
type t = T.ts type t = T.ts