Skip to content

Commit

Permalink
3.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Igorkowalski94 committed Oct 3, 2024
1 parent 859a100 commit dd4ce91
Show file tree
Hide file tree
Showing 26 changed files with 834 additions and 122 deletions.
8 changes: 5 additions & 3 deletions fileComposition.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ export const fileCompositionConfig = createFileComposition({

{
filePattern: "src/rules/*/*.ts",
allowOnlySpecifiedSelectors: true,
allowOnlySpecifiedSelectors: {
file: false,
},
rules: [
{
selector: { type: "variableExpression", limitTo: "ESLintUtils" },
Expand All @@ -49,13 +51,13 @@ export const fileCompositionConfig = createFileComposition({
rootSelectorsLimits: [{ selector: ["arrowFunction", "class"], limit: 1 }],
rules: [
{
selector: "interface",
selector: ["interface", "type"],
positionIndex: 0,
scope: "fileRoot",
format: "{FileName}Props",
},
{
selector: "interface",
selector: ["interface", "type"],
positionIndex: 1,
scope: "fileRoot",
format: "{FileName}Return",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "rules/fileComposition/fileComposition.types";
import { FILE_COMPOSITION_SCHEMA } from "rules/fileComposition/helpers/getFileCompositionConfig/getFileCompositionConfig.consts";

// eslint-disable-next-line project-structure/file-composition
interface GetFileCompositionConfigReturn {
config: FileCompositionConfig;
fileConfig?: FileRules;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Rule } from "rules/fileComposition/fileComposition.types";
import { getFileNameWithoutExtension } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/getFilenameWithoutParts/helpers/getFileNameWithoutExtension";
import { removeFilenameParts } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/getFilenameWithoutParts/helpers/removeFilenameParts";

interface GetFilenameWithoutPartsProps {
filenamePartsToRemove: Rule["filenamePartsToRemove"];
filenamePath: string;
}

export const getFilenameWithoutParts = ({
filenamePartsToRemove,
filenamePath,
}: GetFilenameWithoutPartsProps): string => {
const filenameWithoutExtension = getFileNameWithoutExtension(filenamePath);
return removeFilenameParts({
filenameWithoutExtension,
filenamePartsToRemove,
});
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Rule } from "rules/fileComposition/fileComposition.types";
import { removeFilenameParts } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/removeFilenameParts";
import { removeFilenameParts } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/getFilenameWithoutParts/helpers/removeFilenameParts";

describe("removeFilenameParts", () => {
test.each<{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { RegexParameters } from "types";

import {
Context,
Node,
Rule,
SelectorType,
} from "rules/fileComposition/fileComposition.types";
import { getBodyWithoutImports } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/helpers/getBodyWithoutImports";
import { getPositionIndex } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/helpers/getPositionIndex";
import { getPositionIndexRules } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/helpers/getPositionIndexRules";
import { validatePositionIndex } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/validatePositionIndex/validatePositionIndex";

interface HandlePositionIndexProps {
positionIndex: number;
node: Node;
filenamePath: string;
rules: Rule[];
regexParameters?: RegexParameters;
context: Context;
name: string;
selectorType: SelectorType;
}

export const handlePositionIndex = ({
filenamePath,
positionIndex,
node,
rules,
regexParameters,
context,
name,
selectorType,
}: HandlePositionIndexProps): void => {
const positionIndexRules = getPositionIndexRules({
filenamePath,
rules,
regexParameters,
});
const bodyWithoutImports = getBodyWithoutImports(node);
const newPositionIndex = getPositionIndex({
bodyWithoutImports,
name,
positionIndex,
positionIndexRules,
});

validatePositionIndex({
node,
positionIndex: newPositionIndex,
selectorType,
context,
bodyWithoutImports,
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface PositionIndexRule {
positionIndex: number;
format: string[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { TSESTree } from "@typescript-eslint/utils";

import { Node } from "rules/fileComposition/fileComposition.types";
import { getProgramFromNode } from "rules/fileComposition/helpers/validateFile/helpers/getProgramFromNode";

export const getBodyWithoutImports = (
node: Node,
): TSESTree.ProgramStatement[] => {
const program = getProgramFromNode(node);

return program.body.filter(
({ type }) => type !== TSESTree.AST_NODE_TYPES.ImportDeclaration,
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { PositionIndexRule } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/handlePositionIndex.types";
import { getPositionIndex } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/helpers/getPositionIndex";
import { getSelectorNamesFromBody } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/helpers/getSelectorNamesFromBody";

jest.mock(
"rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/helpers/getSelectorNamesFromBody",
() => ({
getSelectorNamesFromBody: jest.fn(),
}),
);

describe("getPositionIndex", () => {
test.each<{
name: string;
positionIndexRules: PositionIndexRule[];
expected: number;
}>([
{
name: "Return",
positionIndexRules: [
{ format: ["Props"], positionIndex: 0 },
{ format: ["Return"], positionIndex: 1 },
{ format: ["Name"], positionIndex: 2 },
],
expected: 0,
},
{
name: "Name",
positionIndexRules: [
{ format: ["variable"], positionIndex: 0 },
{ format: ["Return"], positionIndex: 1 },
{ format: ["Name"], positionIndex: 2 },
],
expected: 2,
},
{
name: "Name",
positionIndexRules: [],
expected: 1,
},
])(
"Should return correct value for = %o",
({ name, positionIndexRules, expected }) => {
(getSelectorNamesFromBody as jest.Mock).mockReturnValue([
"variable",
"Return",
"Name",
]);

expect(
getPositionIndex({
bodyWithoutImports: [],
name,
positionIndex: 1,
positionIndexRules,
}),
).toEqual(expected);
},
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { TSESTree } from "@typescript-eslint/utils";

import { PositionIndexRule } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/handlePositionIndex.types";
import { getSelectorNamesFromBody } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/helpers/getSelectorNamesFromBody";

interface GetPositionIndexProps {
positionIndex: number;
positionIndexRules: PositionIndexRule[];
bodyWithoutImports: TSESTree.ProgramStatement[];
name: string;
}

export const getPositionIndex = ({
positionIndexRules,
positionIndex,
bodyWithoutImports,
name,
}: GetPositionIndexProps): number => {
const selectorNamesFromBody = getSelectorNamesFromBody(bodyWithoutImports);

const positionIndexRulesBody = selectorNamesFromBody
.map((name) =>
positionIndexRules.find(({ format }) => format.includes(name)),
)
.filter((v): v is PositionIndexRule => v !== undefined)
.sort((a, b) => a.positionIndex - b.positionIndex);

const positionIndexRulesNewOrder = positionIndexRulesBody.map(
({ format }, index) => ({
format,
positionIndex: index,
}),
);

const newPositionIndex = positionIndexRulesNewOrder.find(({ format }) =>
format.includes(name),
)?.positionIndex;

return newPositionIndex ?? positionIndex;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getPositionIndexRules } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/helpers/getPositionIndexRules";

describe("validateRules", () => {
test("Should return correct values", () => {
expect(
getPositionIndexRules({
filenamePath: "",
rules: [
{ selector: "arrowFunction", positionIndex: 1, format: "Props" },
{ selector: "variable" },
],
}),
).toEqual([{ format: ["Props"], positionIndex: 1 }]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { RegexParameters } from "types";

import { Rule } from "rules/fileComposition/fileComposition.types";
import { getFilenameWithoutParts } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/getFilenameWithoutParts/getFilenameWithoutParts";
import { PositionIndexRule } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/handlePositionIndex/handlePositionIndex.types";
import { prepareFormat } from "rules/fileComposition/helpers/validateFile/helpers/validateRules/helpers/prepareFormat/prepareFormat";

interface GetPositionIndexRulesProps {
rules: Rule[];
regexParameters?: RegexParameters;
filenamePath: string;
}

export const getPositionIndexRules = ({
rules,
regexParameters,
filenamePath,
}: GetPositionIndexRulesProps): PositionIndexRule[] =>
rules
.map(({ format, filenamePartsToRemove, positionIndex }) => {
if (positionIndex === undefined) return;

const filenameWithoutParts = getFilenameWithoutParts({
filenamePartsToRemove,
filenamePath,
});

return {
positionIndex,
format: prepareFormat({
format,
filenameWithoutParts,
regexParameters,
}).formatWithoutReferences,
};
})
.filter((v): v is PositionIndexRule => v !== undefined);
Loading

0 comments on commit dd4ce91

Please sign in to comment.