mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-25 19:18:59 +01:00
533 lines
15 KiB
TypeScript
533 lines
15 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
'use strict';
|
|
|
|
import assert = require('assert');
|
|
import SchemaService = require('../jsonSchemaService');
|
|
import JsonSchema = require('../json-toolbox/jsonSchema');
|
|
import Json = require('../json-toolbox/json');
|
|
import Parser = require('../jsonParser');
|
|
import fs = require('fs');
|
|
import path = require('path');
|
|
import {IXHROptions, IXHRResponse} from '../utils/httpRequest';
|
|
|
|
|
|
suite('JSON Schema', () => {
|
|
var fixureDocuments = {
|
|
'http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json': 'deploymentTemplate.json',
|
|
'http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json': 'deploymentParameters.json',
|
|
'http://schema.management.azure.com/schemas/2015-01-01/Microsoft.Authorization.json': 'Microsoft.Authorization.json',
|
|
'http://schema.management.azure.com/schemas/2015-01-01/Microsoft.Resources.json': 'Microsoft.Resources.json',
|
|
'http://schema.management.azure.com/schemas/2014-04-01-preview/Microsoft.Sql.json': 'Microsoft.Sql.json',
|
|
'http://schema.management.azure.com/schemas/2014-06-01/Microsoft.Web.json': 'Microsoft.Web.json',
|
|
'http://schema.management.azure.com/schemas/2014-04-01/SuccessBricks.ClearDB.json': 'SuccessBricks.ClearDB.json',
|
|
'http://schema.management.azure.com/schemas/2015-08-01/Microsoft.Compute.json': 'Microsoft.Compute.json'
|
|
}
|
|
|
|
var requestServiceMock = function (options:IXHROptions) : Promise<IXHRResponse> {
|
|
var uri = options.url;
|
|
if (uri.length && uri[uri.length - 1] === '#') {
|
|
uri = uri.substr(0, uri.length - 1);
|
|
}
|
|
var fileName = fixureDocuments[uri];
|
|
if (fileName) {
|
|
return new Promise<IXHRResponse>((c, e) => {
|
|
var fixturePath = path.join(__dirname, '../../src/test/fixtures', fileName);
|
|
fs.readFile(fixturePath, 'UTF-8', (err, result) => {
|
|
err ? e({ responseText: '', status: 404 }) : c({ responseText: result.toString(), status: 200 })
|
|
});
|
|
});
|
|
}
|
|
return Promise.reject<IXHRResponse>({ responseText: '', status: 404 });
|
|
}
|
|
|
|
test('Resolving $refs', function(testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
service.setSchemaContributions({ schemas: {
|
|
"https://myschemastore/main" : {
|
|
id: 'https://myschemastore/main',
|
|
type: 'object',
|
|
properties: {
|
|
child: {
|
|
'$ref': 'https://myschemastore/child'
|
|
}
|
|
}
|
|
},
|
|
"https://myschemastore/child" :{
|
|
id: 'https://myschemastore/child',
|
|
type: 'bool',
|
|
description: 'Test description'
|
|
}
|
|
}});
|
|
|
|
service.getResolvedSchema('https://myschemastore/main').then(fs => {
|
|
assert.deepEqual(fs.schema.properties['child'], {
|
|
id: 'https://myschemastore/child',
|
|
type: 'bool',
|
|
description: 'Test description'
|
|
});
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
|
|
});
|
|
|
|
test('FileSchema', function(testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
|
|
service.setSchemaContributions({ schemas: {
|
|
"main" : {
|
|
id: 'main',
|
|
type: 'object',
|
|
properties: {
|
|
child: {
|
|
type: 'object',
|
|
properties: {
|
|
'grandchild': {
|
|
type: 'number',
|
|
description: 'Meaning of Life'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}});
|
|
|
|
service.getResolvedSchema('main').then(fs => {
|
|
var section = fs.getSection(['child', 'grandchild']);
|
|
assert.equal(section.description, 'Meaning of Life');
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
});
|
|
|
|
test('Array FileSchema', function(testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
|
|
service.setSchemaContributions({ schemas: {
|
|
"main" : {
|
|
id: 'main',
|
|
type: 'object',
|
|
properties: {
|
|
child: {
|
|
type: 'array',
|
|
items: {
|
|
'type': 'object',
|
|
'properties': {
|
|
'grandchild': {
|
|
type: 'number',
|
|
description: 'Meaning of Life'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}});
|
|
|
|
service.getResolvedSchema('main').then(fs => {
|
|
var section = fs.getSection(['child','0', 'grandchild']);
|
|
assert.equal(section.description, 'Meaning of Life');
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
});
|
|
|
|
test('Missing subschema', function(testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
|
|
service.setSchemaContributions({ schemas: {
|
|
"main" : {
|
|
id: 'main',
|
|
type: 'object',
|
|
properties: {
|
|
child: {
|
|
type: 'object'
|
|
}
|
|
}
|
|
}
|
|
}});
|
|
|
|
service.getResolvedSchema('main').then(fs => {
|
|
var section = fs.getSection(['child','grandchild']);
|
|
assert.strictEqual(section, null);
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
});
|
|
|
|
test('Preloaded Schema', function(testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
var id = 'https://myschemastore/test1';
|
|
var schema : JsonSchema.IJSONSchema = {
|
|
type: 'object',
|
|
properties: {
|
|
child: {
|
|
type: 'object',
|
|
properties: {
|
|
'grandchild': {
|
|
type: 'number',
|
|
description: 'Meaning of Life'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
service.registerExternalSchema(id, [ '*.json' ], schema);
|
|
|
|
service.getSchemaForResource('test.json', null).then((schema) => {
|
|
var section = schema.getSection(['child','grandchild']);
|
|
assert.equal(section.description, 'Meaning of Life');
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
});
|
|
|
|
test('External Schema', function(testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
var id = 'https://myschemastore/test1';
|
|
var schema : JsonSchema.IJSONSchema = {
|
|
type: 'object',
|
|
properties: {
|
|
child: {
|
|
type: 'object',
|
|
properties: {
|
|
'grandchild': {
|
|
type: 'number',
|
|
description: 'Meaning of Life'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
service.registerExternalSchema(id, [ '*.json' ], schema);
|
|
|
|
service.getSchemaForResource('test.json', null).then((schema) => {
|
|
var section = schema.getSection(['child','grandchild']);
|
|
assert.equal(section.description, 'Meaning of Life');
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
});
|
|
|
|
|
|
test('Resolving in-line $refs', function (testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
var id = 'https://myschemastore/test1';
|
|
|
|
var schema:JsonSchema.IJSONSchema = {
|
|
id: 'main',
|
|
type: 'object',
|
|
definitions: {
|
|
'grandchild': {
|
|
type: 'number',
|
|
description: 'Meaning of Life'
|
|
}
|
|
},
|
|
properties: {
|
|
child: {
|
|
type: 'array',
|
|
items: {
|
|
'type': 'object',
|
|
'properties': {
|
|
'grandchild': {
|
|
$ref: '#/definitions/grandchild'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
service.registerExternalSchema(id, [ '*.json' ], schema);
|
|
|
|
service.getSchemaForResource('test.json', null).then((fs) => {
|
|
var section = fs.getSection(['child', '0', 'grandchild']);
|
|
assert.equal(section.description, 'Meaning of Life');
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
});
|
|
|
|
test('Resolving in-line $refs automatically for external schemas', function(testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
var id = 'https://myschemastore/test1';
|
|
var schema:JsonSchema.IJSONSchema = {
|
|
id: 'main',
|
|
type: 'object',
|
|
definitions: {
|
|
'grandchild': {
|
|
type: 'number',
|
|
description: 'Meaning of Life'
|
|
}
|
|
},
|
|
properties: {
|
|
child: {
|
|
type: 'array',
|
|
items: {
|
|
'type': 'object',
|
|
'properties': {
|
|
'grandchild': {
|
|
$ref: '#/definitions/grandchild'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
var fsm = service.registerExternalSchema(id, [ '*.json' ], schema);
|
|
fsm.getResolvedSchema().then((fs) => {
|
|
var section = fs.getSection(['child','0', 'grandchild']);
|
|
assert.equal(section.description, 'Meaning of Life');
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
});
|
|
|
|
|
|
test('Clearing External Schemas', function(testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
var id1 = 'http://myschemastore/test1';
|
|
var schema1:JsonSchema.IJSONSchema = {
|
|
type: 'object',
|
|
properties: {
|
|
child: {
|
|
type: 'number'
|
|
}
|
|
}
|
|
};
|
|
|
|
var id2 = 'http://myschemastore/test2';
|
|
var schema2:JsonSchema.IJSONSchema = {
|
|
type: 'object',
|
|
properties: {
|
|
child: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
};
|
|
|
|
service.registerExternalSchema(id1, [ 'test.json', 'bar.json' ], schema1);
|
|
|
|
service.getSchemaForResource('test.json', null).then((schema) => {
|
|
var section = schema.getSection(['child']);
|
|
assert.equal(section.type, 'number');
|
|
|
|
service.clearExternalSchemas();
|
|
|
|
service.registerExternalSchema(id2, [ '*.json' ], schema2);
|
|
|
|
return service.getSchemaForResource('test.json', null).then((schema) => {
|
|
var section = schema.getSection(['child']);
|
|
assert.equal(section.type, 'string');
|
|
});
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
});
|
|
|
|
test('Schema contributions', function(testDone) {
|
|
var service = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
|
|
service.setSchemaContributions({ schemas: {
|
|
"http://myschemastore/myschemabar" : {
|
|
id: 'main',
|
|
type: 'object',
|
|
properties: {
|
|
foo: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
}
|
|
}, schemaAssociations: {
|
|
'*.bar': ['http://myschemastore/myschemabar', 'http://myschemastore/myschemafoo']
|
|
}});
|
|
|
|
var id2 = 'http://myschemastore/myschemafoo';
|
|
var schema2:JsonSchema.IJSONSchema = {
|
|
type: 'object',
|
|
properties: {
|
|
child: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
};
|
|
|
|
service.registerExternalSchema(id2, null, schema2);
|
|
|
|
service.getSchemaForResource('main.bar', null).then(resolvedSchema => {
|
|
assert.deepEqual(resolvedSchema.errors, []);
|
|
assert.equal(2, resolvedSchema.schema.allOf.length);
|
|
|
|
service.clearExternalSchemas();
|
|
return service.getSchemaForResource('main.bar', null).then(resolvedSchema => {
|
|
assert.equal(resolvedSchema.errors.length, 1);
|
|
assert.ok(resolvedSchema.errors[0].indexOf("Problems loading reference 'http://myschemastore/myschemafoo'") === 0);
|
|
|
|
service.clearExternalSchemas();
|
|
service.registerExternalSchema(id2, null, schema2);
|
|
return service.getSchemaForResource('main.bar', null).then(resolvedSchema => {
|
|
assert.equal(resolvedSchema.errors.length, 0);
|
|
});
|
|
});
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
});
|
|
|
|
test('Resolving circular $refs', function(testDone) {
|
|
|
|
var service : SchemaService.IJSONSchemaService = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
|
|
var input = {
|
|
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
|
"contentVersion": "1.0.0.0",
|
|
"resources": [
|
|
{
|
|
"name": "SQLServer",
|
|
"type": "Microsoft.Sql/servers",
|
|
"location": "West US",
|
|
"apiVersion": "2014-04-01-preview",
|
|
"dependsOn": [ ],
|
|
"tags": {
|
|
"displayName": "SQL Server"
|
|
},
|
|
"properties": {
|
|
"administratorLogin": "asdfasd",
|
|
"administratorLoginPassword": "asdfasdfasd"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
var document = Parser.parse(JSON.stringify(input));
|
|
|
|
service.getSchemaForResource('file://doc/mydoc.json', document).then(resolveSchema => {
|
|
assert.deepEqual(resolveSchema.errors, []);
|
|
|
|
var content = JSON.stringify(resolveSchema.schema);
|
|
assert.equal(content.indexOf('$ref'), -1); // no more $refs
|
|
|
|
var matchingSchemas = [];
|
|
document.validate(resolveSchema.schema, matchingSchemas);
|
|
assert.deepEqual(document.errors, []);
|
|
assert.deepEqual(document.warnings, []);
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
|
|
});
|
|
|
|
test('Resolving circular $refs, invalid document', function(testDone) {
|
|
|
|
var service : SchemaService.IJSONSchemaService = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
|
|
var input = {
|
|
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
|
"contentVersion": "1.0.0.0",
|
|
"resources": [
|
|
{
|
|
"name": "foo",
|
|
"type": "Microsoft.Resources/deployments",
|
|
"apiVersion": "2015-01-01",
|
|
}
|
|
]
|
|
}
|
|
|
|
var document = Parser.parse(JSON.stringify(input));
|
|
|
|
service.getSchemaForResource('file://doc/mydoc.json', document).then(resolveSchema => {
|
|
assert.deepEqual(resolveSchema.errors, []);
|
|
|
|
var content = JSON.stringify(resolveSchema.schema);
|
|
assert.equal(content.indexOf('$ref'), -1); // no more $refs
|
|
|
|
var matchingSchemas = [];
|
|
document.validate(resolveSchema.schema, matchingSchemas);
|
|
assert.deepEqual(document.errors, []);
|
|
assert.equal(document.warnings.length, 1);
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
|
|
});
|
|
|
|
test('Validate Azure Resource Dfinition', function(testDone) {
|
|
|
|
|
|
var service : SchemaService.IJSONSchemaService = new SchemaService.JSONSchemaService(requestServiceMock);
|
|
|
|
var input = {
|
|
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
|
"contentVersion": "1.0.0.0",
|
|
"resources": [
|
|
{
|
|
"apiVersion": "2015-06-15",
|
|
"type": "Microsoft.Compute/virtualMachines",
|
|
"name": "a",
|
|
"location": "West US",
|
|
"properties": {
|
|
"hardwareProfile": {
|
|
"vmSize": "Small"
|
|
},
|
|
"osProfile": {
|
|
"computername": "a",
|
|
"adminUsername": "a",
|
|
"adminPassword": "a"
|
|
},
|
|
"storageProfile": {
|
|
"imageReference": {
|
|
"publisher": "a",
|
|
"offer": "a",
|
|
"sku": "a",
|
|
"version": "latest"
|
|
},
|
|
"osDisk": {
|
|
"name": "osdisk",
|
|
"vhd": {
|
|
"uri": "[concat('http://', 'b','.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]"
|
|
},
|
|
"caching": "ReadWrite",
|
|
"createOption": "FromImage"
|
|
}
|
|
},
|
|
"networkProfile": {
|
|
"networkInterfaces": [
|
|
{
|
|
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
|
|
}
|
|
]
|
|
},
|
|
"diagnosticsProfile": {
|
|
"bootDiagnostics": {
|
|
"enabled": "true",
|
|
"storageUri": "[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net')]"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
var document = Parser.parse(JSON.stringify(input));
|
|
|
|
service.getSchemaForResource('file://doc/mydoc.json', document).then(resolvedSchema => {
|
|
assert.deepEqual(resolvedSchema.errors, []);
|
|
|
|
document.validate(resolvedSchema.schema);
|
|
|
|
assert.equal(document.warnings.length, 1);
|
|
assert.equal(document.warnings[0].message, 'Missing property "computerName"');
|
|
}).then(() => testDone(), (error) => {
|
|
testDone(error);
|
|
});
|
|
|
|
});
|
|
|
|
});
|