Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/parser/jsonParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,11 @@ export class ValidationResult {
}

public hasProblems(): boolean {
return !!this.problems.length;
// A deprecation notice is advisory, not a validation failure. It must not make an
// otherwise-valid schema look like a non-match, otherwise a deprecated-but-matching
// `anyOf`/`oneOf` alternative loses to a non-matching one (see #304). The deprecation
// problem is still reported; it just doesn't count towards match selection here.
return this.problems.some(p => p.code !== ErrorCode.Deprecated);
}

public merge(validationResult: ValidationResult): void {
Expand Down
31 changes: 31 additions & 0 deletions src/test/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2633,6 +2633,37 @@ suite('JSON Parser', () => {

});

test('deprecated alternative in anyOf is selected when it matches (#304)', function () {
// The value matches the second (deprecated) branch. The deprecation warning must not make
// that branch look like a non-match, otherwise the non-matching `const` branch is reported
// instead of the expected "Value is deprecated".
const schema: JSONSchema = {
type: 'object',
properties: {
'key': {
anyOf: [
{ type: 'string', const: 'unused literal' },
{ type: 'string', pattern: '^text value$', deprecated: true }
]
}
}
};
{
const { textDoc, jsonDoc } = toDocument('{ "key": "text value" }');
const semanticErrors = validate2(jsonDoc, textDoc, schema)!;
assert.strictEqual(semanticErrors.length, 1);
assert.strictEqual(semanticErrors[0].code, ErrorCode.Deprecated);
}

// A value that matches neither branch still reports the non-match, unaffected by the fix.
{
const { textDoc, jsonDoc } = toDocument('{ "key": "other value" }');
const semanticErrors = validate2(jsonDoc, textDoc, schema)!;
assert.strictEqual(semanticErrors.length, 1);
assert.notStrictEqual(semanticErrors[0].code, ErrorCode.Deprecated);
}
});

test('Strings with spaces', function () {

const { textDoc, jsonDoc } = toDocument('{"key1":"first string", "key2":["second string"]}');
Expand Down