From 9f29be6bc029cbeb45b9179554e0cbb665025474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Smestad?= Date: Mon, 18 Sep 2023 15:16:32 +0200 Subject: [PATCH] Add tests for sorting rules we use --- eslint.config.js | 6 +++++ test/cases/nice-sort.tsx | 55 ++++++++++++++++++++++++++++++++++++++++ test/cases/ugly-sort.tsx | 51 +++++++++++++++++++++++++++++++++++++ test/test.js | 42 ++++++++++++++++++++++++++++++ tsconfig.json | 2 +- 5 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 test/cases/nice-sort.tsx create mode 100644 test/cases/ugly-sort.tsx diff --git a/eslint.config.js b/eslint.config.js index 856b1a8..98ca0ad 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -5,6 +5,9 @@ import tidal from './index.js'; /** @type { import("eslint").Linter.FlatConfig[] } */ export default [ ...tidal, + { + files: ['*.js', '**/*.js', '**/*.ts', '**/*.tsx'], + }, { ignores: ['test/cases/*'], }, @@ -14,5 +17,8 @@ export default [ ...globals.node, }, }, + settings: { + 'import/internal-regex': '^@tidal/', + }, }, ]; diff --git a/test/cases/nice-sort.tsx b/test/cases/nice-sort.tsx new file mode 100644 index 0000000..abad8df --- /dev/null +++ b/test/cases/nice-sort.tsx @@ -0,0 +1,55 @@ +/* eslint-disable @typescript-eslint/no-empty-function */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable import/no-unresolved */ + +// Sorted imports: +import classnames from 'classnames'; +import * as React from 'react'; + +import { ResourceImage } from '@tidal/core/src/components/resourceImage/resourceImage'; +import { TextImage } from '@tidal/core/src/components/textImage/textImage'; + +import TrashcanIcon from '@tidal/react-icons/lib/detail-view/trashcan'; + +import type { CombinedProps } from '@tidal/web/src/containers/profileImage/profileImage'; + +// eslint-disable-next-line import/extensions +import styles from './profileImage.module.css'; + +// Sorted type keys: +export type ClientApplication = { + name: string; + service: string; + type: number; +}; + +// Sorted type union: +export type OnboardingStepName = 'ALBUM_INFO' | 'BLOCK' | 'CAST'; + +// Sorted object keys: +export function ProfileImageRepresentation({ + className, + desiredWidth, + resourceId, + width, +}) { + const style = { + height: (() => {})(), + width: (() => {})(), + }; + + // Sorted JSX props: + return ( + + ); +} diff --git a/test/cases/ugly-sort.tsx b/test/cases/ugly-sort.tsx new file mode 100644 index 0000000..d850c0c --- /dev/null +++ b/test/cases/ugly-sort.tsx @@ -0,0 +1,51 @@ +/* eslint-disable @typescript-eslint/no-empty-function */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable import/no-unresolved */ + +// Sorted imports: +import { ResourceImage } from '@tidal/core/src/components/resourceImage/resourceImage'; +import { TextImage } from '@tidal/core/src/components/textImage/textImage'; +import TrashcanIcon from '@tidal/react-icons/lib/detail-view/trashcan'; +import classnames from 'classnames'; +import * as React from 'react'; +import type { CombinedProps } from '@tidal/web/src/containers/profileImage/profileImage'; +// eslint-disable-next-line import/extensions +import styles from './profileImage.module.css'; + +// Sorted type keys: +export type ClientApplication = { + type: number; + name: string; + service: string; +}; + +// Sorted type union: +export type OnboardingStepName = 'BLOCK' | 'ALBUM_INFO' | 'CAST'; + +// Sorted object keys: +export function ProfileImageRepresentation({ + width, + className, + desiredWidth, + resourceId, +}) { + const style = { + height: (() => {})(), + width: (() => {})(), + }; + + // Sorted JSX props: + return ( + + ); +} diff --git a/test/test.js b/test/test.js index 7a4967a..43cbc83 100644 --- a/test/test.js +++ b/test/test.js @@ -59,3 +59,45 @@ test('Success on nice files', async t => { errors.map(console.log); } }); + +test('Fails on unsorted file', async t => { + const errors = await runEslint('test/cases/ugly-sort.tsx'); + const errorsAsRuleIds = getUniqueValues( + errors.map((/** @type {{ ruleId: any; }} */ item) => item.ruleId), + ); + + const expectedErrors = [ + 'import/order', + 'typescript-sort-keys/interface', + '@typescript-eslint/sort-type-constituents', + 'sort-destructure-keys/sort-destructure-keys', + ]; + + const expectedErrorsFound = errorsAsRuleIds.filter( + error => expectedErrors.indexOf(error) !== -1, + ); + + // All expected error types are found: + t.is(expectedErrorsFound.length, expectedErrors.length); + + // All found errors are of expected types: + const unexpectedErrorsFound = errorsAsRuleIds.filter( + error => expectedErrors.indexOf(error) === -1, + ); + t.is(unexpectedErrorsFound.length, 0); + + // Total number of seen errors: + t.is(errors.length, 9); +}); + +test('Success on sorted file', async t => { + const errors = await runEslint('test/cases/nice-sort.tsx'); + + t.is(errors.length, 0); + + // For debugging: + if (errors.length) { + // eslint-disable-next-line no-console + errors.map(console.log); + } +}); diff --git a/tsconfig.json b/tsconfig.json index c953e66..a414010 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ /* Language and Environment */ "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ + "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */