Skip to content

Commit

Permalink
feat: added new evaluate command to check the score of the asyncapi d…
Browse files Browse the repository at this point in the history
…ocument (#1413)

Co-authored-by: asyncapi-bot <[email protected]>
  • Loading branch information
AayushSaini101 and asyncapi-bot authored Jul 31, 2024
1 parent 24ceea7 commit 0368d64
Show file tree
Hide file tree
Showing 5 changed files with 256 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/commands/validate.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Args } from '@oclif/core';
import Command from '../core/base';
import { validate, ValidateOptions, ValidationStatus } from '../core/parser';
import { validate, ValidateOptions, ValidationStatus, parse } from '../core/parser';
import { load } from '../core/models/SpecificationFile';
import { specWatcher } from '../core/globals';
import { validateFlags } from '../core/flags/validate.flags';
import { calculateScore } from '../core/utils/scoreCalculator';

export default class Validate extends Command {
static description = 'validate asyncapi file';
Expand All @@ -16,9 +17,14 @@ export default class Validate extends Command {

async run() {
const { args, flags } = await this.parse(Validate); //NOSONAR

const filePath = args['spec-file'];
const watchMode = flags.watch;

if (flags['score']) {
this.specFile = await load(filePath);
const { document } = await parse(this,this.specFile);
this.log(`The score of the asyncapi document is ${await calculateScore(document)}`);
}
this.specFile = await load(filePath);
if (watchMode) {
specWatcher({ spec: this.specFile, handler: this, handlerName: 'validate' });
Expand Down
5 changes: 5 additions & 0 deletions src/core/flags/validate.flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@ export const validateFlags = () => {
help: Flags.help({ char: 'h' }),
watch: watchFlag(),
...validationFlags(),
score: Flags.boolean({
description: 'Compute the score of the AsyncAPI document. Scoring is based on whether the document has description, license, server and/or channels.',
required: false,
default: false
})
};
};
18 changes: 18 additions & 0 deletions src/core/utils/scoreCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { AsyncAPIDocumentInterface } from '@asyncapi/parser/cjs/models';

export async function calculateScore(document: AsyncAPIDocumentInterface | undefined) {
let scoreEvaluate = 0;
if (document?.info().hasDescription()) {
scoreEvaluate += 0.15;
}
if (document?.info().hasLicense()) {
scoreEvaluate += 0.25;
}
if (!document?.servers().isEmpty()) {
scoreEvaluate += 0.25;
}
if (!document?.channels().isEmpty()) {
scoreEvaluate += 0.35;
}
return (scoreEvaluate / 1) * 100;
}
206 changes: 206 additions & 0 deletions test/fixtures/asyncapiTestingScore.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
asyncapi: 3.0.0
info:
title: Streetlights Kafka API
version: 1.0.0
description: |-
The Smartylighting Streetlights API allows you to remotely manage the city
lights.
### Check out its awesome features:
* Turn a specific streetlight on/off 🌃
* Dim a specific streetlight 😎
* Receive real-time information about environmental lighting conditions 📈
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0
defaultContentType: application/json
servers:
scram-connections:
host: test.mykafkacluster.org:18092
protocol: kafka-secure
description: Test broker secured with scramSha256
security:
- $ref: '#/components/securitySchemes/saslScram'
tags:
- name: env:test-scram
description: >-
This environment is meant for running internal tests through
scramSha256
- name: kind:remote
description: This server is a remote server. Not exposed by the application
- name: visibility:private
description: This resource is private and only available to certain users
mtls-connections:
host: test.mykafkacluster.org:28092
protocol: kafka-secure
description: Test broker secured with X509
security:
- $ref: '#/components/securitySchemes/certs'
tags:
- name: env:test-mtls
description: This environment is meant for running internal tests through mtls
- name: kind:remote
description: This server is a remote server. Not exposed by the application
- name: visibility:private
description: This resource is private and only available to certain users
channels:
lightingMeasured:
address: smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured
messages:
lightMeasured:
$ref: '#/components/messages/lightMeasured'
description: The topic on which measured values may be produced and consumed.
parameters:
streetlightId:
$ref: '#/components/parameters/streetlightId'
lightTurnOn:
address: smartylighting.streetlights.1.0.action.{streetlightId}.turn.on
messages:
turnOn:
$ref: '#/components/messages/turnOnOff'
parameters:
streetlightId:
$ref: '#/components/parameters/streetlightId'
lightTurnOff:
address: smartylighting.streetlights.1.0.action.{streetlightId}.turn.off
messages:
turnOff:
$ref: '#/components/messages/turnOnOff'
parameters:
streetlightId:
$ref: '#/components/parameters/streetlightId'
lightsDim:
address: smartylighting.streetlights.1.0.action.{streetlightId}.dim
messages:
dimLight:
$ref: '#/components/messages/dimLight'
parameters:
streetlightId:
$ref: '#/components/parameters/streetlightId'
operations:
receiveLightMeasurement:
action: receive
channel:
$ref: '#/channels/lightingMeasured'
summary: >-
Inform about environmental lighting conditions of a particular
streetlight.
traits:
- $ref: '#/components/operationTraits/kafka'
messages:
- $ref: '#/channels/lightingMeasured/messages/lightMeasured'
turnOn:
action: send
channel:
$ref: '#/channels/lightTurnOn'
traits:
- $ref: '#/components/operationTraits/kafka'
messages:
- $ref: '#/channels/lightTurnOn/messages/turnOn'
turnOff:
action: send
channel:
$ref: '#/channels/lightTurnOff'
traits:
- $ref: '#/components/operationTraits/kafka'
messages:
- $ref: '#/channels/lightTurnOff/messages/turnOff'
dimLight:
action: send
channel:
$ref: '#/channels/lightsDim'
traits:
- $ref: '#/components/operationTraits/kafka'
messages:
- $ref: '#/channels/lightsDim/messages/dimLight'
components:
messages:
lightMeasured:
name: lightMeasured
title: Light measured
summary: >-
Inform about environmental lighting conditions of a particular
streetlight.
contentType: application/json
traits:
- $ref: '#/components/messageTraits/commonHeaders'
payload:
$ref: '#/components/schemas/lightMeasuredPayload'
turnOnOff:
name: turnOnOff
title: Turn on/off
summary: Command a particular streetlight to turn the lights on or off.
traits:
- $ref: '#/components/messageTraits/commonHeaders'
payload:
$ref: '#/components/schemas/turnOnOffPayload'
dimLight:
name: dimLight
title: Dim light
summary: Command a particular streetlight to dim the lights.
traits:
- $ref: '#/components/messageTraits/commonHeaders'
payload:
$ref: '#/components/schemas/dimLightPayload'
schemas:
lightMeasuredPayload:
type: object
properties:
lumens:
type: integer
minimum: 0
description: Light intensity measured in lumens.
sentAt:
$ref: '#/components/schemas/sentAt'
turnOnOffPayload:
type: object
properties:
command:
type: string
enum:
- 'on'
- 'off'
description: Whether to turn on or off the light.
sentAt:
$ref: '#/components/schemas/sentAt'
dimLightPayload:
type: object
properties:
percentage:
type: integer
description: Percentage to which the light should be dimmed to.
minimum: 0
maximum: 100
sentAt:
$ref: '#/components/schemas/sentAt'
sentAt:
type: string
format: date-time
description: Date and time when the message was sent.
securitySchemes:
saslScram:
type: scramSha256
description: Provide your username and password for SASL/SCRAM authentication
certs:
type: X509
description: Download the certificate files from service provider
parameters:
streetlightId:
description: The ID of the streetlight.
messageTraits:
commonHeaders:
headers:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
operationTraits:
kafka:
bindings:
kafka:
clientId:
type: string
enum:
- my-app-id
19 changes: 19 additions & 0 deletions test/integration/validate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,23 @@ describe('validate', () => {
done();
});
});

describe('with --score flag',() => {
beforeEach(() => {
testHelper.createDummyContextFile();
});

afterEach(() => {
testHelper.deleteDummyContextFile();
});

test
.stdout()
.command(['validate', './test/fixtures/asyncapiTestingScore.yml', '--score'])
.it('work with --score flag', (ctx, done) => {
expect(ctx.stdout).to.contains('The score of the asyncapi document is 100\n');
expect(ctx.stdout).to.contains('File ./test/fixtures/asyncapiTestingScore.yml is valid! File ./test/fixtures/asyncapiTestingScore.yml and referenced documents don\'t have governance issues.');
done();
});
});
});

0 comments on commit 0368d64

Please sign in to comment.