Skip to content

Commit

Permalink
fix(@ngtools/json-schema): serialize object properties better. (angul…
Browse files Browse the repository at this point in the history
…ar#4103)

The problem was that in an object that allowed additional properties, we were not serializing the object new values properly.

Fixes angular#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.