Skip to content

Commit

Permalink
feat: mutation functions isCycle param working properly now
Browse files Browse the repository at this point in the history
  • Loading branch information
BelfordZ committed Jun 18, 2021
1 parent 1a5bbee commit 4a6ad09
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
23 changes: 22 additions & 1 deletion src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ describe("traverse", () => {
title: "6",
type: "object",
allOf: [
{ title: "7", type: "object", properties: { baz: { title: "8" } } },
{ title: "7", type: "object", properties: { baz: { title: "5" } } },
],
},
},
Expand Down Expand Up @@ -573,6 +573,27 @@ describe("traverse", () => {
expect(mockMutation).toHaveBeenCalledWith(testSchema, true, "");
expect(mockMutation).not.toHaveBeenCalledWith(testSchema, false, "");
});

it("true when the cycle is inside oneOf", () => {
const testSchema = {
title: "a",
oneOf: [{
title: "b",
type: "object",
properties: {
a: {}
}
}]
};
testSchema.oneOf[0].properties.a = testSchema;

const mockMutation = jest.fn((mockS) => mockS);

traverse(testSchema, mockMutation, { mutable: false });

expect(mockMutation).toHaveBeenCalledWith(testSchema, true, "");
expect(mockMutation).not.toHaveBeenCalledWith(testSchema, false, "");
});
});

describe("bfs", () => {
Expand Down
27 changes: 17 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { JSONSchema, JSONSchemaObject, PatternProperties } from "@json-schema-to
* Signature of the mutation method passed to traverse.
*
* @param schema The schema or subschema node being traversed
* @param isRootOfCycle false if the schema passed is not the root of a detected cycle. Useful for special handling of cycled schemas.
* @param isCycle false if the schema passed is not the root of a detected cycle. Useful for special handling of cycled schemas.
* @param path json path string separated by periods
*/
export type MutationFunction = (schema: JSONSchema, isRootOfCycle: boolean, path: string, ) => JSONSchema;
export type MutationFunction = (schema: JSONSchema, isCycle: boolean, path: string,) => JSONSchema;

/**
* The options you can use when traversing.
Expand Down Expand Up @@ -74,8 +74,8 @@ export default function traverse(
recursiveStack: JSONSchema[] = [],
pathStack: string[] = [],
prePostMap: Array<[JSONSchema, JSONSchema]> = [],
cycleSet: JSONSchema[] = [],
): JSONSchema {
let isRootOfCycle = false;
const opts = { ...defaultOptions, ...traverseOptions }; // would be nice to make an 'entry' func when we get around to optimizations

// booleans are a bit messed. Since all other schemas are objects (non-primitive type
Expand Down Expand Up @@ -112,7 +112,7 @@ export default function traverse(
const rec = (s: JSONSchema, path: string[]): JSONSchema => {
const foundCycle = isCycle(s, recursiveStack);
if (foundCycle) {
if (foundCycle === schema) { isRootOfCycle = true; }
cycleSet.push(foundCycle);

// if the cycle is a ref to the root schema && skipFirstMutation is try we need to call mutate.
// If we don't, it will never happen.
Expand All @@ -124,9 +124,13 @@ export default function traverse(
([orig]) => foundCycle === orig,
) as [JSONSchema, JSONSchema];

// attempt to signal that there is a cycle by putting one into the recursiveStack


return cycledMutableSchema;
}

// else
return traverse(
s,
mutation,
Expand All @@ -135,21 +139,22 @@ export default function traverse(
recursiveStack,
path,
prePostMap,
cycleSet,
);
};

if (schema.anyOf) {
mutableSchema.anyOf = schema.anyOf.map((x,i) => {
mutableSchema.anyOf = schema.anyOf.map((x, i) => {
const result = rec(x, [...pathStack, "anyOf", i.toString()]);
return result;
});
} else if (schema.allOf) {
mutableSchema.allOf = schema.allOf.map((x,i) => {
mutableSchema.allOf = schema.allOf.map((x, i) => {
const result = rec(x, [...pathStack, "allOf", i.toString()]);
return result;
});
} else if (schema.oneOf) {
mutableSchema.oneOf = schema.oneOf.map((x,i) => {
mutableSchema.oneOf = schema.oneOf.map((x, i) => {
const result = rec(x, [...pathStack, "oneOf", i.toString()]);
return result;
});
Expand All @@ -158,14 +163,14 @@ export default function traverse(

if (schema.items) {
if (schema.items instanceof Array) {
mutableSchema.items = schema.items.map((x,i) => {
mutableSchema.items = schema.items.map((x, i) => {
const result = rec(x, [...pathStack, "items", i.toString()]);
return result;
});
} else {
const foundCycle = isCycle(schema.items, recursiveStack);
if (foundCycle) {
if (foundCycle === schema) { isRootOfCycle = true; }
cycleSet.push(foundCycle);

if (opts.skipFirstMutation === true && foundCycle === recursiveStack[0]) {
mutableSchema.items = mutation(schema.items, true, jsonPathStringify(pathStack));
Expand All @@ -186,6 +191,7 @@ export default function traverse(
recursiveStack,
pathStack,
prePostMap,
cycleSet,
);
}
}
Expand Down Expand Up @@ -229,6 +235,7 @@ export default function traverse(
if (opts.bfs === true) {
return mutableSchema;
} else {
return mutation(mutableSchema, isRootOfCycle, jsonPathStringify(pathStack));
const isCycle = cycleSet.indexOf(schema) !== -1
return mutation(mutableSchema, isCycle, jsonPathStringify(pathStack));
}
}

0 comments on commit 4a6ad09

Please sign in to comment.