Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(specs): proper title with linter #3444

Merged
merged 9 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ module.exports = {
'automation-custom/out-of-line-any-of': 'error',
'automation-custom/valid-acl': 'error',
'automation-custom/ref-common': 'error',
'automation-custom/valid-inline-title': 'error',
},
},
],
Expand Down
2 changes: 2 additions & 0 deletions eslint/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createOutOfLineRule } from './rules/outOfLineRule';
import { refCommon } from './rules/refCommon';
import { singleQuoteRef } from './rules/singleQuoteRef';
import { validACL } from './rules/validACL';
import { validInlineTitle } from './rules/validInlineTitle';

const rules = {
'end-with-dot': endWithDot,
Expand All @@ -17,6 +18,7 @@ const rules = {
'valid-acl': validACL,
'no-new-line': noNewLine,
'ref-common': refCommon,
'valid-inline-title': validInlineTitle,
};

// Custom parser for ESLint, to read plain text file like mustache.
Expand Down
23 changes: 1 addition & 22 deletions eslint/src/rules/outOfLineRule.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import type { Rule } from 'eslint';
import type { AST } from 'yaml-eslint-parser';

import {
isBlockScalar,
isMapping,
isPairWithKey,
isScalar,
isSequence,
} from '../utils';
import { isNullable, isPairWithKey } from '../utils';

export function createOutOfLineRule({
property,
Expand Down Expand Up @@ -74,17 +67,3 @@ export function createOutOfLineRule({
};
return rule;
}

function isNullable(node: AST.YAMLNode | null): boolean {
return (
isSequence(node) &&
node.entries.some(
(entry) =>
isMapping(entry) &&
isPairWithKey(entry.pairs[0], 'type') &&
isScalar(entry.pairs[0].value) &&
!isBlockScalar(entry.pairs[0].value) &&
entry.pairs[0].value.raw === "'null'"
)
);
}
103 changes: 103 additions & 0 deletions eslint/src/rules/validInlineTitle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import type { Rule } from 'eslint';

import { isNullable, isPairWithKey } from '../utils';

export const validInlineTitle: Rule.RuleModule = {
meta: {
docs: {
description:
'title must be set in inline models, should be the first property and start with a lowercase',
},
messages: {
inlineTitleExists: 'title must be set in inline models',
lowercaseTitle: 'title must start with a lowercase',
firstProperty: 'title must be the first property',
noSpaceInTitle: 'title must not contain spaces',
},
},
create(context) {
if (!context.sourceCode.parserServices.isYAML) {
return {};
}

return {
YAMLPair(node): void {
if (
!isPairWithKey(node, 'type') ||
node.value?.type !== 'YAMLScalar' ||
node.value.value !== 'object'
) {
return;
}

// we don't enforce it for root level object
if (node.parent.parent.loc.start.column === 0) {
return;
}

// make sure title starts with a lowercase
const title = node.parent.pairs.find((pair) =>
isPairWithKey(pair, 'title')
);
const titleNode = title?.value;
const titleValue = (titleNode as any)?.value as string;
if (
titleNode &&
(titleNode.type !== 'YAMLScalar' || !/^[a-z]/.test(titleValue))
) {
context.report({
node: title,
messageId: 'lowercaseTitle',
});
}

// make sure title doesn't contain spaces
if (titleValue?.includes(' ')) {
context.report({
node: title,
messageId: 'noSpaceInTitle',
});
}

// if there are no properties, we don't need a title
const properties = node.parent.pairs.find((pair) =>
isPairWithKey(pair, 'properties')
);
if (!properties) {
return;
}

// allow it on nullable objects
if (
isPairWithKey(node.parent.parent.parent, 'oneOf') &&
isNullable(node.parent.parent.parent.value)
) {
return;
}

// allow on allOf too, since they are not generated
if (isPairWithKey(node.parent.parent.parent, 'allOf')) {
return;
}

// make sure the title is set on the same object
if (!title) {
context.report({
node: node.value,
messageId: 'inlineTitleExists',
});

return;
}

// make sure title is the first property
if (!isPairWithKey(node.parent.pairs[0], 'title')) {
context.report({
node: title,
messageId: 'firstProperty',
});
}
},
};
},
};
14 changes: 14 additions & 0 deletions eslint/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,17 @@ export function isPairWithKey(
return false;
return isScalar(node.key) && node.key.value === key;
}

export function isNullable(node: AST.YAMLNode | null): boolean {
return (
isSequence(node) &&
node.entries.some(
(entry) =>
isMapping(entry) &&
isPairWithKey(entry.pairs[0], 'type') &&
isScalar(entry.pairs[0].value) &&
!isBlockScalar(entry.pairs[0].value) &&
entry.pairs[0].value.raw === "'null'"
)
);
}
95 changes: 95 additions & 0 deletions eslint/tests/validInlineTitle.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { RuleTester } from 'eslint';

import { validInlineTitle } from '../src/rules/validInlineTitle';

const ruleTester = new RuleTester({
parser: require.resolve('yaml-eslint-parser'),
});

ruleTester.run('valid-inline-title', validInlineTitle, {
valid: [
`
currencies:
type: object
properties:
inner:
type: object
`,
`
currencies:
type: object
properties:
inner:
title: currency
type: object
properties:
currency:
type: string
title: Currency
`,
`
dictionaryLanguage:
oneOf:
- type: object
properties:
prop:
type: integer
- type: 'null'
`,
],
invalid: [
{
code: `
currencies:
type: object
properties:
inner:
type: object
properties:
currency:
type: string
title: Currency
`,
errors: [{ messageId: 'inlineTitleExists' }],
},
{
code: `
currencies:
type: object
properties:
inner:
type: object
title: currency
properties:
currency:
type: string
title: Currency
`,
errors: [{ messageId: 'firstProperty' }],
},
{
code: `
currencies:
title: UpperCaseFine
type: object
properties:
inner:
title: UpperCaseNotFine
type: object
`,
errors: [{ messageId: 'lowercaseTitle' }],
},
{
code: `
currencies:
title: spaces are fine
type: object
properties:
inner:
title: spaces are not fine
type: object
`,
errors: [{ messageId: 'noSpaceInTitle' }],
},
],
});
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public class AlgoliaSwiftGenerator extends Swift5ClientCodegen {
"facetordering",
"facets",
"facetsstats",
"forbidden",
"highlightresult",
"highlightresultoption",
"ignoreplurals",
Expand All @@ -83,10 +84,11 @@ public class AlgoliaSwiftGenerator extends Swift5ClientCodegen {
"promoteobjectids",
"querysuggestionsconfiguration",
"querytype",
"range",
"rankinginfo",
"redirect",
"redirectruleindexmetadata",
"redirectruleindexmetadatadata",
"redirectruleindexdata",
"redirecturl",
"region",
"removestopwords",
Expand Down
2 changes: 1 addition & 1 deletion scripts/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export async function formatter(language: string, cwd: string): Promise<void> {
break;
case 'java':
await run(
`find . -type f -name "*.java" | xargs java --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
`find . -path ./.gradle -prune -o -type f -name "*.java" | xargs java --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
Expand Down
2 changes: 2 additions & 0 deletions specs/abtesting/common/parameters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ filterEffects:
description: A/B test filter effects resulting from configuration settings.
properties:
outliers:
title: outliersFilter
type: object
description: Outliers removed from the A/B test as a result of configuration settings.
example:
Expand All @@ -111,6 +112,7 @@ filterEffects:
description: Number of tracked searches removed from the A/B test.
example: 237
emptySearch:
title: emptySearchFilter
type: object
description: Empty searches removed from the A/B test as a result of configuration settings.
example:
Expand Down
3 changes: 3 additions & 0 deletions specs/analytics/common/parameters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ clickPositions:
minItems: 12
maxItems: 12
items:
title: clickPosition
type: object
description: Click position.
properties:
Expand Down Expand Up @@ -242,10 +243,12 @@ purchaseCount:
example: 10

currencies:
title: currenciesValue
type: object
description: Revenue associated with this search, broken-down by currencies.
default: {}
additionalProperties:
title: currencyCode
x-additionalPropertiesName: currency
type: object
description: Currency code.
Expand Down
6 changes: 3 additions & 3 deletions specs/analytics/common/schemas/getTopHits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ topHitsResponse:
type: array
description: Most frequent search results.
items:
type: object
title: topHit
type: object
additionalProperties: false
required:
- hit
Expand All @@ -32,8 +32,8 @@ topHitsResponseWithAnalytics:
type: array
description: Most frequent search results with click and conversion metrics.
items:
type: object
title: topHitWithAnalytics
type: object
additionalProperties: false
required:
- hit
Expand Down Expand Up @@ -70,8 +70,8 @@ topHitsResponseWithRevenueAnalytics:
type: array
description: Most frequent search results with click, conversion, and revenue metrics.
items:
type: object
title: topHitWithRevenueAnalytics
type: object
additionalProperties: false
required:
- hit
Expand Down
Loading
Loading