diff --git a/src/models/asyncapi.ts b/src/models/asyncapi.ts index 0c20dfcb5..76aca11eb 100644 --- a/src/models/asyncapi.ts +++ b/src/models/asyncapi.ts @@ -4,27 +4,22 @@ import { AsyncAPIDocumentV3 } from "./v3"; import type { InfoInterface } from "./info"; import type { BaseModel } from "./base"; import type { ExtensionsMixinInterface } from "./mixins"; -import { ServersInterface } from "./servers"; +import type { ServersInterface } from "./servers"; +import type { DetailedAsyncAPI } from "../types"; export interface AsyncAPIDocumentInterface extends BaseModel, ExtensionsMixinInterface { version(): string; info(): InfoInterface; - servers(): ServersInterface + servers(): ServersInterface; } -export function newAsyncAPIDocument(json: Record): AsyncAPIDocumentInterface { - const version = json['asyncapi']; // Maybe this should be an arg. - if (version == undefined || version == null || version == '') { - throw new Error('Missing AsyncAPI version in document'); - } - - const major = version.split(".")[0]; - switch (major) { - case '2': - return new AsyncAPIDocumentV2(json); - case '3': - return new AsyncAPIDocumentV3(json); +export function newAsyncAPIDocument(asyncapi: DetailedAsyncAPI): AsyncAPIDocumentInterface { + switch (asyncapi.semver.major) { + case 2: + return new AsyncAPIDocumentV2(asyncapi.parsed, { parent: null, asyncapi, pointer: '/' }); + case 3: + return new AsyncAPIDocumentV3(asyncapi.parsed, { parent: null, asyncapi, pointer: '/' }); default: - throw new Error(`Unsupported version: ${version}`); + throw new Error(`Unsupported AsyncAPI version: ${asyncapi.semver.version}`); } } diff --git a/src/models/base.ts b/src/models/base.ts index 7e09c8007..7e7bb8b7a 100644 --- a/src/models/base.ts +++ b/src/models/base.ts @@ -1,6 +1,16 @@ -export class BaseModel { +import type { Constructor } from "./utils"; +import type { DetailedAsyncAPI } from "../types"; + +export interface ModelMetadata

{ + asyncapi: DetailedAsyncAPI; + pointer: string; + parent: P | null; +} + +export abstract class BaseModel { constructor( protected readonly _json: Record, + protected readonly _meta: ModelMetadata = {} as any, ) {} json>(): T; @@ -10,4 +20,23 @@ export class BaseModel { if (!this._json) return; return this._json[String(key)]; } + + meta(): ModelMetadata { + return this._meta!; + } + + jsonPath(field?: string): string | undefined { + if (typeof field !== 'string') { + return this._meta?.pointer; + } + return `${this._meta?.pointer}/${field}`; + } + + protected createModel(Model: Constructor, value: any, { id, parent, pointer }: { id?: string, parent?: any, pointer: string | number }): T { + const meta = { asyncapi: this._meta.asyncapi, parent: parent || this, pointer } as ModelMetadata; + if (id) { + return new Model(id, value, meta); + } + return new Model(value, meta); + } } diff --git a/src/models/server.ts b/src/models/server.ts index d9526fd3d..70576066b 100644 --- a/src/models/server.ts +++ b/src/models/server.ts @@ -1,10 +1,10 @@ -import { BaseModel } from "./base"; -import { BindingsMixinInterface, DescriptionMixinInterface } from './mixins'; +import type { BaseModel } from "./base"; +import type { BindingsMixinInterface, DescriptionMixinInterface, ExtensionsMixinInterface } from './mixins'; -export interface ServerInterface extends BaseModel, DescriptionMixinInterface, BindingsMixinInterface { - id(): string - protocol(): string | undefined; - protocolVersion(): string; - hasProtocolVersion(): boolean; - url(): string; +export interface ServerInterface extends BaseModel, DescriptionMixinInterface, BindingsMixinInterface, ExtensionsMixinInterface { + id(): string + url(): string; + protocol(): string | undefined; + protocolVersion(): string; + hasProtocolVersion(): boolean; } \ No newline at end of file diff --git a/src/models/utils.ts b/src/models/utils.ts index e2befd7a8..c97451818 100644 --- a/src/models/utils.ts +++ b/src/models/utils.ts @@ -1,6 +1,6 @@ import type { BaseModel } from './base'; -export interface Constructor extends Function { +export interface Constructor extends Function { new (...any: any[]): T; } diff --git a/src/models/v2/asyncapi.ts b/src/models/v2/asyncapi.ts index a220e9fa9..65d35296b 100644 --- a/src/models/v2/asyncapi.ts +++ b/src/models/v2/asyncapi.ts @@ -1,13 +1,13 @@ import { BaseModel } from "../base"; import { Info } from "./info"; +import { Servers } from "./servers"; +import { Server } from "./server"; import { Mixin } from '../utils'; import { ExtensionsMixin } from './mixins/extensions'; -import { AsyncAPIDocumentInterface, InfoInterface } from "../../models"; -import { ServersInterface } from "models/servers"; -import { Servers } from "./servers"; -import { Server } from "./server"; +import type { AsyncAPIDocumentInterface, InfoInterface } from "../../models"; +import type { ServersInterface } from "models/servers"; export class AsyncAPIDocument extends Mixin(BaseModel, ExtensionsMixin) @@ -18,12 +18,14 @@ export class AsyncAPIDocument } info(): InfoInterface { - return new Info(this._json.info); + return this.createModel(Info, this._json.info, { pointer: '/info' }); } servers(): ServersInterface { return new Servers( - Object.entries(this._json.servers).map(([serverName, server]) => new Server(serverName, server as Record)) + Object.entries(this._json.servers).map(([serverName, server]) => + this.createModel(Server, server, { id: serverName, pointer: `/servers/${serverName}` }) + ) ); } } diff --git a/src/models/v2/info.ts b/src/models/v2/info.ts index 9c12dd292..5d53573fc 100644 --- a/src/models/v2/info.ts +++ b/src/models/v2/info.ts @@ -5,13 +5,15 @@ import { License } from "./license"; import { Mixin } from '../utils'; import { DescriptionMixin } from './mixins/description'; import { ExtensionsMixin } from './mixins/extensions'; -import { ExternalDocumentationMixin } from './mixins/external-docs'; -import { TagsMixin } from './mixins/tags'; +import { ExternalDocumentation } from './mixins/external-docs'; +import { Tags, Tag } from './mixins/tags'; import type { InfoInterface } from "../../models/info"; +import type { ExternalDocumentationInterface } from "../../models/external-docs"; +import type { TagsInterface } from "../../models/tags"; export class Info - extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin, ExternalDocumentationMixin, TagsMixin) + extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements InfoInterface { title(): string { @@ -22,14 +24,12 @@ export class Info return this._json.version; } - // TODO: Implement it id(): string | undefined { - return; + return this._meta.asyncapi.parsed.id as string; } - // TODO: Implement it hasId(): boolean { - return true; + return !!this._meta.asyncapi.parsed.id; } hasTermsOfService(): boolean { @@ -46,7 +46,7 @@ export class Info contact(): Contact | undefined { const contact = this._json.contact; - return contact && new Contact(contact); + return contact && this.createModel(Contact, contact, { pointer: '/info/contact' }); } hasLicense(): boolean { @@ -55,6 +55,22 @@ export class Info license(): License | undefined { const license = this._json.license; - return license && new License(license); + return license && this.createModel(License, license, { pointer: `/info/license` }); + } + + hasExternalDocs(): boolean { + return Object.keys(this._meta.asyncapi.parsed.externalDocs || {}).length > 0; + }; + + externalDocs(): ExternalDocumentationInterface | undefined { + if (this.hasExternalDocs()) { + return this.createModel(ExternalDocumentation, this._meta.asyncapi.parsed.externalDocs, { pointer: `/externalDocs` }); + } + return; + }; + + tags(): TagsInterface { + const tags = this._meta.asyncapi.parsed.tags || []; + return new Tags(tags.map((tag: any, idx: number) => this.createModel(Tag, tag, { pointer: `/tags/${idx}` }))); } -} \ No newline at end of file +} diff --git a/src/models/v2/license.ts b/src/models/v2/license.ts index 834f43b29..69cb09e35 100644 --- a/src/models/v2/license.ts +++ b/src/models/v2/license.ts @@ -17,4 +17,4 @@ export class License extends Mixin(BaseModel, ExtensionsMixin) implements Licens url(): string | undefined { return this._json.url; } -} \ No newline at end of file +} diff --git a/src/models/v2/mixins/bindings.ts b/src/models/v2/mixins/bindings.ts index 13dd7a228..b1dfe9b2e 100644 --- a/src/models/v2/mixins/bindings.ts +++ b/src/models/v2/mixins/bindings.ts @@ -4,6 +4,7 @@ import { Collection } from '../../collection'; import { Mixin } from '../../utils'; import { ExtensionsMixin } from './extensions'; +import type { ModelMetadata } from "../../base"; import type { BindingsMixinInterface } from "../../mixins"; import type { BindingsInterface } from "../../bindings"; import type { BindingInterface } from "../../binding"; @@ -12,8 +13,9 @@ export class Binding extends Mixin(BaseModel, ExtensionsMixin) implements Bindin constructor( private readonly _protocol: string, _json: Record, + _meta: ModelMetadata = {} as any, ) { - super(_json); + super(_json, _meta); } protocol(): string { @@ -45,7 +47,9 @@ export abstract class BindingsMixin extends BaseModel implements BindingsMixinIn bindings(): BindingsInterface { const bindings: Record = this._json.bindings || {}; return new Bindings( - Object.entries(bindings).map(([protocol, binding]) => new Binding(protocol, binding)) + Object.entries(bindings).map(([protocol, binding]) => + this.createModel(Binding, binding, { id: protocol, pointer: `${this._meta.pointer}/bindings/${protocol}` }) + ) ); } } diff --git a/src/models/v2/mixins/extensions.ts b/src/models/v2/mixins/extensions.ts index 61ee70409..b95175fa5 100644 --- a/src/models/v2/mixins/extensions.ts +++ b/src/models/v2/mixins/extensions.ts @@ -1,6 +1,7 @@ import { Collection } from '../../collection'; import { BaseModel } from "../../base"; +import type { ModelMetadata } from "../../base"; import type { ExtensionsMixinInterface } from "../../mixins"; import type { ExtensionsInterface } from "../../extensions"; import type { ExtensionInterface } from "../../extension"; @@ -11,8 +12,9 @@ export class Extension extends BaseModel implements ExtensionInterface { constructor( private readonly _id: string, _json: Record, + _meta: ModelMetadata = {} as any, ) { - super(_json); + super(_json, _meta); } id(): string { @@ -43,7 +45,9 @@ export abstract class ExtensionsMixin extends BaseModel implements ExtensionsMix const extensions: Extension[] = []; Object.entries(this._json).forEach(([key, value]) => { if (EXTENSION_REGEX.test(key)) { - extensions.push(new Extension(key, value)); + extensions.push( + this.createModel(Extension, value, { id: key, pointer: `${this._meta.pointer}/${key}` }) + ); } }); return new Extensions(extensions); diff --git a/src/models/v2/mixins/tags.ts b/src/models/v2/mixins/tags.ts index 6cdee98b9..0134183e5 100644 --- a/src/models/v2/mixins/tags.ts +++ b/src/models/v2/mixins/tags.ts @@ -32,6 +32,10 @@ export class Tags extends Collection implements TagsInterface { export abstract class TagsMixin extends BaseModel implements TagsMixinInterface { tags(): TagsInterface { const tags = this._json.tags || []; - return new Tags(tags.map((tag: any) => new Tag(tag))); + return new Tags( + tags.map((tag: any, idx: number) => + this.createModel(Tag, tag, { pointer: `${this._meta.pointer}/tags/${idx}` }) + ) + ); } } \ No newline at end of file diff --git a/src/models/v2/server.ts b/src/models/v2/server.ts index 3f52dc724..672af9696 100644 --- a/src/models/v2/server.ts +++ b/src/models/v2/server.ts @@ -1,34 +1,39 @@ -import { Mixin } from '../utils'; import { BaseModel } from '../base'; -import { ServerInterface } from '../server'; -import { DescriptionMixin } from './mixins/description'; + +import { Mixin } from '../utils'; import { BindingsMixin } from './mixins/bindings'; +import { DescriptionMixin } from './mixins/description'; +import { ExtensionsMixin } from './mixins/extensions'; + +import type { ModelMetadata } from "../base"; +import type { ServerInterface } from '../server'; + +export class Server extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, ExtensionsMixin) implements ServerInterface { + constructor( + private readonly _id: string, + _json: Record, + _meta: ModelMetadata = {} as any, + ) { + super(_json, _meta); + } + + id(): string { + return this._id; + } + + url(): string { + return this._json.url; + } + + protocol(): string | undefined { + return this._json.protocol; + } + + hasProtocolVersion(): boolean { + return !!this._json.protocolVersion; + } -export class Server extends Mixin(BaseModel, DescriptionMixin, BindingsMixin) implements ServerInterface { - constructor( - private readonly _id: string, - _json: Record - ){ - super(_json); - } - - id(): string { - return this._id; - } - - protocol(): string | undefined { - return this.json('protocol'); - } - - hasProtocolVersion(): boolean { - return !!this.json('protocolVersion'); - } - - protocolVersion(): string { - return this.json('protocolVersion'); - } - - url(): string { - return this.json('url'); - } + protocolVersion(): string { + return this._json.protocolVersion; + } } \ No newline at end of file diff --git a/src/models/v2/servers.ts b/src/models/v2/servers.ts index c8e9fa0dc..68da626c9 100644 --- a/src/models/v2/servers.ts +++ b/src/models/v2/servers.ts @@ -3,11 +3,11 @@ import { ServerInterface } from '../server'; import { ServersInterface } from '../servers'; export class Servers extends Collection implements ServersInterface { - override get(id: string): ServerInterface | undefined { - return this.collections.find(server => server.id() === id); - } + override get(id: string): ServerInterface | undefined { + return this.collections.find(server => server.id() === id); + } - override has(id: string): boolean { - return this.collections.some(server => server.id() === id); - } -} \ No newline at end of file + override has(id: string): boolean { + return this.collections.some(server => server.id() === id); + } +} diff --git a/src/models/v3/asyncapi.ts b/src/models/v3/asyncapi.ts index 5da958d7c..65d35296b 100644 --- a/src/models/v3/asyncapi.ts +++ b/src/models/v3/asyncapi.ts @@ -1,30 +1,31 @@ -import { AsyncAPIDocumentInterface } from "../../models/asyncapi"; import { BaseModel } from "../base"; import { Info } from "./info"; +import { Servers } from "./servers"; +import { Server } from "./server"; import { Mixin } from '../utils'; import { ExtensionsMixin } from './mixins/extensions'; -import { ServersInterface } from "models/servers"; -import { Servers } from "./servers"; -import { Server } from "./server"; -export class AsyncAPIDocument - extends Mixin(BaseModel, ExtensionsMixin) +import type { AsyncAPIDocumentInterface, InfoInterface } from "../../models"; +import type { ServersInterface } from "models/servers"; + +export class AsyncAPIDocument + extends Mixin(BaseModel, ExtensionsMixin) implements AsyncAPIDocumentInterface { version(): string { - return this.json("asyncapi"); + return this._json.asyncapi; } - info(): Info { - return new Info(this.json("info")); + info(): InfoInterface { + return this.createModel(Info, this._json.info, { pointer: '/info' }); } servers(): ServersInterface { return new Servers( - Object.entries(this._json.servers).map( - ([serverName, server]) => new Server(serverName, server as Record) + Object.entries(this._json.servers).map(([serverName, server]) => + this.createModel(Server, server, { id: serverName, pointer: `/servers/${serverName}` }) ) - ) + ); } } diff --git a/src/models/v3/info.ts b/src/models/v3/info.ts index 9c12dd292..6e5cfc62e 100644 --- a/src/models/v3/info.ts +++ b/src/models/v3/info.ts @@ -5,13 +5,15 @@ import { License } from "./license"; import { Mixin } from '../utils'; import { DescriptionMixin } from './mixins/description'; import { ExtensionsMixin } from './mixins/extensions'; -import { ExternalDocumentationMixin } from './mixins/external-docs'; -import { TagsMixin } from './mixins/tags'; +import { ExternalDocumentation } from './mixins/external-docs'; +import { Tags, Tag } from './mixins/tags'; import type { InfoInterface } from "../../models/info"; +import type { ExternalDocumentationInterface } from "../../models/external-docs"; +import type { TagsInterface } from "../../models/tags"; export class Info - extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin, ExternalDocumentationMixin, TagsMixin) + extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements InfoInterface { title(): string { @@ -22,14 +24,12 @@ export class Info return this._json.version; } - // TODO: Implement it id(): string | undefined { - return; + return this._meta.asyncapi.parsed.id as string; } - // TODO: Implement it hasId(): boolean { - return true; + return !!this._meta.asyncapi.parsed.id; } hasTermsOfService(): boolean { @@ -46,7 +46,7 @@ export class Info contact(): Contact | undefined { const contact = this._json.contact; - return contact && new Contact(contact); + return contact && this.createModel(Contact, contact, { pointer: '/info/contact' }); } hasLicense(): boolean { @@ -55,6 +55,22 @@ export class Info license(): License | undefined { const license = this._json.license; - return license && new License(license); + return license && this.createModel(License, license, { pointer: `/info/license` }); + } + + hasExternalDocs(): boolean { + return Object.keys(this._meta.asyncapi.parsed.externalDocs || {}).length > 0; + }; + + externalDocs(): ExternalDocumentationInterface | undefined { + if (this.hasExternalDocs()) { + return this.createModel(ExternalDocumentation, this._meta.asyncapi.parsed.externalDocs, { pointer: `/externalDocs` }); + } + return; + }; + + tags(): TagsInterface { + const tags = this._json.tags || []; + return new Tags(tags.map((tag: any, idx: number) => this.createModel(Tag, tag, { pointer: `/tags/${idx}` }))); } -} \ No newline at end of file +} diff --git a/src/models/v3/mixins/bindings.ts b/src/models/v3/mixins/bindings.ts index dc6770263..ae646e166 100644 --- a/src/models/v3/mixins/bindings.ts +++ b/src/models/v3/mixins/bindings.ts @@ -4,6 +4,7 @@ import { Collection } from '../../collection'; import { Mixin } from '../../utils'; import { ExtensionsMixin } from './extensions'; +import type { ModelMetadata } from "../../base"; import type { BindingsMixinInterface } from "../../mixins"; import type { BindingsInterface } from "../../bindings"; import type { BindingInterface } from "../../binding"; @@ -12,8 +13,9 @@ export class Binding extends Mixin(BaseModel, ExtensionsMixin) implements Bindin constructor( private readonly _protocol: string, _json: Record, + _meta: ModelMetadata, ) { - super(_json); + super(_json, _meta); } protocol(): string { @@ -45,7 +47,9 @@ export abstract class BindingsMixin extends BaseModel implements BindingsMixinIn bindings(): BindingsInterface { const bindings: Record = this._json.bindings || {}; return new Bindings( - Object.entries(bindings).map(([protocol, binding]) => new Binding(protocol, binding)) + Object.entries(bindings).map(([protocol, binding]) => + this.createModel(Binding, binding, { id: protocol, pointer: `${this._meta.pointer}/bindings/${protocol}` }) + ) ); } -} \ No newline at end of file +} diff --git a/src/models/v3/mixins/extensions.ts b/src/models/v3/mixins/extensions.ts index 61ee70409..9e5cb45dc 100644 --- a/src/models/v3/mixins/extensions.ts +++ b/src/models/v3/mixins/extensions.ts @@ -1,6 +1,7 @@ import { Collection } from '../../collection'; import { BaseModel } from "../../base"; +import type { ModelMetadata } from "../../base"; import type { ExtensionsMixinInterface } from "../../mixins"; import type { ExtensionsInterface } from "../../extensions"; import type { ExtensionInterface } from "../../extension"; @@ -11,8 +12,9 @@ export class Extension extends BaseModel implements ExtensionInterface { constructor( private readonly _id: string, _json: Record, + _meta: ModelMetadata, ) { - super(_json); + super(_json, _meta); } id(): string { @@ -43,9 +45,11 @@ export abstract class ExtensionsMixin extends BaseModel implements ExtensionsMix const extensions: Extension[] = []; Object.entries(this._json).forEach(([key, value]) => { if (EXTENSION_REGEX.test(key)) { - extensions.push(new Extension(key, value)); + extensions.push( + this.createModel(Extension, value, { id: key, pointer: `${this._meta.pointer}/${key}` }) + ); } }); return new Extensions(extensions); }; -} \ No newline at end of file +} diff --git a/src/models/v3/mixins/tags.ts b/src/models/v3/mixins/tags.ts index 6cdee98b9..e490069e9 100644 --- a/src/models/v3/mixins/tags.ts +++ b/src/models/v3/mixins/tags.ts @@ -32,6 +32,6 @@ export class Tags extends Collection implements TagsInterface { export abstract class TagsMixin extends BaseModel implements TagsMixinInterface { tags(): TagsInterface { const tags = this._json.tags || []; - return new Tags(tags.map((tag: any) => new Tag(tag))); + return new Tags(tags.map((tag: any, idx: number) => this.createModel(Tag, tag, { pointer: `${this._meta.pointer}/tags/${idx}` }))); } -} \ No newline at end of file +} diff --git a/src/models/v3/server.ts b/src/models/v3/server.ts index 3f52dc724..672af9696 100644 --- a/src/models/v3/server.ts +++ b/src/models/v3/server.ts @@ -1,34 +1,39 @@ -import { Mixin } from '../utils'; import { BaseModel } from '../base'; -import { ServerInterface } from '../server'; -import { DescriptionMixin } from './mixins/description'; + +import { Mixin } from '../utils'; import { BindingsMixin } from './mixins/bindings'; +import { DescriptionMixin } from './mixins/description'; +import { ExtensionsMixin } from './mixins/extensions'; + +import type { ModelMetadata } from "../base"; +import type { ServerInterface } from '../server'; + +export class Server extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, ExtensionsMixin) implements ServerInterface { + constructor( + private readonly _id: string, + _json: Record, + _meta: ModelMetadata = {} as any, + ) { + super(_json, _meta); + } + + id(): string { + return this._id; + } + + url(): string { + return this._json.url; + } + + protocol(): string | undefined { + return this._json.protocol; + } + + hasProtocolVersion(): boolean { + return !!this._json.protocolVersion; + } -export class Server extends Mixin(BaseModel, DescriptionMixin, BindingsMixin) implements ServerInterface { - constructor( - private readonly _id: string, - _json: Record - ){ - super(_json); - } - - id(): string { - return this._id; - } - - protocol(): string | undefined { - return this.json('protocol'); - } - - hasProtocolVersion(): boolean { - return !!this.json('protocolVersion'); - } - - protocolVersion(): string { - return this.json('protocolVersion'); - } - - url(): string { - return this.json('url'); - } + protocolVersion(): string { + return this._json.protocolVersion; + } } \ No newline at end of file diff --git a/src/models/v3/servers.ts b/src/models/v3/servers.ts index c8e9fa0dc..68da626c9 100644 --- a/src/models/v3/servers.ts +++ b/src/models/v3/servers.ts @@ -3,11 +3,11 @@ import { ServerInterface } from '../server'; import { ServersInterface } from '../servers'; export class Servers extends Collection implements ServersInterface { - override get(id: string): ServerInterface | undefined { - return this.collections.find(server => server.id() === id); - } + override get(id: string): ServerInterface | undefined { + return this.collections.find(server => server.id() === id); + } - override has(id: string): boolean { - return this.collections.some(server => server.id() === id); - } -} \ No newline at end of file + override has(id: string): boolean { + return this.collections.some(server => server.id() === id); + } +} diff --git a/src/parse.ts b/src/parse.ts index c5ce643cc..2564f64af 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -47,7 +47,7 @@ export async function parse(asyncapi: ParserInput, options?: ParseOptions): Prom const detailed = createDetailedAsyncAPI(asyncapi as string | Record, parsed); await customOperations(detailed, options); - const parsedDoc = newAsyncAPIDocument(parsed); + const parsedDoc = newAsyncAPIDocument(detailed); return { source: asyncapi, diff --git a/src/stringify.ts b/src/stringify.ts index b49e4ed61..32240adee 100644 --- a/src/stringify.ts +++ b/src/stringify.ts @@ -1,6 +1,6 @@ import { AsyncAPIDocumentInterface, newAsyncAPIDocument } from './models'; -import { isAsyncAPIDocument, isParsedDocument, isStringifiedDocument } from './utils'; +import { createDetailedAsyncAPI, isAsyncAPIDocument, isParsedDocument, isStringifiedDocument } from './utils'; import { xParserSpecStringified } from './constants'; export interface StringifyOptions { @@ -26,25 +26,26 @@ export function stringify(document: unknown, options: StringifyOptions = {}): st } export function unstringify(document: unknown): AsyncAPIDocumentInterface | undefined { + let parsed: unknown = document; if (typeof document === 'string') { try { - document = JSON.parse(document); + parsed = JSON.parse(document); } catch(_) { return; } } - if (!isStringifiedDocument(document)) { + if (!isStringifiedDocument(parsed)) { return; } // shall copy of whole JSON - document = { ...document }; + parsed = { ...parsed }; // remove `x-parser-spec-stringified` extension - delete (>document)[String(xParserSpecStringified)]; + delete (>parsed)[String(xParserSpecStringified)]; traverseStringifiedDoc(document, undefined, document, new Map(), new Map()); - return newAsyncAPIDocument(>document); + return newAsyncAPIDocument(createDetailedAsyncAPI(document as string, parsed as Record)); } function refReplacer() { diff --git a/src/types.ts b/src/types.ts index 7294aab80..13e882b8a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,8 +11,8 @@ export interface AsyncAPISemver { } export interface DetailedAsyncAPI { - source: string | Record; - parsed: Record; + source: string | Record; + parsed: Record; semver: AsyncAPISemver; } @@ -26,3 +26,7 @@ export interface ParserOutput { parsed: AsyncAPIDocumentInterface | undefined; diagnostics: Diagnostic[]; } + +export interface Constructor { + new (...args: any[]): T +} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index 6c48e1048..da88db8ad 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -17,7 +17,7 @@ export function toAsyncAPIDocument(maybeDoc: unknown): AsyncAPIDocumentInterface if (!isParsedDocument(maybeDoc)) { return; } - return unstringify(maybeDoc) || newAsyncAPIDocument(maybeDoc); + return unstringify(maybeDoc) || newAsyncAPIDocument(createDetailedAsyncAPI(maybeDoc, maybeDoc)); } export function isAsyncAPIDocument(maybeDoc: unknown): maybeDoc is AsyncAPIDocumentInterface { diff --git a/test/models/base.spec.ts b/test/models/base.spec.ts index b26931a29..eb101e38f 100644 --- a/test/models/base.spec.ts +++ b/test/models/base.spec.ts @@ -1,22 +1,24 @@ import { BaseModel } from '../../src/models/base'; describe('Base model', function() { + class Model extends BaseModel {} + describe('.json()', function() { it('should return the whole JSON object', function() { const doc = { test: 'testing' }; - const d = new BaseModel(doc); + const d = new Model(doc); expect(d.json()).toEqual(doc); }); it('should return the value of a given key', function() { const doc = { test: 'testing' }; - const d = new BaseModel(doc); + const d = new Model(doc); expect(d.json('test')).toEqual(doc.test); }); it('should return the value of a given key, even when this is falsy', function() { const doc = { 0: 'testing' }; - const d = new BaseModel(doc); + const d = new Model(doc); expect(d.json(0)).toEqual(doc[0]); }); }); diff --git a/test/models/v2/asyncapi.spec.ts b/test/models/v2/asyncapi.spec.ts index 60ee2499c..fab5cd43f 100644 --- a/test/models/v2/asyncapi.spec.ts +++ b/test/models/v2/asyncapi.spec.ts @@ -1,4 +1,11 @@ -import { newAsyncAPIDocument, AsyncAPIDocumentV2, InfoV2, AsyncAPIDocumentV3, ServersV2 } from '../../../src/models'; +import { + newAsyncAPIDocument, + AsyncAPIDocumentV2, + InfoV2, + ServersV2, + AsyncAPIDocumentV3 +} from '../../../src/models'; +import { createDetailedAsyncAPI } from '../../../src/utils'; import { assertExtensionsMixinInheritance, @@ -23,19 +30,15 @@ describe('AsyncAPIDocument model', function() { it('should return an Info object', function() { const doc = { info: { name: "LeChuck" } }; const d = new AsyncAPIDocumentV2(doc); - expect(d.info() instanceof InfoV2).toBeTruthy(); + expect(d.info()).toBeInstanceOf(InfoV2); }); }); describe('.servers()', function(){ it('should return an servers object', function(){ - const doc = {servers: { - development: { - - } - }}; + const doc = { servers: { development: {} } }; const d = new AsyncAPIDocumentV2(doc); - expect(d.servers() instanceof ServersV2).toBeTruthy(); + expect(d.servers()).toBeInstanceOf(ServersV2); }) }) @@ -47,20 +50,23 @@ describe('AsyncAPIDocument model', function() { describe('AsyncAPIDocument factory', function() { it('should create a valid document from v2.0.0', function() { const doc = { asyncapi: "2.0.0" }; - const d = newAsyncAPIDocument(doc) + const detailed = createDetailedAsyncAPI(doc, doc); + const d = newAsyncAPIDocument(detailed) expect(d.version()).toEqual(doc.asyncapi); expect(d).toBeInstanceOf(AsyncAPIDocumentV2); }); it('should create a valid document from v3.0.0', function() { const doc = { asyncapi: "3.0.0" }; - const d = newAsyncAPIDocument(doc) + const detailed = createDetailedAsyncAPI(doc, doc); + const d = newAsyncAPIDocument(detailed) expect(d.version()).toEqual(doc.asyncapi); expect(d).toBeInstanceOf(AsyncAPIDocumentV3); }); it('should fail trying to create a document from a non supported spec version', function() { const doc = { asyncapi: "99.99.99" }; - expect(() => newAsyncAPIDocument(doc)).toThrow("Unsupported version: 99.99.99"); + const detailed = createDetailedAsyncAPI(doc, doc); + expect(() => newAsyncAPIDocument(detailed)).toThrow("Unsupported AsyncAPI version: 99.99.99"); }); }); diff --git a/test/models/v2/info.spec.ts b/test/models/v2/info.spec.ts index 6d9e97d55..708917cf6 100644 --- a/test/models/v2/info.spec.ts +++ b/test/models/v2/info.spec.ts @@ -1,12 +1,13 @@ import { Info } from '../../../src/models/v2/info'; import { Contact } from '../../../src/models/v2/contact'; import { License } from '../../../src/models/v2/license'; +import { ExternalDocumentation } from '../../../src/models/v2/mixins/external-docs'; +import { Tags, Tag } from '../../../src/models/v2/mixins/tags'; +import { createDetailedAsyncAPI } from '../../../src/utils'; import { assertDescriptionMixinInheritance, assertExtensionsMixinInheritance, - assertExternalDocumentationMixinInheritance, - assertTagsMixinInheritance } from './mixins/inheritance'; describe('Info model', function() { @@ -26,6 +27,38 @@ describe('Info model', function() { }); }); + describe('.hasId()', function() { + it('should return true when there is a value', function() { + const doc = { asyncapi: '2.0.0', id: 'someId' }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.hasId()).toEqual(true); + }); + + it('should return false when there is no value', function() { + const doc = { asyncapi: '2.0.0' }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.hasId()).toEqual(false); + }); + }); + + describe('.id()', function() { + it('should return the value', function() { + const doc = { asyncapi: '2.0.0', id: 'someId' }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.id()).toEqual(doc.id); + }); + + it('should return undefined when there is no value', function() { + const doc = { asyncapi: '2.0.0' }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.id()).toEqual(undefined); + }); + }); + describe('.hasTermsOfService()', function() { it('should return true when there is a value', function() { const doc = { termsOfService: "These are the terms of service" }; @@ -61,7 +94,7 @@ describe('Info model', function() { expect(d.hasContact()).toEqual(true); }); - it('should return undefined when there is no value', function() { + it('should return false when there is no value', function() { const doc = {}; const d = new Info(doc); expect(d.hasContact()).toEqual(false); @@ -89,7 +122,7 @@ describe('Info model', function() { expect(d.hasLicense()).toEqual(true); }); - it('should return undefined when there is no value', function() { + it('should return false when there is no value', function() { const doc = {}; const d = new Info(doc); expect(d.hasLicense()).toEqual(false); @@ -110,10 +143,76 @@ describe('Info model', function() { }); }); + describe('.hasExternalDocs()', function() { + it('should return true when there is a value', function() { + const doc = { asyncapi: '2.0.0', externalDocs: { url: 'https://example.com' } }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.hasExternalDocs()).toEqual(true); + }); + + it('should return false when there is an empty object', function() { + const doc = { asyncapi: '2.0.0', externalDocs: {} }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.hasExternalDocs()).toEqual(false); + }); + + it('should return false when there is no value', function() { + const doc = { asyncapi: '2.0.0' }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.hasExternalDocs()).toEqual(false); + }); + }); + + describe('.externalDocs()', function() { + it('should return the value', function() { + const doc = { asyncapi: '2.0.0', externalDocs: { url: 'https://example.com' } }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.externalDocs()).toBeInstanceOf(ExternalDocumentation); + expect(d.externalDocs()!.json()).toEqual(doc.externalDocs); + }); + + it('should return undefined when there is an empty object', function() { + const doc = { asyncapi: '2.0.0', externalDocs: {} }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.externalDocs()).toEqual(undefined); + }); + + it('should return undefined when there is no value', function() { + const doc = { asyncapi: '2.0.0' }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.externalDocs()).toEqual(undefined); + }); + }); + + describe('.tags()', function() { + it('should return the collection of tags', function() { + const tags = [{ name: 'one' }, { name: 'two' }]; + const doc = { asyncapi: '2.0.0', tags }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.tags()).toBeInstanceOf(Tags); + expect(d.tags().length).toEqual(2); + expect(d.tags().all()[0]).toBeInstanceOf(Tag); + expect(d.tags().all()[1]).toBeInstanceOf(Tag); + }); + + it('should return empty array when there is an empty collection', function() { + const doc = { asyncapi: '2.0.0' }; + const asyncapi = createDetailedAsyncAPI(doc, doc); + const d = new Info({}, { asyncapi, parent: null, pointer: '/info' }); + expect(d.tags()).toBeInstanceOf(Tags); + expect(d.tags().all()).toEqual([]); + }); + }); + describe('mixins inheritance', function() { assertDescriptionMixinInheritance(Info); assertExtensionsMixinInheritance(Info); - assertExternalDocumentationMixinInheritance(Info); - assertTagsMixinInheritance(Info); }); }); diff --git a/test/models/v2/mixins/external-docs.spec.ts b/test/models/v2/mixins/external-docs.spec.ts index 6cf9c995a..f9aac7bc9 100644 --- a/test/models/v2/mixins/external-docs.spec.ts +++ b/test/models/v2/mixins/external-docs.spec.ts @@ -21,7 +21,6 @@ describe('ExternalDocs mixin', function() { }); }); - // TODO: implement it when the ExternalDocs class will be implemented describe('.externalDocs()', function() { it('should return a externalDocs object', function() { expect(d1.externalDocs()).toBeInstanceOf(ExternalDocumentationV2); diff --git a/test/models/v2/mixins/inheritance.ts b/test/models/v2/mixins/inheritance.ts index d1b473e36..f0fa18333 100644 --- a/test/models/v2/mixins/inheritance.ts +++ b/test/models/v2/mixins/inheritance.ts @@ -4,7 +4,9 @@ import { ExtensionsMixin } from '../../../../src/models/v2/mixins/extensions'; import { ExternalDocumentationMixin } from '../../../../src/models/v2/mixins/external-docs'; import { TagsMixin } from '../../../../src/models/v2/mixins/tags'; -export function assertBindingsMixinInheritance(model: typeof BindingsMixin) { +import type { Constructor } from '../../../../src/models/utils'; + +export function assertBindingsMixinInheritance(model: Constructor) { describe('BindingsMixin inheritance', function() { it(`check if ${model.name} model has inherited methods from BindingsMixin`, function() { expect(model.prototype.bindings).not.toEqual(undefined); @@ -14,7 +16,7 @@ export function assertBindingsMixinInheritance(model: typeof BindingsMixin) { }); } -export function assertDescriptionMixinInheritance(model: typeof DescriptionMixin) { +export function assertDescriptionMixinInheritance(model: Constructor) { describe('DescriptionMixin inheritance', function() { it(`check if ${model.name} model has inherited methods from DescriptionMixin`, function() { expect(model.prototype.hasDescription).not.toEqual(undefined); @@ -28,7 +30,7 @@ export function assertDescriptionMixinInheritance(model: typeof DescriptionMixin }); } -export function assertExtensionsMixinInheritance(model: typeof ExtensionsMixin) { +export function assertExtensionsMixinInheritance(model: Constructor) { describe('SpecificationExtensionsMixin inheritance', function() { it(`check if ${model.name} model has inherited methods from ExtensionsMixin`, function() { expect(model.prototype.extensions).not.toEqual(undefined); @@ -38,7 +40,7 @@ export function assertExtensionsMixinInheritance(model: typeof ExtensionsMixin) }); } -export function assertExternalDocumentationMixinInheritance(model: typeof ExternalDocumentationMixin) { +export function assertExternalDocumentationMixinInheritance(model: Constructor) { describe('ExternalDocsMixin inheritance', function() { it(`check if ${model.name} model has inherited methods from ExternalDocumentationMixin`, function() { expect(model.prototype.hasExternalDocs).not.toEqual(undefined); @@ -52,7 +54,7 @@ export function assertExternalDocumentationMixinInheritance(model: typeof Extern }); } -export function assertTagsMixinInheritance(model: typeof TagsMixin) { +export function assertTagsMixinInheritance(model: Constructor) { describe('TagsMixin inheritance', function() { it(`check if ${model.name} model has inherited methods from TagsMixin`, function() { expect(model.prototype.tags).not.toEqual(undefined); diff --git a/test/models/v2/server.spec.ts b/test/models/v2/server.spec.ts index ccb318834..3a43ee1da 100644 --- a/test/models/v2/server.spec.ts +++ b/test/models/v2/server.spec.ts @@ -1,92 +1,61 @@ import { Server } from '../../../src/models/v2/server'; -import { Servers } from '../../../src/models/v2/servers'; + +import { + assertDescriptionMixinInheritance, + assertExtensionsMixinInheritance, +} from './mixins/inheritance'; const doc = { - 'development': { - protocol: 'mqtt', - protocolVersion: '1.0.0', - url: 'development.gigantic-server.com' - } + 'development': { + protocol: 'mqtt', + protocolVersion: '1.0.0', + url: 'development.gigantic-server.com' + } }; const docItem = new Server('development', doc.development); const emptyItem = new Server('',{}); -describe('Servers model', function () { - describe('.isEmpty()', function () { - it('should return true if collection is empty', function () { - const servers = new Servers([]); - expect(servers.isEmpty()).toBeTruthy(); - }); - - it('should return false if collection is not empty', function () { - const servers = new Servers([docItem]); - expect(servers.isEmpty()).toBeFalsy(); - }); - }) - - describe('.get(id)', function () { - it('should return a specific server Object if it is present', function () { - const servers = new Servers([docItem]); - expect(servers.get('development')).toBeTruthy(); - }); - - it('should return undefined if a server is said Id is missing ', function () { - const servers = new Servers([]); - expect(servers.get('development')).toBeUndefined(); - }); - }) - - describe('.has(id)', function () { - - const servers = new Servers([docItem]); - - it('should return true if the said name is available', function () { - expect(servers.has('development')).toBeTruthy(); - }) - - it('should return false if the server name is missing', function () { - expect(servers.has('production')).toBeFalsy(); - }) - }) -}) - describe('Server Model', function () { - - describe('.id()', function () { - it('should return name if present', function () { - expect(docItem.id()).toMatch('development'); - }); + describe('.id()', function () { + it('should return name if present', function () { + expect(docItem.id()).toMatch('development'); }); + }); - describe('protocol()', function () { - it('should return protocol ', function () { - expect(docItem.protocol()).toMatch(doc.development.protocol); - }); + describe('protocol()', function () { + it('should return protocol ', function () { + expect(docItem.protocol()).toMatch(doc.development.protocol); }); + }); - describe('.hasProtocolVersion()', function () { - it('should return true if protocolVersion is not missing', function () { - expect(docItem.hasProtocolVersion()).toBeTruthy(); - }); + describe('.hasProtocolVersion()', function () { + it('should return true if protocolVersion is not missing', function () { + expect(docItem.hasProtocolVersion()).toBeTruthy(); + }); - it('should be false when protocolVersion is missing', function () { - expect(emptyItem.hasProtocolVersion()).toBeFalsy(); - }); - }) + it('should be false when protocolVersion is missing', function () { + expect(emptyItem.hasProtocolVersion()).toBeFalsy(); + }); + }) - describe('.protocolVersion()', function () { - it('should return protocolVersion', function () { - expect(docItem.protocolVersion()).toMatch(doc.development.protocolVersion); - }); + describe('.protocolVersion()', function () { + it('should return value', function () { + expect(docItem.protocolVersion()).toMatch(doc.development.protocolVersion); + }); - it('should return undefined protocolVersion when protocolVersion is missing', function () { - expect(emptyItem.protocolVersion()).toBeUndefined(); - }) + it('should return undefined when protocolVersion is missing', function () { + expect(emptyItem.protocolVersion()).toBeUndefined(); }) + }) - describe('.url()', function () { - it('should return url', function () { - expect(docItem.url()).toMatch(doc.development.url); - }); + describe('.url()', function () { + it('should return value', function () { + expect(docItem.url()).toMatch(doc.development.url); }); + }); + + describe('mixins inheritance', function() { + assertDescriptionMixinInheritance(Server); + assertExtensionsMixinInheritance(Server); + }); }) \ No newline at end of file diff --git a/test/models/v2/servers.spec.ts b/test/models/v2/servers.spec.ts new file mode 100644 index 000000000..f76ff7f3c --- /dev/null +++ b/test/models/v2/servers.spec.ts @@ -0,0 +1,49 @@ +import { Servers } from '../../../src/models/v2/servers'; +import { Server } from '../../../src/models/v2/server'; + +const doc = { + 'development': { + protocol: 'mqtt', + protocolVersion: '1.0.0', + url: 'development.gigantic-server.com' + } +}; +const docItem = new Server('development', doc.development); + +describe('Servers model', function () { + describe('.isEmpty()', function () { + it('should return true if collection is empty', function () { + const servers = new Servers([]); + expect(servers.isEmpty()).toBeTruthy(); + }); + + it('should return false if collection is not empty', function () { + const servers = new Servers([docItem]); + expect(servers.isEmpty()).toBeFalsy(); + }); + }); + + describe('.get(id)', function () { + it('should return a specific server Object if it is present', function () { + const servers = new Servers([docItem]); + expect(servers.get('development')).toBeTruthy(); + }); + + it('should return undefined if a server is said Id is missing ', function () { + const servers = new Servers([]); + expect(servers.get('development')).toBeUndefined(); + }); + }); + + describe('.has(id)', function () { + const servers = new Servers([docItem]); + + it('should return true if the said name is available', function () { + expect(servers.has('development')).toBeTruthy(); + }) + + it('should return false if the server name is missing', function () { + expect(servers.has('production')).toBeFalsy(); + }) + }) +}) \ No newline at end of file diff --git a/test/stringify.spec.ts b/test/stringify.spec.ts index 6c515f886..14c79eee9 100644 --- a/test/stringify.spec.ts +++ b/test/stringify.spec.ts @@ -1,8 +1,11 @@ import { xParserSpecParsed, xParserSpecStringified } from '../src/constants'; import { BaseModel, newAsyncAPIDocument } from '../src/models'; import { stringify, unstringify } from '../src/stringify'; +import { createDetailedAsyncAPI } from '../src/utils'; describe('stringify & unstringify', function() { + class Model extends BaseModel {} + describe('stringify()', function() { it('should not stringify normal object', function() { expect(stringify({})).toEqual(undefined); @@ -17,7 +20,7 @@ describe('stringify & unstringify', function() { }); it('should not stringify BaseModel instance', function() { - expect(stringify(new BaseModel({}))).toEqual(undefined); + expect(stringify(new Model({}))).toEqual(undefined); }); it('should stringify parsed document', function() { @@ -29,7 +32,9 @@ describe('stringify & unstringify', function() { }); it('should stringify AsyncAPIDocument instance', function() { - expect(typeof stringify(newAsyncAPIDocument({ asyncapi: '2.0.0' }))).toEqual('string'); + const doc = { asyncapi: '2.0.0' }; + const detailed = createDetailedAsyncAPI(doc, doc); + expect(typeof stringify(newAsyncAPIDocument(detailed))).toEqual('string'); }); }); @@ -47,7 +52,7 @@ describe('stringify & unstringify', function() { }); it('should not stringify BaseModel instance', function() { - expect(unstringify(new BaseModel({}))).toEqual(undefined); + expect(unstringify(new Model({}))).toEqual(undefined); }); it('should not unstringify parsed document', function() { diff --git a/test/utils.spec.ts b/test/utils.spec.ts index b8e6afd5d..e5ebfdca3 100644 --- a/test/utils.spec.ts +++ b/test/utils.spec.ts @@ -19,7 +19,10 @@ import { import type { Diagnostic } from '../src/types'; describe('utils', function() { + class Model extends BaseModel {} + describe('toAsyncAPIDocument()', function() { + it('normal object should not return AsyncAPIDocument instance', function() { expect(toAsyncAPIDocument({})).toEqual(undefined); }); @@ -33,11 +36,13 @@ describe('utils', function() { }); it('BaseModel instance should not return AsyncAPIDocument instance', function() { - expect(toAsyncAPIDocument(new BaseModel({}))).toEqual(undefined); + expect(toAsyncAPIDocument(new Model({}))).toEqual(undefined); }); it('AsyncAPIDocument instance should return AsyncAPIDocument instance', function() { - expect(toAsyncAPIDocument(newAsyncAPIDocument({ asyncapi: '2.0.0' }))).toBeInstanceOf(AsyncAPIDocumentV2); + const doc = { asyncapi: '2.0.0' }; + const detailed = createDetailedAsyncAPI(doc, doc); + expect(toAsyncAPIDocument(newAsyncAPIDocument(detailed))).toBeInstanceOf(AsyncAPIDocumentV2); }); it('parsed document should return AsyncAPIDocument instance', function() { @@ -67,11 +72,13 @@ describe('utils', function() { }); it('BaseModel instance should not be AsyncAPI document', function() { - expect(isAsyncAPIDocument(new BaseModel({}))).toEqual(false); + expect(isAsyncAPIDocument(new Model({}))).toEqual(false); }); it('AsyncAPIDocument instance should be AsyncAPI document', function() { - expect(isAsyncAPIDocument(newAsyncAPIDocument({ asyncapi: '2.0.0' }))).toEqual(true); + const doc = { asyncapi: '2.0.0' }; + const detailed = createDetailedAsyncAPI(doc, doc); + expect(isAsyncAPIDocument(newAsyncAPIDocument(detailed))).toEqual(true); }); }); @@ -89,15 +96,19 @@ describe('utils', function() { }); it('BaseModel instance should not be AsyncAPI document', function() { - expect(isParsedDocument(new BaseModel({}))).toEqual(false); + expect(isParsedDocument(new Model({}))).toEqual(false); }); it('AsyncAPIDocument instance should not be parsed document', function() { - expect(isParsedDocument(newAsyncAPIDocument({ asyncapi: '2.0.0' }))).toEqual(false); + const doc = { asyncapi: '2.0.0' }; + const detailed = createDetailedAsyncAPI(doc, doc); + expect(isParsedDocument(newAsyncAPIDocument(detailed))).toEqual(false); }); it('AsyncAPIDocument instance with proper extension should not be parsed document', function() { - expect(isParsedDocument(newAsyncAPIDocument({ asyncapi: '2.0.0', [xParserSpecParsed]: true }))).toEqual(false); + const doc = { asyncapi: '2.0.0', [xParserSpecParsed]: true }; + const detailed = createDetailedAsyncAPI(doc, doc); + expect(isParsedDocument(newAsyncAPIDocument(detailed))).toEqual(false); }); it('object with proper extension should be parsed document', function() { @@ -119,15 +130,19 @@ describe('utils', function() { }); it('BaseModel instance should not be AsyncAPI document', function() { - expect(isStringifiedDocument(new BaseModel({}))).toEqual(false); + expect(isStringifiedDocument(new Model({}))).toEqual(false); }); it('AsyncAPIDocument instance should not be parsed document', function() { - expect(isStringifiedDocument(newAsyncAPIDocument({ asyncapi: '2.0.0' }))).toEqual(false); + const doc = { asyncapi: '2.0.0' }; + const detailed = createDetailedAsyncAPI(doc, doc); + expect(isStringifiedDocument(newAsyncAPIDocument(detailed))).toEqual(false); }); it('AsyncAPIDocument instance with proper extension should not be parsed document', function() { - expect(isStringifiedDocument(newAsyncAPIDocument({ asyncapi: '2.0.0', [xParserSpecParsed]: true, [xParserSpecStringified]: true }))).toEqual(false); + const doc = { asyncapi: '2.0.0', [xParserSpecParsed]: true, [xParserSpecStringified]: true }; + const detailed = createDetailedAsyncAPI(doc, doc); + expect(isStringifiedDocument(newAsyncAPIDocument(detailed))).toEqual(false); }); it('object with only stringified extension should not be parsed document', function() {