From ebb0b66d7d8cb39c0698befc39c07847cc66bca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Pintos=20L=C3=B3pez?= Date: Wed, 6 Sep 2023 23:56:36 +0200 Subject: [PATCH 1/2] refactor(json-schema-parser): add getJsonSchemaBaseUri --- .../calculations/getJsonSchemaBaseUri.spec.ts | 93 +++++++++++++++++++ .../calculations/getJsonSchemaBaseUri.ts | 20 ++++ 2 files changed, 113 insertions(+) create mode 100644 packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.spec.ts create mode 100644 packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.ts diff --git a/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.spec.ts b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.spec.ts new file mode 100644 index 0000000..79e5746 --- /dev/null +++ b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.spec.ts @@ -0,0 +1,93 @@ +import { afterAll, beforeAll, describe, expect, it, jest } from '@jest/globals'; + +jest.mock('@cuaklabs/uri'); + +import { JsonSchemaObject } from '@cuaklabs/json-schema-types/2020-12'; +import { getBaseUri, GetBaseUriOptions } from '@cuaklabs/uri'; + +import { JsonRootSchema202012Fixtures } from '../fixtures/JsonRootSchema202012Fixtures'; +import { getJsonSchemaBaseUri } from './getJsonSchemaBaseUri'; + +describe(getJsonSchemaBaseUri.name, () => { + describe('having a JsonSchema with $id', () => { + let jsonSchemaFixture: JsonSchemaObject; + + beforeAll(() => { + jsonSchemaFixture = JsonRootSchema202012Fixtures.withId; + }); + + describe('when called', () => { + let uriFixture: string; + + let result: unknown; + + beforeAll(() => { + uriFixture = 'uri:fixture'; + + (getBaseUri as jest.Mock).mockReturnValueOnce( + uriFixture, + ); + + result = getJsonSchemaBaseUri(jsonSchemaFixture); + }); + + afterAll(() => { + jest.clearAllMocks(); + }); + + it('should call getBaseUri()', () => { + const expected: GetBaseUriOptions = { + documentBaseUri: jsonSchemaFixture.$id, + }; + + expect(getBaseUri).toHaveBeenCalledTimes(1); + expect(getBaseUri).toHaveBeenCalledWith(expected); + }); + + it('should return an Uri()', () => { + expect(result).toBe(uriFixture); + }); + }); + }); + + describe('having a JsonSchema with no id', () => { + let jsonSchemaFixture: JsonSchemaObject; + + beforeAll(() => { + jsonSchemaFixture = JsonRootSchema202012Fixtures.withNoId; + }); + + describe('when called', () => { + let uriFixture: string; + + let result: unknown; + + beforeAll(() => { + uriFixture = 'uri:fixture'; + + (getBaseUri as jest.Mock).mockReturnValueOnce( + uriFixture, + ); + + result = getJsonSchemaBaseUri(jsonSchemaFixture); + }); + + afterAll(() => { + jest.clearAllMocks(); + }); + + it('should call getBaseUri()', () => { + const expected: GetBaseUriOptions = { + documentBaseUri: undefined, + }; + + expect(getBaseUri).toHaveBeenCalledTimes(1); + expect(getBaseUri).toHaveBeenCalledWith(expected); + }); + + it('should return an Uri()', () => { + expect(result).toBe(uriFixture); + }); + }); + }); +}); diff --git a/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.ts b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.ts new file mode 100644 index 0000000..19afdf5 --- /dev/null +++ b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.ts @@ -0,0 +1,20 @@ +import { JsonSchema } from '@cuaklabs/json-schema-types/2020-12'; +import { getBaseUri } from '@cuaklabs/uri'; + +export interface GetJsonSchemaBaseUriOptions { + encapsulatingDocumentBaseUri?: string | undefined; + retrievalUri?: string | undefined; +} + +export function getJsonSchemaBaseUri( + schema: JsonSchema, + options?: GetJsonSchemaBaseUriOptions, +): string { + const documentBaseUri: string | undefined = + typeof schema === 'boolean' ? undefined : schema.$id; + + return getBaseUri({ + ...(options ?? {}), + documentBaseUri, + }); +} From d00d34b1cf518217cb4cc554fc46e0a74a0c730a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Pintos=20L=C3=B3pez?= Date: Thu, 7 Sep 2023 00:00:59 +0200 Subject: [PATCH 2/2] test(json-schema-parser): add JsonRootSchemaFixtures --- .../calculations/getJsonSchemaBaseUri.spec.ts | 6 +- .../202012/fixtures/JsonRootSchemaFixtures.ts | 244 ++++++++++++++++++ 2 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 packages/parser/json-schema-parser/src/jsonSchema/202012/fixtures/JsonRootSchemaFixtures.ts diff --git a/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.spec.ts b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.spec.ts index 79e5746..878b504 100644 --- a/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.spec.ts +++ b/packages/parser/json-schema-parser/src/jsonSchema/202012/calculations/getJsonSchemaBaseUri.spec.ts @@ -5,7 +5,7 @@ jest.mock('@cuaklabs/uri'); import { JsonSchemaObject } from '@cuaklabs/json-schema-types/2020-12'; import { getBaseUri, GetBaseUriOptions } from '@cuaklabs/uri'; -import { JsonRootSchema202012Fixtures } from '../fixtures/JsonRootSchema202012Fixtures'; +import { JsonRootSchemaFixtures } from '../fixtures/JsonRootSchemaFixtures'; import { getJsonSchemaBaseUri } from './getJsonSchemaBaseUri'; describe(getJsonSchemaBaseUri.name, () => { @@ -13,7 +13,7 @@ describe(getJsonSchemaBaseUri.name, () => { let jsonSchemaFixture: JsonSchemaObject; beforeAll(() => { - jsonSchemaFixture = JsonRootSchema202012Fixtures.withId; + jsonSchemaFixture = JsonRootSchemaFixtures.withId; }); describe('when called', () => { @@ -54,7 +54,7 @@ describe(getJsonSchemaBaseUri.name, () => { let jsonSchemaFixture: JsonSchemaObject; beforeAll(() => { - jsonSchemaFixture = JsonRootSchema202012Fixtures.withNoId; + jsonSchemaFixture = JsonRootSchemaFixtures.withNoId; }); describe('when called', () => { diff --git a/packages/parser/json-schema-parser/src/jsonSchema/202012/fixtures/JsonRootSchemaFixtures.ts b/packages/parser/json-schema-parser/src/jsonSchema/202012/fixtures/JsonRootSchemaFixtures.ts new file mode 100644 index 0000000..8be3bff --- /dev/null +++ b/packages/parser/json-schema-parser/src/jsonSchema/202012/fixtures/JsonRootSchemaFixtures.ts @@ -0,0 +1,244 @@ +import { + JsonRootSchemaObject, + jsonSchemaTypes, +} from '@cuaklabs/json-schema-types/2020-12'; + +export class JsonRootSchemaFixtures { + public static get any(): JsonRootSchemaObject { + return { + $schema: 'https://json-schema.org/draft/2020-12/schema', + }; + } + + public static get withId(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + $id: 'https://schema.id', + }; + } + + public static get withNoId(): JsonRootSchemaObject { + const fixture: JsonRootSchemaObject = JsonRootSchemaFixtures.any; + + delete fixture.$id; + + return fixture; + } + + public static get with$DefsOne(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + $defs: { + enabledToggle: { + default: null, + description: `Whether the feature is enabled (true), +disabled (false), or under +automatic control (null)`, + title: 'Enabled', + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withAdditionalProperties(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + additionalProperties: { $ref: 'other.json' }, + }; + } + + public static get withAllOfTwo(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + allOf: [{ maximum: 30 }, { minimum: 20 }], + }; + } + + public static get withAnyOfTwo(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + anyOf: [{ maximum: 30 }, { minimum: 20 }], + }; + } + + public static get withContains(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + contains: { + enabledToggle: { + default: null, + description: `Whether the feature is enabled (true), +disabled (false), or under +automatic control (null)`, + title: 'Enabled', + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withDependentSchemasOne(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + dependentSchemas: { + enabledToggle: { + default: null, + description: `Whether the feature is enabled (true), +disabled (false), or under +automatic control (null)`, + title: 'Enabled', + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withElse(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + else: { + enabledToggle: { + default: null, + description: `Whether the feature is enabled (true), +disabled (false), or under +automatic control (null)`, + title: 'Enabled', + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withIf(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + if: { + enabledToggle: { + default: null, + description: `Whether the feature is enabled (true), +disabled (false), or under +automatic control (null)`, + title: 'Enabled', + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withItems(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + items: { + enabledToggle: { + default: null, + description: `Whether the feature is enabled (true), +disabled (false), or under +automatic control (null)`, + title: 'Enabled', + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withNot(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + not: { + enabledToggle: { + default: null, + description: `Whether the feature is enabled (true), +disabled (false), or under +automatic control (null)`, + title: 'Enabled', + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withOneOfTwo(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + oneOf: [{ maximum: 20 }, { minimum: 30 }], + }; + } + + public static get withPatternProperiesOne(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + patternProperties: { + '^[a-z0-9]+$': { + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withPrefixItemsOne(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + prefixItems: [ + { + enabledToggle: { + default: null, + description: `Whether the feature is enabled (true), +disabled (false), or under +automatic control (null)`, + title: 'Enabled', + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + ], + }; + } + + public static get withProperiesOne(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + properties: { + z39: { + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withProperyNames(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + propertyNames: { maxLength: 3 }, + }; + } + + public static get withThen(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + then: { + enabledToggle: { + default: null, + description: `Whether the feature is enabled (true), +disabled (false), or under +automatic control (null)`, + title: 'Enabled', + type: [jsonSchemaTypes.boolean, jsonSchemaTypes.null], + }, + }, + }; + } + + public static get withUnevaluatedItems(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + unevaluatedItems: { maxLength: 3 }, + }; + } + + public static get withUnevaluatedProperties(): JsonRootSchemaObject { + return { + ...JsonRootSchemaFixtures.any, + unevaluatedProperties: { maxLength: 3 }, + }; + } +}