Skip to content

Commit d030b64

Browse files
committed
move type checks to internal helpers to be reused
1 parent bf3501c commit d030b64

File tree

5 files changed

+61
-62
lines changed

5 files changed

+61
-62
lines changed

internal/check.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {timingFunctions} from "./animate/timing";
2+
3+
const typeCheck = (name: string, val: any, expected: string[]) => {
4+
let actual: string = typeof val;
5+
if (actual === "number" && isNaN(val)) actual = "NaN";
6+
if (actual === "object" && val === null) actual = "null";
7+
if (!expected.includes(actual)) {
8+
throw `"${name}" should have type "${expected.join("|")}" but was "${actual}".`;
9+
}
10+
};
11+
12+
export const checkKeyframeOptions = (keyframe: any) => {
13+
typeCheck(`keyframe`, keyframe, ["object"]);
14+
const {delay, duration, timingFunction, callback} = keyframe;
15+
typeCheck(`delay`, delay, ["number", "undefined"]);
16+
if (delay && delay < 0) throw `delay is invalid "${delay}".`;
17+
typeCheck(`duration`, duration, ["number"]);
18+
if (duration && duration < 0) throw `duration is invalid "${duration}".`;
19+
typeCheck(`timingFunction`, timingFunction, ["string", "undefined"]);
20+
if (timingFunction && !(timingFunctions as any)[timingFunction])
21+
throw `".timingFunction" is not recognized "${timingFunction}".`;
22+
typeCheck(`callback`, callback, ["function", "undefined"]);
23+
};
24+
25+
export const checkBlobOptions = (blobOptions: any) => {
26+
typeCheck(`blobOptions`, blobOptions, ["object"]);
27+
const {seed, extraPoints, randomness, size} = blobOptions;
28+
typeCheck(`blobOptions.seed`, seed, ["string", "number"]);
29+
typeCheck(`blobOptions.extraPoints`, extraPoints, ["number"]);
30+
if (extraPoints < 0) throw `blobOptions.extraPoints is invalid "${extraPoints}".`;
31+
typeCheck(`blobOptions.randomness`, randomness, ["number"]);
32+
if (randomness < 0) throw `blobOptions.randomness is invalid "${randomness}".`;
33+
typeCheck(`blobOptions.size`, size, ["number"]);
34+
if (size < 0) throw `blobOptions.size is invalid "${size}".`;
35+
};
36+
37+
export const checkCanvasOptions = (canvasOptions: any) => {
38+
typeCheck(`canvasOptions`, canvasOptions, ["object", "undefined"]);
39+
if (canvasOptions) {
40+
const {offsetX, offsetY} = canvasOptions;
41+
typeCheck(`canvasOptions.offsetX`, offsetX, ["number", "undefined"]);
42+
typeCheck(`canvasOptions.offsetY`, offsetY, ["number", "undefined"]);
43+
}
44+
};

internal/errors.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

public/animate.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe("animate", () => {
2121
describe("canvasPath", () => {
2222
describe("transition", () => {
2323
describe("keyframe", () => {
24-
it("should accept minimal generated keyframe", () => {
24+
it("should accept generated keyframe", () => {
2525
const animation = canvasPath();
2626
const keyframe = genKeyframe();
2727

@@ -32,7 +32,7 @@ describe("animate", () => {
3232
const animation = canvasPath();
3333
const keyframes = [genKeyframe(), null as any, genKeyframe()];
3434

35-
expect(() => animation.transition(...keyframes)).toThrow(/keyframes.*1/g);
35+
expect(() => animation.transition(...keyframes)).toThrow(/keyframe.*1/g);
3636
});
3737

3838
interface TestCase {

public/animate.ts

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import {renderPath2D} from "../internal/render/canvas";
33
import {genFromOptions} from "../internal/gen";
44
import {mapPoints} from "../internal/util";
55
import {statefulAnimationGenerator} from "../internal/animate/state";
6-
import {typeCheck, err} from "../internal/errors";
7-
import {timingFunctions} from "../internal/animate/timing";
6+
import {checkBlobOptions, checkCanvasOptions, checkKeyframeOptions} from "../internal/check";
87

98
export interface CanvasKeyframe {
109
delay?: number;
@@ -39,39 +38,13 @@ const canvasBlobGenerator = (keyframe: CanvasKeyframe): Point[] => {
3938
});
4039
};
4140

42-
// TODO make reusable.
4341
const canvasKeyframeChecker = (keyframe: CanvasKeyframe, index: number) => {
44-
// keyframe options
45-
typeCheck(`keyframes[${index}]`, keyframe, ["object"]);
46-
const {delay, duration, timingFunction, callback} = keyframe;
47-
typeCheck(`keyframes[${index}].delay`, delay, ["number", "undefined"]);
48-
if (delay && delay < 0) err(`keyframes[${index}].delay is invalid "${delay}".`);
49-
typeCheck(`keyframes[${index}].duration`, duration, ["number"]);
50-
if (duration && duration < 0) err(`keyframes[${index}].duration is invalid "${duration}".`);
51-
typeCheck(`keyframes[${index}].timingFunction`, timingFunction, ["string", "undefined"]);
52-
if (timingFunction && !timingFunctions[timingFunction])
53-
err(`"keyframes[${index}].timingFunction" is not recognized "${timingFunction}".`);
54-
typeCheck(`keyframes[${index}].callback`, callback, ["function", "undefined"]);
55-
56-
// blobOptions
57-
typeCheck(`keyframes[${index}].blobOptions`, keyframe.blobOptions, ["object"]);
58-
const {seed, extraPoints, randomness, size} = keyframe.blobOptions;
59-
typeCheck(`keyframes[${index}].blobOptions.seed`, seed, ["string", "number"]);
60-
typeCheck(`keyframes[${index}].blobOptions.extraPoints`, extraPoints, ["number"]);
61-
if (extraPoints < 0)
62-
err(`keyframes[${index}].blobOptions.extraPoints is invalid "${extraPoints}".`);
63-
typeCheck(`keyframes[${index}].blobOptions.randomness`, randomness, ["number"]);
64-
if (randomness < 0)
65-
err(`keyframes[${index}].blobOptions.randomness is invalid "${randomness}".`);
66-
typeCheck(`keyframes[${index}].blobOptions.size`, size, ["number"]);
67-
if (size < 0) err(`keyframes[${index}].blobOptions.size is invalid "${size}".`);
68-
69-
// canvasOptions
70-
typeCheck(`keyframes[${index}].canvasOptions`, keyframe.canvasOptions, ["object", "undefined"]);
71-
if (keyframe.canvasOptions) {
72-
const {offsetX, offsetY} = keyframe.canvasOptions;
73-
typeCheck(`keyframes[${index}].canvasOptions.offsetX`, offsetX, ["number", "undefined"]);
74-
typeCheck(`keyframes[${index}].canvasOptions.offsetY`, offsetY, ["number", "undefined"]);
42+
try {
43+
checkBlobOptions(keyframe.blobOptions);
44+
checkCanvasOptions(keyframe.canvasOptions);
45+
checkKeyframeOptions(keyframe);
46+
} catch (e) {
47+
throw `(blobs2): keyframe ${index}: ${e}`;
7548
}
7649
};
7750

public/blobs.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {genFromOptions} from "../internal/gen";
22
import {renderPath} from "../internal/render/svg";
33
import {renderPath2D} from "../internal/render/canvas";
44
import {mapPoints} from "../internal/util";
5-
import {typeCheck} from "../internal/errors";
5+
import {checkBlobOptions} from "../internal/check";
66

77
export interface BlobOptions {
88
seed: string | number;
@@ -23,12 +23,7 @@ export interface SvgOptions {
2323
}
2424

2525
export const canvasPath = (blobOptions: BlobOptions, canvasOptions: CanvasOptions = {}): Path2D => {
26-
typeCheck("canvasOptions", canvasOptions, ["object", "undefined"]);
27-
if (canvasOptions) {
28-
typeCheck("canvasOptions.offsetX", canvasOptions.offsetX, ["number", "undefined"]);
29-
typeCheck("canvasOptions.offsetY", canvasOptions.offsetY, ["number", "undefined"]);
30-
}
31-
26+
// TODO check options
3227
return renderPath2D(
3328
mapPoints(genFromOptions(blobOptions), ({curr}) => {
3429
curr.x += canvasOptions.offsetX || 0;
@@ -39,13 +34,7 @@ export const canvasPath = (blobOptions: BlobOptions, canvasOptions: CanvasOption
3934
};
4035

4136
export const svg = (blobOptions: BlobOptions, svgOptions: SvgOptions = {}): string => {
42-
typeCheck("svgOptions", svgOptions, ["object", "undefined"]);
43-
if (svgOptions) {
44-
typeCheck("svgOptions.fill", svgOptions.fill, ["string", "undefined"]);
45-
typeCheck("svgOptions.stroke", svgOptions.stroke, ["number", "undefined"]);
46-
typeCheck("svgOptions.strokeWidth", svgOptions.strokeWidth, ["number", "undefined"]);
47-
}
48-
37+
// TODO check options
4938
const path = svgPath(blobOptions);
5039
const size = Math.floor(blobOptions.size);
5140
const fill = svgOptions.fill === undefined ? "#ec576b" : svgOptions.fill;
@@ -58,5 +47,10 @@ export const svg = (blobOptions: BlobOptions, svgOptions: SvgOptions = {}): stri
5847
};
5948

6049
export const svgPath = (blobOptions: BlobOptions): string => {
50+
try {
51+
checkBlobOptions(blobOptions);
52+
} catch (e) {
53+
throw `(blobs2): ${e}`;
54+
}
6155
return renderPath(genFromOptions(blobOptions));
6256
};

0 commit comments

Comments
 (0)