Skip to content

Commit

Permalink
refactor: add models for server object (asyncapi#497)
Browse files Browse the repository at this point in the history
  • Loading branch information
Souvikns authored and magicmatatjahu committed Oct 3, 2022
1 parent d7e6bb0 commit d749906
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .sonarcloud.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Disable specific duplicate code since it would introduce more complexity to reduce it.
sonar.cpd.exclusions=src/models/**/*.ts
2 changes: 2 additions & 0 deletions src/models/asyncapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import { AsyncAPIDocumentV3 } from "./v3";
import type { InfoInterface } from "./info";
import type { BaseModel } from "./base";
import type { ExtensionsMixinInterface } from "./mixins";
import { ServersInterface } from "./servers";

export interface AsyncAPIDocumentInterface extends BaseModel, ExtensionsMixinInterface {
version(): string;
info(): InfoInterface;
servers(): ServersInterface
}

export function newAsyncAPIDocument(json: Record<string, any>): AsyncAPIDocumentInterface {
Expand Down
10 changes: 10 additions & 0 deletions src/models/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { BaseModel } from "./base";
import { BindingsMixinInterface, DescriptionMixinInterface } from './mixins';

export interface ServerInterface extends BaseModel, DescriptionMixinInterface, BindingsMixinInterface {
id(): string
protocol(): string | undefined;
protocolVersion(): string;
hasProtocolVersion(): boolean;
url(): string;
}
4 changes: 4 additions & 0 deletions src/models/servers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Collection } from "./collection";
import {ServerInterface} from "./server";

export interface ServersInterface extends Collection<ServerInterface> {}
10 changes: 10 additions & 0 deletions src/models/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,14 @@ function mixin(derivedCtor: any, constructors: any[]): typeof BaseModel {
});
});
return derivedCtor;
}

export function createArrayFromMap(json: Record<string,any>){
const ArrayObject = [];
for (const [key, value] of Object.entries(json)) {
value['id'] = key;
ArrayObject.push(value);
};

return ArrayObject;
}
13 changes: 11 additions & 2 deletions src/models/v2/asyncapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ 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";

export class AsyncAPIDocument
extends Mixin(BaseModel, ExtensionsMixin)
export class AsyncAPIDocument
extends Mixin(BaseModel, ExtensionsMixin)
implements AsyncAPIDocumentInterface {

version(): string {
Expand All @@ -17,4 +20,10 @@ export class AsyncAPIDocument
info(): InfoInterface {
return new Info(this._json.info);
}

servers(): ServersInterface {
return new Servers(
Object.entries(this._json.servers).map(([serverName, server]) => new Server(serverName, server as Record<string, any>))
);
}
}
4 changes: 3 additions & 1 deletion src/models/v2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ export { License as LicenseV2 } from './license';
export { Bindings as BindingsV2, Binding as BindingV2 } from './mixins/bindings';
export { Extensions as ExtensionsV2, Extension as ExtensionV2 } from './mixins/extensions';
export { ExternalDocumentation as ExternalDocumentationV2 } from './mixins/external-docs';
export { Tags as TagsV2, Tag as TagV2 } from './mixins/tags';
export { Tags as TagsV2, Tag as TagV2 } from './mixins/tags';
export { Server as ServerV2 } from './server';
export { Servers as ServersV2 } from './servers';
34 changes: 34 additions & 0 deletions src/models/v2/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Mixin } from '../utils';
import { BaseModel } from '../base';
import { ServerInterface } from '../server';
import { DescriptionMixin } from './mixins/description';
import { BindingsMixin } from './mixins/bindings';

export class Server extends Mixin(BaseModel, DescriptionMixin, BindingsMixin) implements ServerInterface {
constructor(
private readonly _id: string,
_json: Record<string, any>
){
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');
}
}
13 changes: 13 additions & 0 deletions src/models/v2/servers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Collection } from '../collection';
import { ServerInterface } from '../server';
import { ServersInterface } from '../servers';

export class Servers extends Collection<ServerInterface> implements ServersInterface {
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);
}
}
13 changes: 12 additions & 1 deletion src/models/v3/asyncapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,27 @@ import { Info } from "./info";

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)
implements AsyncAPIDocumentInterface {

version(): string {
return this.json("asyncapi");
}

info(): Info {
return new Info(this.json("info"));
}

servers(): ServersInterface {
return new Servers(
Object.entries(this._json.servers).map(
([serverName, server]) => new Server(serverName, server as Record<string, any>)
)
)
}
}
4 changes: 3 additions & 1 deletion src/models/v3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ export { License as LicenseV3 } from './license';
export { Bindings as BindingsV3, Binding as BindingV3 } from './mixins/bindings';
export { Extensions as ExtensionsV3, Extension as ExtensionV3 } from './mixins/extensions';
export { ExternalDocumentation as ExternalDocumentationV3 } from './mixins/external-docs';
export { Tags as TagsV3, Tag as TagV3 } from './mixins/tags';
export { Tags as TagsV3, Tag as TagV3 } from './mixins/tags';
export { Server as ServerV3 } from './server';
export { Servers as ServersV3 } from './servers';
34 changes: 34 additions & 0 deletions src/models/v3/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Mixin } from '../utils';
import { BaseModel } from '../base';
import { ServerInterface } from '../server';
import { DescriptionMixin } from './mixins/description';
import { BindingsMixin } from './mixins/bindings';

export class Server extends Mixin(BaseModel, DescriptionMixin, BindingsMixin) implements ServerInterface {
constructor(
private readonly _id: string,
_json: Record<string, any>
){
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');
}
}
13 changes: 13 additions & 0 deletions src/models/v3/servers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Collection } from '../collection';
import { ServerInterface } from '../server';
import { ServersInterface } from '../servers';

export class Servers extends Collection<ServerInterface> implements ServersInterface {
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);
}
}
14 changes: 13 additions & 1 deletion test/models/v2/asyncapi.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { newAsyncAPIDocument, AsyncAPIDocumentV2, InfoV2, AsyncAPIDocumentV3 } from '../../../src/models';
import { newAsyncAPIDocument, AsyncAPIDocumentV2, InfoV2, AsyncAPIDocumentV3, ServersV2 } from '../../../src/models';

import {
assertExtensionsMixinInheritance,
Expand Down Expand Up @@ -27,6 +27,18 @@ describe('AsyncAPIDocument model', function() {
});
});

describe('.servers()', function(){
it('should return an servers object', function(){
const doc = {servers: {
development: {

}
}};
const d = new AsyncAPIDocumentV2(doc);
expect(d.servers() instanceof ServersV2).toBeTruthy();
})
})

describe('mixins inheritance', function() {
assertExtensionsMixinInheritance(AsyncAPIDocumentV2);
});
Expand Down
92 changes: 92 additions & 0 deletions test/models/v2/server.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Server } from '../../../src/models/v2/server';
import { Servers } from '../../../src/models/v2/servers';

const doc = {
'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('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();
});

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);
});

it('should return undefined protocolVersion when protocolVersion is missing', function () {
expect(emptyItem.protocolVersion()).toBeUndefined();
})
})

describe('.url()', function () {
it('should return url', function () {
expect(docItem.url()).toMatch(doc.development.url);
});
});
})

0 comments on commit d749906

Please sign in to comment.