Skip to content

Commit

Permalink
fix(@ngtools/json-schema): enum values properly handle defaults and n…
Browse files Browse the repository at this point in the history
…ull. (#4387)

NULL are not valid values, and now the default will be respected.
  • Loading branch information
hansl authored Feb 3, 2017
1 parent 2048459 commit ea9f334
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 18 deletions.
10 changes: 10 additions & 0 deletions packages/@ngtools/json-schema/src/schema-tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ describe('@ngtools/json-schema', () => {
proto.a[1] = 'INVALID';
expect(proto.a).toEqual(['v2', null, null, 'v3']);
});

it('supports default values', () => {
const proto: any = Object.create(null);
const schema = new RootSchemaTreeNode(proto, {
value: valueJson,
schema: schemaJson
});

expect(schema.children['b'].get()).toEqual('default');
});
});

});
34 changes: 18 additions & 16 deletions packages/@ngtools/json-schema/src/schema-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export abstract class SchemaTreeNode<T> implements SchemaNode {
get itemPrototype(): SchemaTreeNode<any> | null { return null; }

abstract get(): T;
set(v: T, force = false) {
set(v: T, init = false, force = false) {
if (!this.readOnly) {
throw new MissingImplementationError();
}
Expand Down Expand Up @@ -220,10 +220,10 @@ export class OneOfSchemaTreeNode extends NonLeafSchemaTreeNode<any> {
}

this._currentTypeHolder = proto;
this._currentTypeHolder.set(v, true);
this._currentTypeHolder.set(v, false, true);
}

set(v: any, force = false) {
set(v: any, init = false, force = false) {
return this._set(v, false, force);
}

Expand Down Expand Up @@ -338,7 +338,6 @@ export class ArraySchemaTreeNode extends NonLeafSchemaTreeNode<Array<any>> {
const schema = this._schema;
const forward = this._forward;

this._defined = !!value;
this._value = Object.create(null);
this._dirty = this._dirty || !init;

Expand All @@ -361,8 +360,8 @@ export class ArraySchemaTreeNode extends NonLeafSchemaTreeNode<Array<any>> {
}
}

set(v: any, force = false) {
return this._set(v, false, force);
set(v: any, init = false, force = false) {
return this._set(v, init, force);
}

isCompatible(v: any) { return Array.isArray(v); }
Expand Down Expand Up @@ -395,7 +394,7 @@ export class RootSchemaTreeNode extends ObjectSchemaTreeNode {

/** A leaf in the schema tree. Must contain a single primitive value. */
export abstract class LeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
private _default: T;
protected _default: T;

constructor(metaData: TreeNodeConstructorArgument<T>) {
super(metaData);
Expand All @@ -410,13 +409,13 @@ export abstract class LeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
return this._forward.get();
}
if (!this.defined) {
return this._default !== undefined ? this._default : undefined;
return 'default' in this._schema ? this._default : undefined;
}
return this._value === undefined
? undefined
: (this._value === null ? null : this.convert(this._value));
}
set(v: T, force = false) {
set(v: T, init = false, force = false) {
if (this.readOnly && !force) {
throw new SettingReadOnlyPropertyError();
}
Expand All @@ -428,7 +427,7 @@ export abstract class LeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
}
}

this.dirty = true;
this.dirty = !init;
this._value = convertedValue;
}

Expand All @@ -438,7 +437,10 @@ export abstract class LeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
}

get defaultValue(): T {
return 'default' in this._schema ? this._default : null;
return this.hasDefault ? this._default : null;
}
get hasDefault() {
return 'default' in this._schema;
}

abstract convert(v: any): T;
Expand All @@ -462,20 +464,20 @@ class StringSchemaTreeNode extends LeafSchemaTreeNode<string> {


class EnumSchemaTreeNode extends StringSchemaTreeNode {
private _enumValues: string[];

constructor(metaData: TreeNodeConstructorArgument<string>) {
super(metaData);

if (!Array.isArray(metaData.schema['enum'])) {
throw new InvalidSchema();
}
this._enumValues = [].concat(metaData.schema['enum']);
this.set(metaData.value, true);
if (this.hasDefault && !this._isInEnum(this._default)) {
throw new InvalidSchema();
}
this.set(metaData.value, true, true);
}

protected _isInEnum(value: string) {
return this._enumValues.some(v => v === value);
return this._schema['enum'].some((v: string) => v === value);
}

isCompatible(v: any) {
Expand Down
4 changes: 4 additions & 0 deletions packages/@ngtools/json-schema/tests/schema2.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
"items": {
"enum": [ "v1", "v2", "v3" ]
}
},
"b": {
"enum": [ "default", "v1", "v2" ],
"default": "default"
}
}
}
4 changes: 2 additions & 2 deletions packages/@ngtools/json-schema/tests/serializer/value2.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"a": [
null,
"v2",
"v1",
null,
"v2",
"v3"
]
}

0 comments on commit ea9f334

Please sign in to comment.