Skip to content

Commit

Permalink
fix: add float support
Browse files Browse the repository at this point in the history
fixes #5
  • Loading branch information
mattbford committed Aug 12, 2020
1 parent c2b0628 commit 4a7c1c4
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 99 deletions.
49 changes: 3 additions & 46 deletions src/base-validators/integer.test.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,10 @@
import validator, { IntegerValidationError } from "./integer";
import { NumberValidationError } from "./number";

describe("validator", () => {
it("can validate and invalidate a integer", () => {
expect(validator({ type: "integer" }, "im a integer")).toBeInstanceOf(IntegerValidationError);
expect(validator({ type: "integer" }, 123)).toBe(true);
expect(validator({ type: "integer" }, {})).toBeInstanceOf(IntegerValidationError);
expect(validator({ type: "integer" }, true)).toBeInstanceOf(IntegerValidationError);
expect(validator({ type: "integer" }, false)).toBeInstanceOf(IntegerValidationError);
expect(validator({ type: "integer" }, null)).toBeInstanceOf(IntegerValidationError);
expect(validator({ type: "integer" }, 123.123)).toBeInstanceOf(IntegerValidationError);
});

it("multipleOf", () => {
expect(validator({ type: "integer", multipleOf: 10 }, 100)).toBe(true);
expect(validator({ type: "integer", multipleOf: 100 }, 10)).toBeInstanceOf(IntegerValidationError);
});

it("maximum", () => {
expect(validator({ type: "integer", maximum: 10 }, 10)).toBe(true);
expect(validator({ type: "integer", maximum: 10 }, 11)).toBeInstanceOf(IntegerValidationError);
});

it("exclusiveMaximum", () => {
expect(validator({ type: "integer", exclusiveMaximum: 10 }, 9)).toBe(true);
expect(validator({ type: "integer", exclusiveMaximum: 10 }, 10)).toBeInstanceOf(IntegerValidationError);
});

it("minimum", () => {
expect(validator({ type: "integer", minimum: 10 }, 10)).toBe(true);
expect(validator({ type: "integer", minimum: 10 }, 9)).toBeInstanceOf(IntegerValidationError);
});

it("exclusiveMinimum", () => {
expect(validator({ type: "integer", exclusiveMinimum: 10 }, 11)).toBe(true);
expect(validator({ type: "integer", exclusiveMinimum: 10 }, 10)).toBeInstanceOf(IntegerValidationError);
});

it("const", () => {
expect(validator({ type: "integer", const: 123 }, 123)).toBe(true);
expect(validator({ type: "integer", const: 456 }, 123)).toBeInstanceOf(IntegerValidationError);
});

it("enum", () => {
expect(validator({ type: "integer", enum: [123] }, 123)).toBe(true);
expect(validator({ type: "integer", enum: [123] }, 456)).toBeInstanceOf(IntegerValidationError);

expect(validator({ type: "integer", enum: [123, 456] }, 123)).toBe(true);
expect(validator({ type: "integer", enum: [123, 456] }, 1)).toBeInstanceOf(IntegerValidationError);

expect(validator({ type: "integer", enum: ["foo", "123", "bar"] }, 123)).toBeInstanceOf(IntegerValidationError);
expect(validator({ type: "integer" }, "this is an integer")).toBeInstanceOf(NumberValidationError);
expect(validator({ type: "integer" }, 123.10)).toBeInstanceOf(IntegerValidationError);
});
});
57 changes: 5 additions & 52 deletions src/base-validators/integer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ValidationError from "../validation-error";
import { JSONSchemaObject } from "@json-schema-tools/meta-schema";
import NumberValidator, { NumberValidationError } from "./number";

export class IntegerValidationError implements Error {
public name = "IntegerValidationError";
Expand All @@ -21,63 +22,15 @@ const isInt = (num: number) => {
}

export default (schema: JSONSchemaObject, d: any): true | ValidationError => {
if (typeof d !== "number") {
return new IntegerValidationError(schema, d, "Not a number type");

const validNumber = NumberValidator(schema, d);
if (validNumber !== true) {
return validNumber;
}

if (!isInt(d)) {
return new IntegerValidationError(schema, d, "provided number is a float, not an integer");
}

if (schema.multipleOf) {
if (!isInt(d / schema.multipleOf)) {
return new IntegerValidationError(schema, d, `number is not a multiple of ${schema.multipleOf}`);
}
}

if (schema.maximum) {
if (d > schema.maximum) {
return new IntegerValidationError(schema, d, `number exceeds maximum of ${schema.maximum}`);
}
}

if (schema.exclusiveMaximum) {
if (d >= schema.exclusiveMaximum) {
return new IntegerValidationError(
schema,
d,
`number is greater than or equal to exclusive maximum of ${schema.exclusiveMaximum}`
);
}
}

if (schema.minimum) {
if (d < schema.minimum) {
return new IntegerValidationError(schema, d, `number is less than minimum of ${schema.minimum}`);
}
}

if (schema.exclusiveMinimum) {
if (d <= schema.exclusiveMinimum) {
return new IntegerValidationError(
schema,
d,
`number is less than or equal to exclusive minimum of ${schema.exclusiveMinimum}`
);
}
}

if (schema.const) {
if (d !== schema.const) {
return new IntegerValidationError(schema, d, `must be: ${schema.const}`);
}
}

if (schema.enum) {
if (schema.enum.indexOf(d) === -1) {
return new IntegerValidationError(schema, d, `must be one of: ${schema.enum}`);
}
}

return true;
}
53 changes: 53 additions & 0 deletions src/base-validators/number.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import validator, { NumberValidationError } from "./number";

describe("validator", () => {
it("can validate and invalidate a number", () => {
expect(validator({ type: "number" }, "im a number")).toBeInstanceOf(NumberValidationError);
expect(validator({ type: "number" }, 123)).toBe(true);
expect(validator({ type: "number" }, {})).toBeInstanceOf(NumberValidationError);
expect(validator({ type: "number" }, true)).toBeInstanceOf(NumberValidationError);
expect(validator({ type: "number" }, false)).toBeInstanceOf(NumberValidationError);
expect(validator({ type: "number" }, null)).toBeInstanceOf(NumberValidationError);
expect(validator({ type: "number" }, 123.123)).toBe(true);
});

it("multipleOf", () => {
expect(validator({ type: "number", multipleOf: 10 }, 100)).toBe(true);
expect(validator({ type: "number", multipleOf: 100 }, 10)).toBeInstanceOf(NumberValidationError);
});

it("maximum", () => {
expect(validator({ type: "number", maximum: 10 }, 10)).toBe(true);
expect(validator({ type: "number", maximum: 10 }, 11)).toBeInstanceOf(NumberValidationError);
});

it("exclusiveMaximum", () => {
expect(validator({ type: "number", exclusiveMaximum: 10 }, 9)).toBe(true);
expect(validator({ type: "number", exclusiveMaximum: 10 }, 10)).toBeInstanceOf(NumberValidationError);
});

it("minimum", () => {
expect(validator({ type: "number", minimum: 10 }, 10)).toBe(true);
expect(validator({ type: "number", minimum: 10 }, 9)).toBeInstanceOf(NumberValidationError);
});

it("exclusiveMinimum", () => {
expect(validator({ type: "number", exclusiveMinimum: 10 }, 11)).toBe(true);
expect(validator({ type: "number", exclusiveMinimum: 10 }, 10)).toBeInstanceOf(NumberValidationError);
});

it("const", () => {
expect(validator({ type: "number", const: 123 }, 123)).toBe(true);
expect(validator({ type: "number", const: 456 }, 123)).toBeInstanceOf(NumberValidationError);
});

it("enum", () => {
expect(validator({ type: "number", enum: [123] }, 123)).toBe(true);
expect(validator({ type: "number", enum: [123] }, 456)).toBeInstanceOf(NumberValidationError);

expect(validator({ type: "number", enum: [123, 456] }, 123)).toBe(true);
expect(validator({ type: "number", enum: [123, 456] }, 1)).toBeInstanceOf(NumberValidationError);

expect(validator({ type: "number", enum: ["foo", "123", "bar"] }, 123)).toBeInstanceOf(NumberValidationError);
});
});
71 changes: 71 additions & 0 deletions src/base-validators/number.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import ValidationError from "../validation-error";
import { JSONSchemaObject } from "@json-schema-tools/meta-schema";

export class NumberValidationError implements Error {
public name = "NumberValidationError";
public message: string;

constructor(schema: JSONSchemaObject, data: any, reason: string) {
this.message = [
"invalid data provided is not a valid integer",
`reason: ${reason}`,
].join("\n");
}
}
export default (schema: JSONSchemaObject, d: any): true | ValidationError => {
if (typeof d !== "number") {
return new NumberValidationError(schema, d, "Not a number type");
}

if (schema.multipleOf) {
if (d % schema.multipleOf !== 0) {
return new NumberValidationError(schema, d, `number is not a multiple of ${schema.multipleOf}`);
}
}

if (schema.maximum) {
if (d > schema.maximum) {
return new NumberValidationError(schema, d, `number exceeds maximum of ${schema.maximum}`);
}
}

if (schema.exclusiveMaximum) {
if (d >= schema.exclusiveMaximum) {
return new NumberValidationError(
schema,
d,
`number is greater than or equal to exclusive maximum of ${schema.exclusiveMaximum}`
);
}
}

if (schema.minimum) {
if (d < schema.minimum) {
return new NumberValidationError(schema, d, `number is less than minimum of ${schema.minimum}`);
}
}

if (schema.exclusiveMinimum) {
if (d <= schema.exclusiveMinimum) {
return new NumberValidationError(
schema,
d,
`number is less than or equal to exclusive minimum of ${schema.exclusiveMinimum}`
);
}
}

if (schema.const) {
if (d !== schema.const) {
return new NumberValidationError(schema, d, `must be: ${schema.const}`);
}
}

if (schema.enum) {
if (schema.enum.indexOf(d) === -1) {
return new NumberValidationError(schema, d, `must be one of: ${schema.enum}`);
}
}

return true;
}
12 changes: 11 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ import { JSONSchema, JSONSchemaObject } from "@json-schema-tools/meta-schema";
import traverse from "@json-schema-tools/traverse";
import StringValidator, { StringValidationError } from "./base-validators/string";
import BooleanValidator, { BooleanValidationError } from "./base-validators/boolean";
import NumberValidator, { NumberValidationError } from "./base-validators/number";
import IntegerValidator, { IntegerValidationError } from "./base-validators/integer";

// import all the different validation errors
type ValidationError = StringValidationError | BooleanValidationError | IntegerValidationError;
type ValidationError =
StringValidationError |
BooleanValidationError |
IntegerValidationError |
NumberValidationError;

export class ValidationErrors implements Error {
public name = "ValidationErrors";
Expand Down Expand Up @@ -43,6 +48,11 @@ const validator = (schema: JSONSchema, data: any): true | ValidationErrors => {
if (valid !== true) {
errors.push(valid);
}
} else if (schema.type === "number") {
const valid = NumberValidator(schema, data);
if (valid !== true) {
errors.push(valid);
}
}

if (errors.length === 0) {
Expand Down

0 comments on commit 4a7c1c4

Please sign in to comment.