Skip to content

Commit

Permalink
fix(@ngtools/json-schema): serialize object properties better. (#4103)
Browse files Browse the repository at this point in the history
The problem was that in an object that allowed additional properties, we were not serializing the object new values properly.

Fixes #4044.
  • Loading branch information
hansl authored Jan 18, 2017
1 parent cd296bc commit 48d1e44
Show file tree
Hide file tree
Showing 8 changed files with 431 additions and 23 deletions.
46 changes: 24 additions & 22 deletions packages/@ngtools/json-schema/src/serializers/json.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,28 @@ import {RootSchemaTreeNode} from '../schema-tree';


describe('JsonSerializer', () => {
const schemaJsonFilePath = path.join(__dirname, '../../tests/schema1.json');
const schemaJson = JSON.parse(fs.readFileSync(schemaJsonFilePath, 'utf-8'));
const valueJsonFilePath = path.join(__dirname, '../../tests/value1.json');
const valueJson = JSON.parse(fs.readFileSync(valueJsonFilePath, 'utf-8'));

const schemaClass = new (SchemaClassFactory(schemaJson))(valueJson);
const schema: RootSchemaTreeNode = schemaClass.$$schema();

it('works', () => {
let str = '';
function writer(s: string) {
str += s;
}

const serializer = new JsonSerializer(writer);

serializer.start();
schema.serialize(serializer);
serializer.end();

expect(JSON.stringify(JSON.parse(str))).toEqual(JSON.stringify(valueJson));
});
for (const nb of [1, 2, 3]) {
it(`works (${nb})`, () => {
const schemaJsonFilePath = path.join(__dirname, `../../tests/serializer/schema${nb}.json`);
const schemaJson = JSON.parse(fs.readFileSync(schemaJsonFilePath, 'utf-8'));
const valueJsonFilePath = path.join(__dirname, `../../tests/serializer/value${nb}.json`);
const valueJson = JSON.parse(fs.readFileSync(valueJsonFilePath, 'utf-8'));

const schemaClass = new (SchemaClassFactory(schemaJson))(valueJson);
const schema: RootSchemaTreeNode = schemaClass.$$schema();

let str = '';
function writer(s: string) {
str += s;
}

const serializer = new JsonSerializer(writer);

serializer.start();
schema.serialize(serializer);
serializer.end();

expect(JSON.stringify(JSON.parse(str))).toEqual(JSON.stringify(valueJson));
});
}
});
2 changes: 1 addition & 1 deletion packages/@ngtools/json-schema/src/serializers/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class JsonSerializer implements Serializer {
this._willOutputValue();
this._writer(JSON.stringify(key));
this._writer(': ');
this._writer(JSON.stringify(node.value));
this._writer(JSON.stringify(node.value[key]));
}
}

Expand Down
84 changes: 84 additions & 0 deletions packages/@ngtools/json-schema/tests/serializer/schema1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "JsonSchema",
"type": "object",
"properties": {
"requiredKey": {
"type": "number"
},
"stringKeyDefault": {
"type": "string",
"default": "defaultValue"
},
"stringKey": {
"type": "string"
},
"booleanKey": {
"type": "boolean"
},
"numberKey": {
"type": "number"
},
"oneOfKey1": {
"oneOf": [
{ "type": "string" },
{ "type": "number" }
]
},
"oneOfKey2": {
"oneOf": [
{ "type": "string" },
{ "type": "array", "items": { "type": "string" } }
]
},
"objectKey1": {
"type": "object",
"properties": {
"stringKey": {
"type": "string"
},
"objectKey": {
"type": "object",
"properties": {
"stringKey": {
"type": "string"
}
}
}
}
},
"objectKey2": {
"type": "object",
"properties": {
"stringKey": {
"type": "string",
"default": "default objectKey2.stringKey"
}
},
"additionalProperties": true
},
"arrayKey1": {
"type": "array",
"items": {
"type": "object",
"properties": {
"stringKey": {
"type": "string"
}
}
}
},
"arrayKey2": {
"type": "array",
"items": {
"type": "object",
"properties": {
"stringKey": {
"type": "string"
}
}
}
}
},
"required": ["requiredKey"]
}
13 changes: 13 additions & 0 deletions packages/@ngtools/json-schema/tests/serializer/schema2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "JsonSchema",
"type": "object",
"properties": {
"a": {
"type": "array",
"items": {
"enum": [ "v1", "v2", "v3" ]
}
}
}
}
237 changes: 237 additions & 0 deletions packages/@ngtools/json-schema/tests/serializer/schema3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
{
"$comment": "Please run `npm run build-config-interface` after changing this file. Thanks!",
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "CliConfig",
"title": "Angular CLI Config Schema",
"type": "object",
"properties": {
"project": {
"description": "The global configuration of the project.",
"type": "object",
"properties": {
"version": {
"type": "string"
},
"name": {
"type": "string"
}
},
"additionalProperties": false
},
"apps": {
"description": "Properties of the different applications in this project.",
"type": "array",
"items": {
"type": "object",
"properties": {
"root": {
"type": "string"
},
"outDir": {
"type": "string",
"default": "dist/"
},
"assets": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"default": []
},
"deployUrl": {
"type": "string"
},
"index": {
"type": "string",
"default": "index.html"
},
"main": {
"type": "string"
},
"test": {
"type": "string"
},
"tsconfig": {
"type": "string",
"default": "tsconfig.json"
},
"prefix": {
"type": "string"
},
"mobile": {
"type": "boolean"
},
"styles": {
"description": "Global styles to be included in the build.",
"type": "array",
"items": {
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"input": {
"type": "string"
}
},
"additionalProperties": true
}
]
},
"additionalProperties": false
},
"scripts": {
"description": "Global scripts to be included in the build.",
"type": "array",
"items": {
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"input": {
"type": "string"
}
},
"additionalProperties": true,
"required": ["input"]
}
]
},
"additionalProperties": false
},
"environments": {
"description": "Name and corresponding file for environment config.",
"type": "object",
"additionalProperties": true
}
},
"additionalProperties": false
},
"additionalProperties": false
},
"addons": {
"description": "Configuration reserved for installed third party addons.",
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": true
}
},
"packages": {
"description": "Configuration reserved for installed third party packages.",
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": true
}
},
"e2e": {
"type": "object",
"properties": {
"protractor": {
"type": "object",
"properties": {
"config": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"test": {
"type": "object",
"properties": {
"karma": {
"type": "object",
"properties": {
"config": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"defaults": {
"type": "object",
"properties": {
"styleExt": {
"type": "string"
},
"prefixInterfaces": {
"type": "boolean"
},
"poll": {
"type": "number"
},
"viewEncapsulation": {
"type": "string"
},
"changeDetection": {
"type": "string"
},
"inline": {
"type": "object",
"properties": {
"style": {
"type": "boolean",
"default": false
},
"template": {
"type": "boolean",
"default": false
}
}
},
"spec": {
"type": "object",
"properties": {
"class": {
"type": "boolean",
"default": false
},
"component": {
"type": "boolean",
"default": true
},
"directive": {
"type": "boolean",
"default": true
},
"module": {
"type": "boolean",
"default": false
},
"pipe": {
"type": "boolean",
"default": true
},
"service": {
"type": "boolean",
"default": true
}
}
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
Loading

0 comments on commit 48d1e44

Please sign in to comment.