Skip to content

Commit d8e39d7

Browse files
authored
Merge pull request #535 from fractal-analytics-platform/jsonschema-2020-12
Supported prefixItems (JSON Schema Draft 2020-12 - pydantic_v2)
2 parents dfe00ed + fa0da6f commit d8e39d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1287
-663
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
*Note: Numbers like (\#123) point to closed Pull Requests on the fractal-web repository.*
22

3+
# Unreleased
4+
5+
* Fixed input filters lost after version update (\#535);
6+
* JSON Schema form: computed default values also for empty object (\#535);
7+
* Supported `prefixItems` of JSON Schema Draft 2020-12 - `pydantic_v2` (\#535);
8+
39
# 1.3.2
410

511
* Supported `pydantic_v2` schemas (\#532);

jschema/__tests__/JSchemaTestWrapper.svelte

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
export let schema;
66
/** @type {any} */
77
export let schemaData;
8+
/** @type {'pydantic_v1'|'pydantic_v2'} */
9+
export let schemaVersion;
810
/** @type {(data: any) => void} */
911
export let onChange = function () {};
1012
@@ -26,4 +28,11 @@
2628
}
2729
</script>
2830

29-
<JSchema componentId="test" bind:this={jschema} {schema} {schemaData} on:change={innerOnChange} />
31+
<JSchema
32+
componentId="test"
33+
bind:this={jschema}
34+
{schema}
35+
{schemaData}
36+
{schemaVersion}
37+
on:change={innerOnChange}
38+
/>

jschema/__tests__/bad_input.test.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ describe('badInput', () => {
1818
}
1919
}
2020
},
21-
vi.fn()
21+
vi.fn(),
22+
'pydantic_v1'
2223
);
2324
expect(manager.getFormData()).deep.eq({ foo: { bar: null } });
2425
manager.root.children[0].children[0].badInput = true;
@@ -40,7 +41,8 @@ describe('badInput', () => {
4041
}
4142
}
4243
},
43-
vi.fn()
44+
vi.fn(),
45+
'pydantic_v1'
4446
);
4547
expect(manager.getFormData()).deep.eq({ foo: [0] });
4648
manager.root.children[0].children[0].badInput = true;
@@ -66,7 +68,8 @@ describe('badInput', () => {
6668
}
6769
}
6870
},
69-
vi.fn()
71+
vi.fn(),
72+
'pydantic_v1'
7073
);
7174
expect(manager.getFormData()).deep.eq({ foo: [0] });
7275
manager.root.children[0].children[0].badInput = true;

jschema/__tests__/jschema_initial_data.test.js

Lines changed: 128 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ describe('jschema_intial_data', () => {
8080
};
8181

8282
it('Generate default data with undefined initial value', () => {
83-
const data = getJsonSchemaData(schema, undefined);
83+
const data = getJsonSchemaData(schema, 'pydantic_v1', undefined);
8484

8585
expect(data.arrayProp.length).eq(0);
8686
expect(data.objectProp.requiredArrayWithMinItems.length).eq(3);
@@ -112,7 +112,7 @@ describe('jschema_intial_data', () => {
112112
}
113113
};
114114

115-
const data = getJsonSchemaData(schema, initialValue);
115+
const data = getJsonSchemaData(schema, 'pydantic_v1', initialValue);
116116

117117
expect(data.arrayProp.length).eq(1);
118118
expect(data.arrayProp[0]).eq('x');
@@ -162,6 +162,7 @@ describe('jschema_intial_data', () => {
162162
}
163163
}
164164
},
165+
'pydantic_v1',
165166
{ a1: [{ p1: 'foo' }] }
166167
);
167168

@@ -189,6 +190,7 @@ describe('jschema_intial_data', () => {
189190
}
190191
}
191192
},
193+
'pydantic_v1',
192194
{ t1: [{ p1: 'foo' }, { p2: 'bar' }] }
193195
);
194196

@@ -214,6 +216,7 @@ describe('jschema_intial_data', () => {
214216
}
215217
}
216218
},
219+
'pydantic_v1',
217220
{ t1: ['a', 'b', 'c', 'd'] }
218221
);
219222

@@ -243,6 +246,7 @@ describe('jschema_intial_data', () => {
243246
}
244247
}
245248
},
249+
'pydantic_v1',
246250
{ obj: { key1: { prop1: 'foo' } } }
247251
);
248252

@@ -263,6 +267,7 @@ describe('jschema_intial_data', () => {
263267
}
264268
}
265269
},
270+
'pydantic_v1',
266271
{}
267272
);
268273

@@ -288,6 +293,7 @@ describe('jschema_intial_data', () => {
288293
}
289294
}
290295
},
296+
'pydantic_v1',
291297
undefined
292298
);
293299

@@ -317,6 +323,7 @@ describe('jschema_intial_data', () => {
317323
}
318324
}
319325
},
326+
'pydantic_v1',
320327
undefined
321328
);
322329

@@ -346,6 +353,7 @@ describe('jschema_intial_data', () => {
346353
}
347354
}
348355
},
356+
'pydantic_v1',
349357
undefined
350358
);
351359

@@ -373,6 +381,7 @@ describe('jschema_intial_data', () => {
373381
}
374382
}
375383
},
384+
'pydantic_v1',
376385
undefined
377386
);
378387

@@ -396,6 +405,7 @@ describe('jschema_intial_data', () => {
396405
}
397406
}
398407
},
408+
'pydantic_v1',
399409
undefined
400410
);
401411

@@ -420,6 +430,7 @@ describe('jschema_intial_data', () => {
420430
},
421431
required: ['tuple']
422432
},
433+
'pydantic_v1',
423434
undefined
424435
);
425436

@@ -447,6 +458,7 @@ describe('jschema_intial_data', () => {
447458
},
448459
required: ['tuple']
449460
},
461+
'pydantic_v1',
450462
undefined
451463
);
452464

@@ -462,26 +474,127 @@ describe('jschema_intial_data', () => {
462474
b2: { type: 'boolean' }
463475
}
464476
},
477+
'pydantic_v1',
465478
{ b1: false }
466479
);
467480
expect(data).deep.eq({ b1: false, b2: null });
468481
});
469482

470483
it('Handle tuple size/items mismatch (minItems = 2; items.length = 1)', () => {
471-
const data = getJsonSchemaData({
472-
title: 'test',
473-
type: 'object',
474-
properties: {
475-
foo: {
476-
default: [1, 2],
477-
type: 'array',
478-
minItems: 2,
479-
maxItems: 2,
480-
items: [{ type: 'integer' }]
481-
}
484+
const data = getJsonSchemaData(
485+
{
486+
title: 'test',
487+
type: 'object',
488+
properties: {
489+
foo: {
490+
default: [1, 2],
491+
type: 'array',
492+
minItems: 2,
493+
maxItems: 2,
494+
items: [{ type: 'integer' }]
495+
}
496+
},
497+
required: ['foo']
482498
},
483-
required: ['foo']
484-
});
499+
'pydantic_v1'
500+
);
485501
expect(data).deep.eq({ foo: [1, null] });
486502
});
503+
504+
it('Tuple with prefixItems (pydantic_v2)', async function () {
505+
const data = getJsonSchemaData(
506+
{
507+
title: 'test',
508+
type: 'object',
509+
properties: {
510+
foo: {
511+
default: [1, 1],
512+
maxItems: 2,
513+
minItems: 2,
514+
prefixItems: [{ type: 'integer' }, { type: 'integer' }],
515+
type: 'array'
516+
}
517+
},
518+
required: ['foo']
519+
},
520+
'pydantic_v2'
521+
);
522+
expect(data).deep.eq({ foo: [1, 1] });
523+
});
524+
525+
it('Compute default for null initial value', async function () {
526+
const data = getJsonSchemaData(
527+
{
528+
title: 'test',
529+
type: 'object',
530+
properties: {
531+
foo: {
532+
default: 1,
533+
type: 'number'
534+
}
535+
}
536+
},
537+
'pydantic_v2',
538+
null
539+
);
540+
expect(data).deep.eq({ foo: 1 });
541+
});
542+
543+
it('Compute default for undefined initial value', async function () {
544+
const data = getJsonSchemaData(
545+
{
546+
title: 'test',
547+
type: 'object',
548+
properties: {
549+
foo: {
550+
default: 1,
551+
type: 'number'
552+
}
553+
}
554+
},
555+
'pydantic_v2',
556+
undefined
557+
);
558+
expect(data).deep.eq({ foo: 1 });
559+
});
560+
561+
it('Compute default for empty object initial value', async function () {
562+
const data = getJsonSchemaData(
563+
{
564+
title: 'test',
565+
type: 'object',
566+
properties: {
567+
foo: {
568+
default: 1,
569+
type: 'number'
570+
}
571+
}
572+
},
573+
'pydantic_v2',
574+
{}
575+
);
576+
expect(data).deep.eq({ foo: 1 });
577+
});
578+
579+
it('Does not compute default for populated initial value', async function () {
580+
const data = getJsonSchemaData(
581+
{
582+
title: 'test',
583+
type: 'object',
584+
properties: {
585+
foo: {
586+
default: 1,
587+
type: 'number'
588+
},
589+
bar: {
590+
default: 2,
591+
type: 'number'
592+
}
593+
}
594+
},
595+
'pydantic_v2',
596+
{ foo: 5 }
597+
);
598+
expect(data).deep.eq({ foo: 5, bar: null });
599+
});
487600
});

0 commit comments

Comments
 (0)