Refactored errors for XYShape
This commit is contained in:
parent
95a4bac49b
commit
94d4a38540
|
@ -18,21 +18,22 @@ let pointSetDist3: PointSetTypes.xyShape = {
|
||||||
ys: [0.2, 0.5, 0.8],
|
ys: [0.2, 0.5, 0.8],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let makeAndGetErrorString = (~xs, ~ys) =>
|
||||||
|
XYShape.T.make(~xs, ~ys)->E.R.getError->E.O2.fmap(XYShape.Error.toString)
|
||||||
|
|
||||||
describe("XYShapes", () => {
|
describe("XYShapes", () => {
|
||||||
describe("Validator", () => {
|
describe("Validator", () => {
|
||||||
makeTest("with no errors", XYShape.T.Validator.validate(pointSetDist1), None)
|
|
||||||
makeTest(
|
makeTest(
|
||||||
"when empty",
|
"with no errors",
|
||||||
XYShape.T.Validator.validate({xs: [], ys: []})->E.O2.fmap(Errors.toString),
|
makeAndGetErrorString(~xs=[1.0, 4.0, 8.0], ~ys=[0.2, 0.4, 0.8]),
|
||||||
Some("XYShape validate Xs is empty"),
|
None,
|
||||||
)
|
)
|
||||||
|
makeTest("when empty", makeAndGetErrorString(~xs=[], ~ys=[]), Some("Xs is empty"))
|
||||||
makeTest(
|
makeTest(
|
||||||
"when not sorted, different lengths, and not finite",
|
"when not sorted, different lengths, and not finite",
|
||||||
XYShape.T.Validator.validate({xs: [2.0, 1.0, infinity, 0.0], ys: [3.0, Js.Float._NaN]})->E.O2.fmap(
|
makeAndGetErrorString(~xs=[2.0, 1.0, infinity, 0.0], ~ys=[3.0, Js.Float._NaN]),
|
||||||
Errors.toString,
|
|
||||||
),
|
|
||||||
Some(
|
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: NaN]",
|
"Multiple Errors: [Xs is not sorted], [Xs and Ys have different lengths. Xs has length 4 and Ys has length 2], [Xs is not finite. Example value: Infinity], [Ys is not finite. Example value: NaN]",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -19,6 +19,7 @@ type error =
|
||||||
| RequestedStrategyInvalidError(string)
|
| RequestedStrategyInvalidError(string)
|
||||||
| LogarithmOfDistributionError(string)
|
| LogarithmOfDistributionError(string)
|
||||||
| OtherError(string)
|
| OtherError(string)
|
||||||
|
| XYShapeError(XYShape.error)
|
||||||
|
|
||||||
@genType
|
@genType
|
||||||
module Error = {
|
module Error = {
|
||||||
|
@ -39,6 +40,7 @@ module Error = {
|
||||||
| PointSetConversionError(err) => SampleSetDist.pointsetConversionErrorToString(err)
|
| PointSetConversionError(err) => SampleSetDist.pointsetConversionErrorToString(err)
|
||||||
| SparklineError(err) => PointSetTypes.sparklineErrorToString(err)
|
| SparklineError(err) => PointSetTypes.sparklineErrorToString(err)
|
||||||
| RequestedStrategyInvalidError(err) => `Requested strategy invalid: ${err}`
|
| RequestedStrategyInvalidError(err) => `Requested strategy invalid: ${err}`
|
||||||
|
| XYShapeError(err) => `XY Shape Error: ${XYShape.Error.toString(err)}`
|
||||||
| OtherError(s) => s
|
| OtherError(s) => s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,12 @@ exception Assertion(string)
|
||||||
module R = {
|
module R = {
|
||||||
let result = Rationale.Result.result
|
let result = Rationale.Result.result
|
||||||
let id = e => e |> result(U.id, U.id)
|
let id = e => e |> result(U.id, U.id)
|
||||||
|
let isOk = Belt.Result.isOk
|
||||||
|
let getError = (r: result<'a, 'b>) =>
|
||||||
|
switch r {
|
||||||
|
| Ok(_) => None
|
||||||
|
| Error(e) => Some(e)
|
||||||
|
}
|
||||||
let fmap = Rationale.Result.fmap
|
let fmap = Rationale.Result.fmap
|
||||||
let bind = Rationale.Result.bind
|
let bind = Rationale.Result.bind
|
||||||
let toExn = (msg: string, x: result<'a, 'b>): 'a =>
|
let toExn = (msg: string, x: result<'a, 'b>): 'a =>
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
type property = {fnName: string, propertyName: string}
|
|
||||||
|
|
||||||
type rec error =
|
|
||||||
| NotSorted(property)
|
|
||||||
| IsEmpty(property)
|
|
||||||
| NotFinite(property, float)
|
|
||||||
| DifferentLengths({fnName: string, p1Name: string, p2Name: string, p1Length: int, p2Length: int})
|
|
||||||
| Multiple(array<error>)
|
|
||||||
|
|
||||||
let mapErrorArrayToError = (errors: array<error>): option<error> => {
|
|
||||||
switch errors {
|
|
||||||
| [] => None
|
|
||||||
| [error] => Some(error)
|
|
||||||
| _ => Some(Multiple(errors))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let rec toString = (t: error) =>
|
|
||||||
switch t {
|
|
||||||
| NotSorted({fnName, propertyName}) => `${fnName} ${propertyName} is not sorted`
|
|
||||||
| IsEmpty({fnName, propertyName}) => `${fnName} ${propertyName} is empty`
|
|
||||||
| NotFinite({fnName, propertyName}, exampleValue) =>
|
|
||||||
`${fnName} ${propertyName} is not finite. Example value: ${E.Float.toString(exampleValue)}`
|
|
||||||
| DifferentLengths({fnName, p1Name, p2Name, p1Length, p2Length}) =>
|
|
||||||
`${fnName} ${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString(
|
|
||||||
p1Length,
|
|
||||||
)} and ${p2Name} has length ${E.I.toString(p2Length)}`
|
|
||||||
| Multiple(errors) =>
|
|
||||||
`Multiple Errors: ${E.A2.fmap(errors, toString)->E.A2.fmap(r => `[${r}]`)
|
|
||||||
|> E.A.joinWith(", ")}`
|
|
||||||
}
|
|
|
@ -4,6 +4,42 @@ type xyShape = {
|
||||||
ys: array<float>,
|
ys: array<float>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type propertyName = string
|
||||||
|
|
||||||
|
@genType
|
||||||
|
type rec error =
|
||||||
|
| NotSorted(propertyName)
|
||||||
|
| IsEmpty(propertyName)
|
||||||
|
| NotFinite(propertyName, float)
|
||||||
|
| DifferentLengths({p1Name: string, p2Name: string, p1Length: int, p2Length: int})
|
||||||
|
| MultipleErrors(array<error>)
|
||||||
|
|
||||||
|
@genType
|
||||||
|
module Error = {
|
||||||
|
let mapErrorArrayToError = (errors: array<error>): option<error> => {
|
||||||
|
switch errors {
|
||||||
|
| [] => None
|
||||||
|
| [error] => Some(error)
|
||||||
|
| _ => Some(MultipleErrors(errors))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let rec toString = (t: error) =>
|
||||||
|
switch t {
|
||||||
|
| NotSorted(propertyName) => `${propertyName} is not sorted`
|
||||||
|
| IsEmpty(propertyName) => `${propertyName} is empty`
|
||||||
|
| NotFinite(propertyName, exampleValue) =>
|
||||||
|
`${propertyName} is not finite. Example value: ${E.Float.toString(exampleValue)}`
|
||||||
|
| DifferentLengths({p1Name, p2Name, p1Length, p2Length}) =>
|
||||||
|
`${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString(
|
||||||
|
p1Length,
|
||||||
|
)} and ${p2Name} has length ${E.I.toString(p2Length)}`
|
||||||
|
| MultipleErrors(errors) =>
|
||||||
|
`Multiple Errors: ${E.A2.fmap(errors, toString)->E.A2.fmap(r => `[${r}]`)
|
||||||
|
|> E.A.joinWith(", ")}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@genType
|
@genType
|
||||||
type interpolationStrategy = [
|
type interpolationStrategy = [
|
||||||
| #Stepwise
|
| #Stepwise
|
||||||
|
@ -63,15 +99,10 @@ module T = {
|
||||||
|
|
||||||
module Validator = {
|
module Validator = {
|
||||||
let fnName = "XYShape validate"
|
let fnName = "XYShape validate"
|
||||||
let property = (propertyName: string): Errors.property => {
|
let notSortedError = (p: string): error => NotSorted(p)
|
||||||
fnName: fnName,
|
let notFiniteError = (p, exampleValue): error => NotFinite(p, exampleValue)
|
||||||
propertyName: propertyName,
|
let isEmptyError = (propertyName): error => IsEmpty(propertyName)
|
||||||
}
|
let differentLengthsError = (t): error => DifferentLengths({
|
||||||
let notSortedError = (p: string): Errors.error => NotSorted(property(p))
|
|
||||||
let notFiniteError = (p, exampleValue): Errors.error => NotFinite(property(p), exampleValue)
|
|
||||||
let isEmptyError = (propertyName): Errors.error => IsEmpty(property(propertyName))
|
|
||||||
let differentLengthsError = (t): Errors.error => DifferentLengths({
|
|
||||||
fnName: fnName,
|
|
||||||
p1Name: "Xs",
|
p1Name: "Xs",
|
||||||
p2Name: "Ys",
|
p2Name: "Ys",
|
||||||
p1Length: E.A.length(xs(t)),
|
p1Length: E.A.length(xs(t)),
|
||||||
|
@ -92,7 +123,15 @@ module T = {
|
||||||
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]
|
||||||
->E.A.O.concatSomes
|
->E.A.O.concatSomes
|
||||||
->Errors.mapErrorArrayToError
|
->Error.mapErrorArrayToError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let make = (~xs: array<float>, ~ys: array<float>) => {
|
||||||
|
let attempt: t = {xs: xs, ys: ys}
|
||||||
|
switch Validator.validate(attempt) {
|
||||||
|
| Some(error) => Error(error)
|
||||||
|
| None => Ok(attempt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user