@blumintinc/eslint-plugin-blumint 1.19.11 → 1.19.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -222,7 +222,7 @@ function noFrontendImportsFromFunctionsPatterns(pattern) {
222
222
  module.exports = {
223
223
  meta: {
224
224
  name: '@blumintinc/eslint-plugin-blumint',
225
- version: '1.19.11',
225
+ version: '1.19.12',
226
226
  },
227
227
  parseOptions: {
228
228
  ecmaVersion: 2020,
@@ -1 +1,7 @@
1
- export declare const testFileLocationEnforcement: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"misplacedTestFile", [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
1
+ type Options = [
2
+ {
3
+ additionalSubjectExtensions?: string[];
4
+ }?
5
+ ];
6
+ export declare const testFileLocationEnforcement: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"misplacedTestFile", Options, import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
7
+ export {};
@@ -9,6 +9,10 @@ const path_1 = __importDefault(require("path"));
9
9
  const createRule_1 = require("../utils/createRule");
10
10
  const TEST_FILE_PATTERN = /\.test\.tsx?$/i;
11
11
  const SUPPORTED_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx'];
12
+ const DEFAULT_OPTIONS = {
13
+ additionalSubjectExtensions: [],
14
+ };
15
+ const normalizeExtension = (extension) => extension.startsWith('.') ? extension : `.${extension}`;
12
16
  exports.testFileLocationEnforcement = (0, createRule_1.createRule)({
13
17
  name: 'test-file-location-enforcement',
14
18
  meta: {
@@ -17,13 +21,31 @@ exports.testFileLocationEnforcement = (0, createRule_1.createRule)({
17
21
  description: 'Enforce colocating *.test.ts or *.test.tsx files with the code they cover.',
18
22
  recommended: 'error',
19
23
  },
20
- schema: [],
24
+ schema: [
25
+ {
26
+ type: 'object',
27
+ properties: {
28
+ additionalSubjectExtensions: {
29
+ type: 'array',
30
+ items: { type: 'string' },
31
+ default: [],
32
+ },
33
+ },
34
+ additionalProperties: false,
35
+ },
36
+ ],
21
37
  messages: {
22
38
  misplacedTestFile: 'Test file "{{testFile}}" is not colocated with its subject. Keep tests in the same directory as {{expectedNames}} so refactors move code and coverage together and engineers can find the implementation without searching separate test folders.',
23
39
  },
24
40
  },
25
- defaultOptions: [],
26
- create(context) {
41
+ defaultOptions: [DEFAULT_OPTIONS],
42
+ create(context, [options]) {
43
+ const resolvedOptions = { ...DEFAULT_OPTIONS, ...(options ?? {}) };
44
+ const additionalExtensions = (resolvedOptions.additionalSubjectExtensions ?? []).map(normalizeExtension);
45
+ const subjectExtensions = [
46
+ ...SUPPORTED_EXTENSIONS,
47
+ ...additionalExtensions.filter((extension) => !SUPPORTED_EXTENSIONS.includes(extension)),
48
+ ];
27
49
  return {
28
50
  Program(node) {
29
51
  const filename = context.getFilename();
@@ -36,7 +58,7 @@ exports.testFileLocationEnforcement = (0, createRule_1.createRule)({
36
58
  const directory = path_1.default.dirname(filename);
37
59
  const testFileName = path_1.default.basename(filename);
38
60
  const baseName = testFileName.replace(TEST_FILE_PATTERN, '');
39
- const candidates = SUPPORTED_EXTENSIONS.map((extension) => path_1.default.join(directory, `${baseName}${extension}`));
61
+ const candidates = subjectExtensions.map((extension) => path_1.default.join(directory, `${baseName}${extension}`));
40
62
  const hasSibling = candidates.some((candidate) => fs_1.default.existsSync(candidate));
41
63
  if (hasSibling) {
42
64
  return;
@@ -44,7 +66,9 @@ exports.testFileLocationEnforcement = (0, createRule_1.createRule)({
44
66
  const relativePath = path_1.default.isAbsolute(filename)
45
67
  ? path_1.default.relative(process.cwd(), filename) || filename
46
68
  : filename;
47
- const expectedNames = SUPPORTED_EXTENSIONS.map((extension) => `"${baseName}${extension}"`).join(' or ');
69
+ const expectedNames = subjectExtensions
70
+ .map((extension) => `"${baseName}${extension}"`)
71
+ .join(' or ');
48
72
  context.report({
49
73
  node,
50
74
  messageId: 'misplacedTestFile',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.19.11",
3
+ "version": "1.19.12",
4
4
  "description": "Custom eslint rules for use within BluMint",
5
5
  "author": {
6
6
  "name": "Brodie McGuire",
@@ -1,4 +1,18 @@
1
1
  [
2
+ {
3
+ "version": "1.19.12",
4
+ "date": "2026-07-17T19:23:55.157Z",
5
+ "rules": [
6
+ {
7
+ "name": "test-file-location-enforcement",
8
+ "changeType": "fix",
9
+ "issues": [
10
+ 1314
11
+ ],
12
+ "summary": "add opt-in additionalSubjectExtensions for non-JS/TS subjects (closes #1314)"
13
+ }
14
+ ]
15
+ },
2
16
  {
3
17
  "version": "1.19.11",
4
18
  "date": "2026-07-17T10:46:20.593Z",