diff --git a/packages/rulesets/src/asyncapi/__tests__/asyncapi-channel-parameters-defined.test.ts b/packages/rulesets/src/asyncapi/__tests__/asyncapi-channel-parameters.test.ts similarity index 98% rename from packages/rulesets/src/asyncapi/__tests__/asyncapi-channel-parameters-defined.test.ts rename to packages/rulesets/src/asyncapi/__tests__/asyncapi-channel-parameters.test.ts index 1b697ec32..e4715798a 100644 --- a/packages/rulesets/src/asyncapi/__tests__/asyncapi-channel-parameters-defined.test.ts +++ b/packages/rulesets/src/asyncapi/__tests__/asyncapi-channel-parameters.test.ts @@ -1,7 +1,7 @@ import { DiagnosticSeverity } from '@stoplight/types'; import testRule from './__helpers__/tester'; -testRule('asyncapi-channel-parameters-defined', [ +testRule('asyncapi-channel-parameters', [ { name: 'valid case', document: { diff --git a/packages/rulesets/src/asyncapi/__tests__/asyncapi-server-variables-defined.test.ts b/packages/rulesets/src/asyncapi/__tests__/asyncapi-server-variables.test.ts similarity index 98% rename from packages/rulesets/src/asyncapi/__tests__/asyncapi-server-variables-defined.test.ts rename to packages/rulesets/src/asyncapi/__tests__/asyncapi-server-variables.test.ts index b4be3e8df..b529611aa 100644 --- a/packages/rulesets/src/asyncapi/__tests__/asyncapi-server-variables-defined.test.ts +++ b/packages/rulesets/src/asyncapi/__tests__/asyncapi-server-variables.test.ts @@ -1,7 +1,7 @@ import { DiagnosticSeverity } from '@stoplight/types'; import testRule from './__helpers__/tester'; -testRule('asyncapi-server-variables-defined', [ +testRule('asyncapi-server-variables', [ { name: 'valid case', document: { diff --git a/packages/rulesets/src/asyncapi/functions/asyncApi2ChannelParameters.ts b/packages/rulesets/src/asyncapi/functions/asyncApi2ChannelParameters.ts index 92cf96dec..24897fc64 100644 --- a/packages/rulesets/src/asyncapi/functions/asyncApi2ChannelParameters.ts +++ b/packages/rulesets/src/asyncapi/functions/asyncApi2ChannelParameters.ts @@ -1,5 +1,8 @@ import { createRulesetFunction } from '@stoplight/spectral-core'; -import { parseUrlVariables, getMissingProps, getRedundantProps } from './utils'; + +import { parseUrlVariables } from './utils/parseUrlVariables'; +import { getMissingProps } from './utils/getMissingProps'; +import { getRedundantProps } from './utils/getRedundantProps'; import type { IFunctionResult } from '@stoplight/spectral-core'; @@ -13,7 +16,7 @@ export default createRulesetFunction<{ parameters: Record }, nu const results: IFunctionResult[] = []; const parameters = parseUrlVariables(path); - if (!parameters || parameters.length === 0) return; + if (parameters.length === 0) return; const missingParameters = getMissingProps(parameters, targetVal.parameters); if (missingParameters.length) { diff --git a/packages/rulesets/src/asyncapi/functions/asyncApi2ServerVariables.ts b/packages/rulesets/src/asyncapi/functions/asyncApi2ServerVariables.ts index 943ef2d3c..2d7023a9d 100644 --- a/packages/rulesets/src/asyncapi/functions/asyncApi2ServerVariables.ts +++ b/packages/rulesets/src/asyncapi/functions/asyncApi2ServerVariables.ts @@ -1,5 +1,8 @@ import { createRulesetFunction } from '@stoplight/spectral-core'; -import { parseUrlVariables, getMissingProps, getRedundantProps } from './utils'; + +import { parseUrlVariables } from './utils/parseUrlVariables'; +import { getMissingProps } from './utils/getMissingProps'; +import { getRedundantProps } from './utils/getRedundantProps'; import type { IFunctionResult } from '@stoplight/spectral-core'; @@ -12,7 +15,7 @@ export default createRulesetFunction<{ url: string; variables: Record v.slice(1, -1)); -} - -export function getMissingProps(arr: string[] = [], obj: Record = {}) { - if (!Object.keys(obj).length) return arr; - return arr.filter(val => { - return !obj.hasOwnProperty(val); - }); -} - -export function getRedundantProps(arr: string[] = [], obj: Record = {}) { - if (!arr.length) return Object.keys(obj); - return Object.keys(obj).filter(val => { - return !arr.includes(val); - }); -} diff --git a/packages/rulesets/src/asyncapi/functions/utils/__tests__/getMissingProps.test.ts b/packages/rulesets/src/asyncapi/functions/utils/__tests__/getMissingProps.test.ts new file mode 100644 index 000000000..928d06ae0 --- /dev/null +++ b/packages/rulesets/src/asyncapi/functions/utils/__tests__/getMissingProps.test.ts @@ -0,0 +1,18 @@ +import { getMissingProps } from '../getMissingProps'; + +describe('getMissingProps', () => { + test('should return all props when object is empty', () => { + const result = getMissingProps(['one', 'two', 'three'], {}); + expect(result).toEqual(['one', 'two', 'three']); + }); + + test('should return only missed props', () => { + const result = getMissingProps(['one', 'two', 'three'], { one: {}, three: {} }); + expect(result).toEqual(['two']); + }); + + test('should return empty array when all props are defined', () => { + const result = getMissingProps(['one', 'two', 'three'], { one: {}, two: {}, three: {} }); + expect(result).toEqual([]); + }); +}); diff --git a/packages/rulesets/src/asyncapi/functions/utils/__tests__/getRedundantProps.test.ts b/packages/rulesets/src/asyncapi/functions/utils/__tests__/getRedundantProps.test.ts new file mode 100644 index 000000000..bad9660fa --- /dev/null +++ b/packages/rulesets/src/asyncapi/functions/utils/__tests__/getRedundantProps.test.ts @@ -0,0 +1,18 @@ +import { getRedundantProps } from '../getRedundantProps'; + +describe('getRedundantProps', () => { + test('should return all redundant props when array is empty', () => { + const result = getRedundantProps([], { one: {}, two: {}, three: {} }); + expect(result).toEqual(['one', 'two', 'three']); + }); + + test('should return only redundant props', () => { + const result = getRedundantProps(['one', 'three'], { one: {}, two: {}, three: {} }); + expect(result).toEqual(['two']); + }); + + test('should return empty array when all props are defined', () => { + const result = getRedundantProps(['one', 'two', 'three'], { one: {}, two: {}, three: {} }); + expect(result).toEqual([]); + }); +}); diff --git a/packages/rulesets/src/asyncapi/functions/utils/__tests__/parseUrlVariables.test.ts b/packages/rulesets/src/asyncapi/functions/utils/__tests__/parseUrlVariables.test.ts new file mode 100644 index 000000000..ada099353 --- /dev/null +++ b/packages/rulesets/src/asyncapi/functions/utils/__tests__/parseUrlVariables.test.ts @@ -0,0 +1,13 @@ +import { parseUrlVariables } from '../parseUrlVariables'; + +describe('parseUrlVariables', () => { + test('should return all variables from string', () => { + const result = parseUrlVariables('{stage}.some.{channel}'); + expect(result).toEqual(['stage', 'channel']); + }); + + test('should return empty array if no variable is defined', () => { + const result = parseUrlVariables('stage.some.channel'); + expect(result).toEqual([]); + }); +}); diff --git a/packages/rulesets/src/asyncapi/functions/utils/getMissingProps.ts b/packages/rulesets/src/asyncapi/functions/utils/getMissingProps.ts new file mode 100644 index 000000000..72d5784ed --- /dev/null +++ b/packages/rulesets/src/asyncapi/functions/utils/getMissingProps.ts @@ -0,0 +1,6 @@ +export function getMissingProps(arr: string[] = [], obj: Record = {}): string[] { + if (!Object.keys(obj).length) return arr; + return arr.filter(val => { + return !Object.prototype.hasOwnProperty.call(obj, val); + }); +} diff --git a/packages/rulesets/src/asyncapi/functions/utils/getRedundantProps.ts b/packages/rulesets/src/asyncapi/functions/utils/getRedundantProps.ts new file mode 100644 index 000000000..d7a9fdeae --- /dev/null +++ b/packages/rulesets/src/asyncapi/functions/utils/getRedundantProps.ts @@ -0,0 +1,6 @@ +export function getRedundantProps(arr: string[] = [], obj: Record = {}): string[] { + if (!arr.length) return Object.keys(obj); + return Object.keys(obj).filter(val => { + return !arr.includes(val); + }); +} diff --git a/packages/rulesets/src/asyncapi/functions/utils/parseUrlVariables.ts b/packages/rulesets/src/asyncapi/functions/utils/parseUrlVariables.ts new file mode 100644 index 000000000..071c3e388 --- /dev/null +++ b/packages/rulesets/src/asyncapi/functions/utils/parseUrlVariables.ts @@ -0,0 +1,6 @@ +export function parseUrlVariables(str: string): string[] { + if (typeof str !== 'string') return []; + const variables = str.match(/{(.+?)}/g); + if (!variables || variables.length === 0) return []; + return variables.map(v => v.slice(1, -1)); +} diff --git a/packages/rulesets/src/asyncapi/index.ts b/packages/rulesets/src/asyncapi/index.ts index 465923491..06114f22b 100644 --- a/packages/rulesets/src/asyncapi/index.ts +++ b/packages/rulesets/src/asyncapi/index.ts @@ -57,7 +57,7 @@ export default { }, }, }, - 'asyncapi-channel-parameters-defined': { + 'asyncapi-channel-parameters': { description: 'Channel parameters must be defined and there must be no redundant parameters.', message: '{{error}}', severity: 'error', @@ -295,7 +295,7 @@ export default { function: asyncApi2DocumentSchema, }, }, - 'asyncapi-server-variables-defined': { + 'asyncapi-server-variables': { description: 'Server variables must be defined and there must be no redundant variables.', message: '{{error}}', severity: 'error',