Skip to content

Commit

Permalink
introduce: __oneOfIndex
Browse files Browse the repository at this point in the history
  • Loading branch information
sagold committed Dec 1, 2024
1 parent 363c43a commit 70e27d3
Show file tree
Hide file tree
Showing 9 changed files with 714 additions and 573 deletions.
14 changes: 12 additions & 2 deletions lib/features/oneOf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import settings from "../config/settings";
import { errorOrPromise } from "../utils/filter";
import { JsonSchema, JsonError, isJsonError } from "../types";
import { isObject } from "../utils/isObject";
import { JsonValidator } from "../validation/type"
import { JsonValidator } from "../validation/type";
import { SchemaNode } from "../schemaNode";

const { DECLARATOR_ONEOF } = settings;
Expand Down Expand Up @@ -57,6 +57,8 @@ export function resolveOneOf(node: SchemaNode, data: any): SchemaNode | JsonErro
if (result.length > 0) {
errors.push(...result);
} else {
// @evaluation-info
oneNode.schema.__oneOfIndex = i;
return resultNode.next(oneNode.schema);
}
}
Expand Down Expand Up @@ -85,6 +87,8 @@ export function resolveOneOf(node: SchemaNode, data: any): SchemaNode | JsonErro
}

if (matches.length === 1) {
// @evaluation-info
matches[0].schema.__oneOfIndex = matches[0].index;
return node.next(matches[0].schema);
}
if (matches.length > 1) {
Expand Down Expand Up @@ -146,7 +150,7 @@ function fuzzyObjectValue(node: SchemaNode, data: Record<string, unknown>) {
export function resolveOneOfFuzzy(node: SchemaNode, data: any): SchemaNode | JsonError {
const { schema, pointer, draft } = node;
if (!Array.isArray(schema.oneOf)) {
throw new Error("not a oneof schema")
throw new Error("not a oneof schema");
return node;
}
// !keyword: oneOfProperty
Expand Down Expand Up @@ -182,6 +186,8 @@ export function resolveOneOfFuzzy(node: SchemaNode, data: any): SchemaNode | Jso
if (result.length > 0) {
errors.push(...result);
} else {
// @evaluation-info
oneNode.schema.__oneOfIndex = i;
return resultNode.next(oneNode.schema);
}
}
Expand All @@ -206,6 +212,8 @@ export function resolveOneOfFuzzy(node: SchemaNode, data: any): SchemaNode | Jso
}

if (matches.length === 1) {
// @evaluation-info
matches[0].schema.__oneOfIndex = matches[0].index;
return node.next(matches[0].schema);
}

Expand Down Expand Up @@ -235,6 +243,8 @@ export function resolveOneOfFuzzy(node: SchemaNode, data: any): SchemaNode | Jso
});
}

// @evaluation-info
schemaOfItem.__oneOfIndex = schemaOfIndex;
return node.next(schemaOfItem);
}

Expand Down
1 change: 1 addition & 0 deletions lib/resolveDynamicSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function isDynamicSchema(schema: JsonData): boolean {
/**
* @note this utility does not reference draft methods for resolution
* @todo consider using draft methods
* @todo consider exposing separate info-object (oneOf-Index)
*
* Resolves all dynamic schema definitions for the given input data and returns
* the resulting json-schema without any dynamic schema definitions. The result
Expand Down
1 change: 1 addition & 0 deletions test/unit/docs/docs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ describe("docs", () => {
expect(schemaOfItem).to.deep.equal({
type: "object",
required: ["name"],
__oneOfIndex: 0,
properties: {
name: {
type: "string",
Expand Down
2 changes: 2 additions & 0 deletions test/unit/resolveDynamicSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ describe("resolveDynamicSchema", () => {
"#"
);
expect(schema).to.deep.equal({
__oneOfIndex: 1,
properties: {
two: {
type: "string"
Expand Down Expand Up @@ -389,6 +390,7 @@ describe("resolveDynamicSchema", () => {
);

expect(schema).to.deep.equal({
__oneOfIndex: 1,
properties: {
id: { const: "second" },
one: { type: "number" }
Expand Down
32 changes: 24 additions & 8 deletions test/unit/resolveOneOf.fuzzy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ import { resolveOneOfFuzzy as _resolveOneOf } from "../../lib/features/oneOf";

const { DECLARATOR_ONEOF } = settings;


function resolveOneOf(draft: Draft, data: any, schema: JsonSchema = draft.rootSchema, pointer = "#"): JsonSchema | JsonError {
function resolveOneOf(
draft: Draft,
data: any,
schema: JsonSchema = draft.rootSchema,
pointer = "#"
): JsonSchema | JsonError {
const node = createNode(draft, schema, pointer);
const result = _resolveOneOf(node, data);
if (result && !isJsonError(result)) {
Expand All @@ -19,7 +23,6 @@ function resolveOneOf(draft: Draft, data: any, schema: JsonSchema = draft.rootSc
return result;
}


describe("resolveOneOf (fuzzy)", () => {
let draft: Core;
beforeEach(() => (draft = new Core()));
Expand All @@ -29,7 +32,7 @@ describe("resolveOneOf (fuzzy)", () => {
oneOf: [{ type: "string" }, { type: "number" }, { type: "object" }]
});

expect(res).to.deep.eq({ type: "number" });
expect(res).to.deep.eq({ __oneOfIndex: 1, type: "number" });
});

it("should return schema with matching pattern", () => {
Expand All @@ -40,7 +43,7 @@ describe("resolveOneOf (fuzzy)", () => {
]
});

expect(res).to.deep.eq({ type: "string", pattern: "asterix" });
expect(res).to.deep.eq({ __oneOfIndex: 1, type: "string", pattern: "asterix" });
});

it("should resolve $ref before schema", () => {
Expand All @@ -53,7 +56,7 @@ describe("resolveOneOf (fuzzy)", () => {
});
const res = resolveOneOf(draft, "anasterixcame");

expect(res).to.deep.eq({ type: "string", pattern: "asterix" });
expect(res).to.deep.eq({ __oneOfIndex: 1, type: "string", pattern: "asterix" });
});

describe("object", () => {
Expand All @@ -72,6 +75,7 @@ describe("resolveOneOf (fuzzy)", () => {

expect(res).to.deep.eq({
type: "object",
__oneOfIndex: 1,
properties: { description: { type: "string" } }
});
});
Expand All @@ -88,7 +92,11 @@ describe("resolveOneOf (fuzzy)", () => {
}
);

expect(res).to.deep.eq({ type: "object", properties: { title: { type: "string" } } });
expect(res).to.deep.eq({
__oneOfIndex: 1,
type: "object",
properties: { title: { type: "string" } }
});
});

describe("oneOfProperty", () => {
Expand Down Expand Up @@ -126,6 +134,7 @@ describe("resolveOneOf (fuzzy)", () => {

expect(res).to.deep.eq({
type: "object",
__oneOfIndex: 1,
properties: {
name: { type: "string", pattern: "^2$" },
title: { type: "number" }
Expand Down Expand Up @@ -167,6 +176,7 @@ describe("resolveOneOf (fuzzy)", () => {

expect(res).to.deep.eq({
type: "object",
__oneOfIndex: 1,
properties: {
name: { type: "string", pattern: "^2$" },
title: { type: "number" }
Expand Down Expand Up @@ -255,7 +265,11 @@ describe("resolveOneOf (fuzzy)", () => {
}
);

expect(res).to.deep.eq({ type: "object", properties: { a: t, b: t, c: t } });
expect(res).to.deep.eq({
__oneOfIndex: 1,
type: "object",
properties: { a: t, b: t, c: t }
});
});

it("should only count properties that match the schema", () => {
Expand All @@ -274,6 +288,7 @@ describe("resolveOneOf (fuzzy)", () => {

expect(res).to.deep.eq({
type: "object",
__oneOfIndex: 1,
properties: { a: { type: "boolean" }, b: t, d: t }
});
});
Expand Down Expand Up @@ -329,6 +344,7 @@ describe("resolveOneOf (fuzzy)", () => {

expect(res).to.deep.eq({
type: "object",
__oneOfIndex: 1,
properties: {
redirectUrl: {
format: "url",
Expand Down
11 changes: 9 additions & 2 deletions test/unit/resolveOneOf.oneOfProperty.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import { resolveOneOf as _resolveOneOf } from "../../lib/features/oneOf";

const { DECLARATOR_ONEOF } = settings;

function resolveOneOf(draft: Draft, data: any, schema: JsonSchema = draft.rootSchema, pointer = "#"): JsonSchema | JsonError {
function resolveOneOf(
draft: Draft,
data: any,
schema: JsonSchema = draft.rootSchema,
pointer = "#"
): JsonSchema | JsonError {
const node = createNode(draft, schema, pointer);
const result = _resolveOneOf(node, data);
if (result && !isJsonError(result)) {
Expand All @@ -18,7 +23,7 @@ function resolveOneOf(draft: Draft, data: any, schema: JsonSchema = draft.rootSc
return result;
}

describe("oneOfProperty", () => {
describe("resolveOneOf.oneOfProperty", () => {
let draft: Draft07;
beforeEach(() => (draft = new Draft07()));

Expand Down Expand Up @@ -56,6 +61,7 @@ describe("oneOfProperty", () => {

expect(res).to.deep.eq({
type: "object",
__oneOfIndex: 1,
properties: {
name: { type: "string", pattern: "^2$" },
title: { type: "number" }
Expand Down Expand Up @@ -97,6 +103,7 @@ describe("oneOfProperty", () => {

expect(res).to.deep.eq({
type: "object",
__oneOfIndex: 1,
properties: {
name: { type: "string", pattern: "^2$" },
title: { type: "number" }
Expand Down
11 changes: 8 additions & 3 deletions test/unit/step/step.oneOf.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@

import { expect } from "chai";
import _step from "../../../lib/step";
import { Draft04 } from "../../../lib/draft04";
import { Draft } from "../../../lib/draft";
import { JsonSchema } from "../../../lib/types";
import { createNode, isSchemaNode } from "../../../lib/schemaNode";

function step(draft: Draft, key: string | number, schema: JsonSchema, data?: unknown, pointer = '#') {
function step(
draft: Draft,
key: string | number,
schema: JsonSchema,
data?: unknown,
pointer = "#"
) {
const res = _step(createNode(draft, schema, pointer), key, data);
return isSchemaNode(res) ? res.schema : res;
}
Expand Down Expand Up @@ -38,7 +43,7 @@ describe("step.oneof", () => {
delete res.oneOfSchema;
delete res.variableSchema;
delete res.oneOfIndex;
expect(res).to.deep.eq({ type: "number", title: "Zahl" });
expect(res).to.deep.eq({ __oneOfIndex: 1, type: "number", title: "Zahl" });
});

// PR #35 https://github.com/sagold/json-schema-library/pull/35/commits/8b6477113bdfce522081473bb0dd8fd6fe680391
Expand Down
9 changes: 8 additions & 1 deletion test/unit/step/step.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import { Draft04 as Core } from "../../../lib/draft04";
import { expect } from "chai";
import { JsonSchema } from "../../../lib/types";

function step(draft: Draft, key: string | number, schema: JsonSchema, data?: unknown, pointer = '#') {
function step(
draft: Draft,
key: string | number,
schema: JsonSchema,
data?: unknown,
pointer = "#"
) {
const res = _step(createNode(draft, schema, pointer), key, data);
return isSchemaNode(res) ? res.schema : res;
}
Expand Down Expand Up @@ -341,6 +347,7 @@ describe("step", () => {
);

expect(res).to.deep.eq({
__oneOfIndex: 1,
type: "object",
properties: { title: { type: "number" } }
});
Expand Down
Loading

0 comments on commit 70e27d3

Please sign in to comment.