Skip to content

Commit 82d0d1e

Browse files
committed
Don't modify schema in testers
1 parent 735ce93 commit 82d0d1e

File tree

4 files changed

+21
-28
lines changed

4 files changed

+21
-28
lines changed

packages/core/src/testers/testers.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import { deriveTypes, hasType, resolveSchema } from '../util';
4747
export const NOT_APPLICABLE = -1;
4848
/**
4949
* A tester is a function that receives an UI schema and a JSON schema and returns a boolean.
50-
* Optionally, a root JSON schema can be provided, which can be used for resolving refs in the schema.
50+
* The rootSchema is handed over as context. Can be used to resolve references.
5151
*/
5252
export type Tester = (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => boolean;
5353

@@ -403,22 +403,31 @@ export const isObjectArrayControl = and(uiTypeIs('Control'), isObjectArray);
403403

404404
const traverse = (
405405
any: JsonSchema | JsonSchema[],
406-
pred: (obj: JsonSchema) => boolean
406+
pred: (obj: JsonSchema) => boolean,
407+
rootSchema: JsonSchema
407408
): boolean => {
408409
if (isArray(any)) {
409-
return reduce(any, (acc, el) => acc || traverse(el, pred), false);
410+
return reduce(any, (acc, el) => acc || traverse(el, pred, rootSchema), false);
410411
}
411412

412413
if (pred(any)) {
413414
return true;
414415
}
416+
417+
if (any.$ref) {
418+
const toTraverse = resolveSchema(rootSchema, any.$ref, rootSchema);
419+
if (toTraverse && !toTraverse.$ref) {
420+
return traverse(toTraverse, pred, rootSchema);
421+
}
422+
}
423+
415424
if (any.items) {
416-
return traverse(any.items, pred);
425+
return traverse(any.items, pred, rootSchema);
417426
}
418427
if (any.properties) {
419428
return reduce(
420429
toPairs(any.properties),
421-
(acc, [_key, val]) => acc || traverse(val, pred),
430+
(acc, [_key, val]) => acc || traverse(val, pred, rootSchema),
422431
false
423432
);
424433
}
@@ -436,9 +445,6 @@ export const isObjectArrayWithNesting = (
436445
}
437446
const schemaPath = (uischema as ControlElement).scope;
438447
const resolvedSchema = resolveSchema(schema, schemaPath, rootSchema ?? schema);
439-
if (resolvedSchema?.items && (resolvedSchema.items as any).$ref){
440-
resolvedSchema.items = resolveSchema(resolvedSchema, 'items', rootSchema ?? schema);
441-
}
442448
const wantedNestingByType: { [key: string]: number } = {
443449
object: 2,
444450
array: 1
@@ -463,7 +469,7 @@ export const isObjectArrayWithNesting = (
463469
}
464470
wantedNestingByType[val.type] = typeCount - 1;
465471
return wantedNestingByType[val.type] === 0;
466-
})
472+
}, rootSchema)
467473
) {
468474
return true;
469475
}

packages/core/test/testers.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ test('tester isObjectArrayWithNesting', t => {
801801
t.true(isObjectArrayWithNesting(uischema, nestedSchema, undefined));
802802
t.true(isObjectArrayWithNesting(uischema, nestedSchema2, undefined));
803803
t.true(isObjectArrayWithNesting(uischema, nestedSchema3, undefined));
804-
t.true(isObjectArrayWithNesting(uischema, nestedSchemaWithRef, undefined));
804+
t.true(isObjectArrayWithNesting(uischema, nestedSchemaWithRef, nestedSchemaWithRef));
805805

806806
t.false(isObjectArrayWithNesting(uischemaOptions.default, schema, undefined));
807807
t.true(isObjectArrayWithNesting(uischemaOptions.generate, schema, undefined));

packages/core/test/util/path.test.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ test('resolve $ref', t => {
142142
const result = Resolve.schema(schema, '#/properties/foos/items', schema);
143143
t.deepEqual(result, { type: 'string' });
144144
});
145-
test.failing('resolve $ref simple', t => {
145+
test('resolve $ref simple', t => {
146146
const schema: JsonSchema = {
147147
definitions: {
148148
foo: {
@@ -174,14 +174,14 @@ test.failing('resolve $ref simple', t => {
174174
bar: {
175175
type: 'array',
176176
items: {
177-
$ref: '#'
177+
$ref: '#/definitions/foo'
178178
}
179179
}
180180
}
181181
});
182182
t.not((schema.definitions.foo.properties.bar.items as JsonSchema).$ref, '#');
183183
});
184-
test.failing('resolve $ref complicated', t => {
184+
test('resolve $ref complicated', t => {
185185
const schema: JsonSchema = {
186186
definitions: {
187187
foo: {
@@ -219,19 +219,6 @@ test.failing('resolve $ref complicated', t => {
219219
};
220220
const result = Resolve.schema(schema, '#/properties/foos/items', schema);
221221
t.deepEqual(result, {
222-
definitions: {
223-
foo2: {
224-
type: 'object',
225-
properties: {
226-
bar: {
227-
type: 'array',
228-
items: {
229-
$ref: '#'
230-
}
231-
}
232-
}
233-
}
234-
},
235222
type: 'object',
236223
properties: {
237224
bar: {

packages/material/test/renderers/MaterialArrayLayout.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ describe('Material array layout tester', () => {
181181
expect(materialArrayLayoutTester(uischema, schema, undefined)).toBe(-1);
182182
expect(materialArrayLayoutTester(uischema, nestedSchema, undefined)).toBe(4);
183183
expect(materialArrayLayoutTester(uischema, nestedSchema2, undefined)).toBe(4);
184-
expect(materialArrayLayoutTester(uischema, nestedSchemaWithRef, undefined)).toBe(4);
185184
expect(materialArrayLayoutTester(uischema, nestedSchemaWithRef, nestedSchemaWithRef)).toBe(4);
186-
expect(materialArrayLayoutTester(uischema, nestedSchema2WithRef, undefined)).toBe(4);
185+
expect(materialArrayLayoutTester(uischema, nestedSchemaWithRef, nestedSchemaWithRef)).toBe(4);
186+
expect(materialArrayLayoutTester(uischema, nestedSchema2WithRef, nestedSchema2WithRef)).toBe(4);
187187

188188
expect(materialArrayLayoutTester(uischemaOptions.default, schema, undefined)).toBe(-1);
189189
expect(materialArrayLayoutTester(uischemaOptions.generate, schema, undefined)).toBe(4);

0 commit comments

Comments
 (0)