@archest/vitest 1.0.1 → 1.0.2

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.
Files changed (191) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +1 -13
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +44 -764
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/matchers/index.d.ts +21 -0
  7. package/dist/matchers/models.d.ts +201 -0
  8. package/node_modules/@archest/core/dist/classes/locateClasses.d.ts +5 -0
  9. package/node_modules/@archest/core/dist/classes/types.d.ts +25 -0
  10. package/node_modules/@archest/core/dist/dto.d.ts +78 -0
  11. package/node_modules/@archest/core/dist/files/checkDependOnExternalModule.d.ts +3 -0
  12. package/node_modules/@archest/core/dist/files/getFileDependencies.d.ts +2 -0
  13. package/node_modules/@archest/core/dist/files/locateFiles.d.ts +4 -0
  14. package/node_modules/@archest/core/dist/files/types.d.ts +17 -0
  15. package/node_modules/@archest/core/dist/functions/locateFunctions.d.ts +5 -0
  16. package/node_modules/@archest/core/dist/functions/types.d.ts +19 -0
  17. package/node_modules/@archest/core/dist/index.d.ts +43 -0
  18. package/node_modules/@archest/core/dist/index.js +14 -0
  19. package/node_modules/@archest/core/dist/index.js.map +1 -0
  20. package/node_modules/@archest/core/dist/index.mjs +615 -0
  21. package/node_modules/@archest/core/dist/index.mjs.map +1 -0
  22. package/node_modules/@archest/core/dist/layers/createLayeredArchitecture.d.ts +3 -0
  23. package/node_modules/@archest/core/dist/layers/getLayerDependencies.d.ts +2 -0
  24. package/node_modules/@archest/core/dist/layers/types.d.ts +8 -0
  25. package/node_modules/@archest/core/dist/project/parseProject.d.ts +55 -0
  26. package/node_modules/@archest/core/dist/properties/locateProperties.d.ts +5 -0
  27. package/node_modules/@archest/core/dist/properties/types.d.ts +17 -0
  28. package/node_modules/@archest/core/dist/shared/sharedCheckHaveMaxCyclomaticComplexity.d.ts +1 -0
  29. package/node_modules/@archest/core/dist/shared/sharedCheckHaveMinMaintainabilityIndex.d.ts +1 -0
  30. package/node_modules/@archest/core/dist/shared/sharedCheckHaveModifier.d.ts +7 -0
  31. package/node_modules/@archest/core/dist/shared/sharedCheckHaveNameMatchingFileName.d.ts +3 -0
  32. package/node_modules/@archest/core/dist/shared/sharedCheckMatchNamePattern.d.ts +1 -0
  33. package/node_modules/@archest/core/dist/slices/locateSlices.d.ts +3 -0
  34. package/node_modules/@archest/core/dist/slices/types.d.ts +8 -0
  35. package/node_modules/@archest/core/package.json +49 -0
  36. package/node_modules/@archest/core-rust/core-rust.darwin-arm64.node +0 -0
  37. package/node_modules/@archest/core-rust/core-rust.linux-x64-gnu.node +0 -0
  38. package/node_modules/@archest/core-rust/core-rust.win32-x64-msvc.node +0 -0
  39. package/node_modules/@archest/core-rust/index.d.ts +16 -0
  40. package/node_modules/@archest/core-rust/index.js +316 -0
  41. package/node_modules/@archest/core-rust/package.json +34 -0
  42. package/package.json +12 -1
  43. package/dist/src/core/classes/locateClasses.d.ts +0 -3
  44. package/dist/src/core/classes/types.d.ts +0 -14
  45. package/dist/src/core/files/getFileDependencies.d.ts +0 -2
  46. package/dist/src/core/files/locateFiles.d.ts +0 -3
  47. package/dist/src/core/files/types.d.ts +0 -10
  48. package/dist/src/core/functions/locateFunctions.d.ts +0 -3
  49. package/dist/src/core/functions/types.d.ts +0 -11
  50. package/dist/src/core/layers/createLayeredArchitecture.d.ts +0 -3
  51. package/dist/src/core/layers/getLayerDependencies.d.ts +0 -2
  52. package/dist/src/core/layers/types.d.ts +0 -8
  53. package/dist/src/core/project/parseProject.d.ts +0 -22
  54. package/dist/src/core/properties/locateProperties.d.ts +0 -3
  55. package/dist/src/core/properties/types.d.ts +0 -10
  56. package/dist/src/core/shared/sharedCheckHaveMaxCyclomaticComplexity.d.ts +0 -1
  57. package/dist/src/core/shared/sharedCheckHaveMinMaintainabilityIndex.d.ts +0 -1
  58. package/dist/src/core/shared/sharedCheckHaveModifier.d.ts +0 -2
  59. package/dist/src/core/shared/sharedCheckHaveNameMatchingFileName.d.ts +0 -2
  60. package/dist/src/core/shared/sharedCheckMatchNamePattern.d.ts +0 -1
  61. package/dist/src/core/slices/locateSlices.d.ts +0 -3
  62. package/dist/src/core/slices/types.d.ts +0 -8
  63. package/dist/src/index.d.ts +0 -35
  64. package/dist/src/matchers/index.d.ts +0 -20
  65. package/src/core/classes/classCheckExtendClass.test.ts +0 -30
  66. package/src/core/classes/classCheckExtendClass.ts +0 -41
  67. package/src/core/classes/classCheckHaveMaxCyclomaticComplexity.test.ts +0 -8
  68. package/src/core/classes/classCheckHaveMaxCyclomaticComplexity.ts +0 -35
  69. package/src/core/classes/classCheckHaveModifier.test.ts +0 -30
  70. package/src/core/classes/classCheckHaveModifier.ts +0 -17
  71. package/src/core/classes/classCheckHaveNameMatchingFileName.test.ts +0 -30
  72. package/src/core/classes/classCheckHaveNameMatchingFileName.ts +0 -15
  73. package/src/core/classes/classCheckImplementInterface.test.ts +0 -30
  74. package/src/core/classes/classCheckImplementInterface.ts +0 -43
  75. package/src/core/classes/classCheckMatchNamePattern.test.ts +0 -8
  76. package/src/core/classes/classCheckMatchNamePattern.ts +0 -17
  77. package/src/core/classes/classCheckResideInFolder.test.ts +0 -8
  78. package/src/core/classes/classCheckResideInFolder.ts +0 -31
  79. package/src/core/classes/locateClasses.test.ts +0 -13
  80. package/src/core/classes/locateClasses.ts +0 -127
  81. package/src/core/classes/types.ts +0 -16
  82. package/src/core/files/checkDependOnFilesInFolder.test.ts +0 -7
  83. package/src/core/files/checkDependOnFilesInFolder.ts +0 -36
  84. package/src/core/files/fileCheckBeFreeOfCycles.test.ts +0 -7
  85. package/src/core/files/fileCheckBeFreeOfCycles.ts +0 -72
  86. package/src/core/files/fileCheckHaveMaxCyclomaticComplexity.test.ts +0 -8
  87. package/src/core/files/fileCheckHaveMaxCyclomaticComplexity.ts +0 -35
  88. package/src/core/files/fileCheckHaveMaxExportedFunctions.test.ts +0 -32
  89. package/src/core/files/fileCheckHaveMaxExportedFunctions.ts +0 -45
  90. package/src/core/files/fileCheckHaveMinMaintainabilityIndex.test.ts +0 -8
  91. package/src/core/files/fileCheckHaveMinMaintainabilityIndex.ts +0 -19
  92. package/src/core/files/fileCheckMatchNamePattern.test.ts +0 -30
  93. package/src/core/files/fileCheckMatchNamePattern.ts +0 -17
  94. package/src/core/files/getFileDependencies.ts +0 -43
  95. package/src/core/files/locateFiles.test.ts +0 -30
  96. package/src/core/files/locateFiles.ts +0 -31
  97. package/src/core/files/types.ts +0 -12
  98. package/src/core/functions/functionCheckHaveExplicitReturnType.test.ts +0 -30
  99. package/src/core/functions/functionCheckHaveExplicitReturnType.ts +0 -29
  100. package/src/core/functions/functionCheckHaveMaxCyclomaticComplexity.test.ts +0 -8
  101. package/src/core/functions/functionCheckHaveMaxCyclomaticComplexity.ts +0 -20
  102. package/src/core/functions/functionCheckHaveMinMaintainabilityIndex.test.ts +0 -8
  103. package/src/core/functions/functionCheckHaveMinMaintainabilityIndex.ts +0 -20
  104. package/src/core/functions/functionCheckHaveModifier.test.ts +0 -30
  105. package/src/core/functions/functionCheckHaveModifier.ts +0 -18
  106. package/src/core/functions/functionCheckHaveNameMatchingFileName.test.ts +0 -30
  107. package/src/core/functions/functionCheckHaveNameMatchingFileName.ts +0 -16
  108. package/src/core/functions/functionCheckMatchNamePattern.test.ts +0 -30
  109. package/src/core/functions/functionCheckMatchNamePattern.ts +0 -18
  110. package/src/core/functions/locateFunctions.test.ts +0 -16
  111. package/src/core/functions/locateFunctions.ts +0 -47
  112. package/src/core/functions/types.ts +0 -13
  113. package/src/core/layers/checkLayeredArchitecture.test.ts +0 -23
  114. package/src/core/layers/checkLayeredArchitecture.ts +0 -15
  115. package/src/core/layers/createLayeredArchitecture.test.ts +0 -13
  116. package/src/core/layers/createLayeredArchitecture.ts +0 -15
  117. package/src/core/layers/getLayerDependencies.ts +0 -45
  118. package/src/core/layers/layer.test.ts +0 -12
  119. package/src/core/layers/layer.ts +0 -10
  120. package/src/core/layers/layerShouldNotBeAccessedByAnyLayer.test.ts +0 -14
  121. package/src/core/layers/layerShouldNotBeAccessedByAnyLayer.ts +0 -40
  122. package/src/core/layers/layerShouldOnlyBeAccessedBy.test.ts +0 -15
  123. package/src/core/layers/layerShouldOnlyBeAccessedBy.ts +0 -48
  124. package/src/core/layers/types.ts +0 -9
  125. package/src/core/metrics/calculateCyclomaticComplexity.test.ts +0 -23
  126. package/src/core/metrics/calculateCyclomaticComplexity.ts +0 -36
  127. package/src/core/metrics/calculateMaintainabilityIndex.test.ts +0 -38
  128. package/src/core/metrics/calculateMaintainabilityIndex.ts +0 -47
  129. package/src/core/project/parseProject.test.ts +0 -19
  130. package/src/core/project/parseProject.ts +0 -216
  131. package/src/core/properties/locateProperties.test.ts +0 -19
  132. package/src/core/properties/locateProperties.ts +0 -41
  133. package/src/core/properties/propertyCheckBeReadonly.test.ts +0 -32
  134. package/src/core/properties/propertyCheckBeReadonly.ts +0 -27
  135. package/src/core/properties/types.ts +0 -12
  136. package/src/core/shared/sharedCheckHaveMaxCyclomaticComplexity.test.ts +0 -30
  137. package/src/core/shared/sharedCheckHaveMaxCyclomaticComplexity.ts +0 -23
  138. package/src/core/shared/sharedCheckHaveMinMaintainabilityIndex.test.ts +0 -30
  139. package/src/core/shared/sharedCheckHaveMinMaintainabilityIndex.ts +0 -23
  140. package/src/core/shared/sharedCheckHaveModifier.test.ts +0 -31
  141. package/src/core/shared/sharedCheckHaveModifier.ts +0 -51
  142. package/src/core/shared/sharedCheckHaveNameMatchingFileName.test.ts +0 -17
  143. package/src/core/shared/sharedCheckHaveNameMatchingFileName.ts +0 -36
  144. package/src/core/shared/sharedCheckMatchNamePattern.test.ts +0 -29
  145. package/src/core/shared/sharedCheckMatchNamePattern.ts +0 -22
  146. package/src/core/slices/locateSlices.test.ts +0 -22
  147. package/src/core/slices/locateSlices.ts +0 -35
  148. package/src/core/slices/sliceCheckBeFreeOfCycles.test.ts +0 -26
  149. package/src/core/slices/sliceCheckBeFreeOfCycles.ts +0 -91
  150. package/src/core/slices/sliceCheckHaveMaxDistanceFromMainSequence.test.ts +0 -27
  151. package/src/core/slices/sliceCheckHaveMaxDistanceFromMainSequence.ts +0 -110
  152. package/src/core/slices/types.ts +0 -9
  153. package/src/core/testUtils.ts +0 -61
  154. package/src/core/types.ts +0 -19
  155. package/src/core/utils/ruleBuilder.test.ts +0 -24
  156. package/src/core/utils/ruleBuilder.ts +0 -28
  157. package/src/index.ts +0 -35
  158. package/src/matchers/index.ts +0 -331
  159. package/test/architecture.test.ts +0 -152
  160. package/tsconfig.json +0 -18
  161. package/vite.config.ts +0 -18
  162. /package/{dist/src/core → node_modules/@archest/core/dist}/classes/classCheckExtendClass.d.ts +0 -0
  163. /package/{dist/src/core → node_modules/@archest/core/dist}/classes/classCheckHaveMaxCyclomaticComplexity.d.ts +0 -0
  164. /package/{dist/src/core → node_modules/@archest/core/dist}/classes/classCheckHaveModifier.d.ts +0 -0
  165. /package/{dist/src/core → node_modules/@archest/core/dist}/classes/classCheckHaveNameMatchingFileName.d.ts +0 -0
  166. /package/{dist/src/core → node_modules/@archest/core/dist}/classes/classCheckImplementInterface.d.ts +0 -0
  167. /package/{dist/src/core → node_modules/@archest/core/dist}/classes/classCheckMatchNamePattern.d.ts +0 -0
  168. /package/{dist/src/core → node_modules/@archest/core/dist}/classes/classCheckResideInFolder.d.ts +0 -0
  169. /package/{dist/src/core → node_modules/@archest/core/dist}/files/checkDependOnFilesInFolder.d.ts +0 -0
  170. /package/{dist/src/core → node_modules/@archest/core/dist}/files/fileCheckBeFreeOfCycles.d.ts +0 -0
  171. /package/{dist/src/core → node_modules/@archest/core/dist}/files/fileCheckHaveMaxCyclomaticComplexity.d.ts +0 -0
  172. /package/{dist/src/core → node_modules/@archest/core/dist}/files/fileCheckHaveMaxExportedFunctions.d.ts +0 -0
  173. /package/{dist/src/core → node_modules/@archest/core/dist}/files/fileCheckHaveMinMaintainabilityIndex.d.ts +0 -0
  174. /package/{dist/src/core → node_modules/@archest/core/dist}/files/fileCheckMatchNamePattern.d.ts +0 -0
  175. /package/{dist/src/core → node_modules/@archest/core/dist}/functions/functionCheckHaveExplicitReturnType.d.ts +0 -0
  176. /package/{dist/src/core → node_modules/@archest/core/dist}/functions/functionCheckHaveMaxCyclomaticComplexity.d.ts +0 -0
  177. /package/{dist/src/core → node_modules/@archest/core/dist}/functions/functionCheckHaveMinMaintainabilityIndex.d.ts +0 -0
  178. /package/{dist/src/core → node_modules/@archest/core/dist}/functions/functionCheckHaveModifier.d.ts +0 -0
  179. /package/{dist/src/core → node_modules/@archest/core/dist}/functions/functionCheckHaveNameMatchingFileName.d.ts +0 -0
  180. /package/{dist/src/core → node_modules/@archest/core/dist}/functions/functionCheckMatchNamePattern.d.ts +0 -0
  181. /package/{dist/src/core → node_modules/@archest/core/dist}/layers/checkLayeredArchitecture.d.ts +0 -0
  182. /package/{dist/src/core → node_modules/@archest/core/dist}/layers/layer.d.ts +0 -0
  183. /package/{dist/src/core → node_modules/@archest/core/dist}/layers/layerShouldNotBeAccessedByAnyLayer.d.ts +0 -0
  184. /package/{dist/src/core → node_modules/@archest/core/dist}/layers/layerShouldOnlyBeAccessedBy.d.ts +0 -0
  185. /package/{dist/src/core → node_modules/@archest/core/dist}/metrics/calculateCyclomaticComplexity.d.ts +0 -0
  186. /package/{dist/src/core → node_modules/@archest/core/dist}/metrics/calculateMaintainabilityIndex.d.ts +0 -0
  187. /package/{dist/src/core → node_modules/@archest/core/dist}/properties/propertyCheckBeReadonly.d.ts +0 -0
  188. /package/{dist/src/core → node_modules/@archest/core/dist}/slices/sliceCheckBeFreeOfCycles.d.ts +0 -0
  189. /package/{dist/src/core → node_modules/@archest/core/dist}/slices/sliceCheckHaveMaxDistanceFromMainSequence.d.ts +0 -0
  190. /package/{dist/src/core → node_modules/@archest/core/dist}/types.d.ts +0 -0
  191. /package/{dist/src/core → node_modules/@archest/core/dist}/utils/ruleBuilder.d.ts +0 -0
@@ -1,110 +0,0 @@
1
- import * as ts from 'typescript';
2
- import type { RuleResult } from '../types';
3
- import type { SliceLocatorData } from './types';
4
-
5
- export function sliceCheckHaveMaxDistanceFromMainSequence(
6
- locator: SliceLocatorData,
7
- max: number,
8
- isNot: boolean,
9
- ): RuleResult {
10
- const violations: string[] = [];
11
-
12
- const ceMap = new Map<string, Set<string>>(); // Slices this slice depends on
13
- const caMap = new Map<string, Set<string>>(); // Slices depending on this slice
14
-
15
- for (const slice of locator.sliceIds) {
16
- ceMap.set(slice, new Set());
17
- caMap.set(slice, new Set());
18
- }
19
-
20
- for (const [sliceId, files] of locator.sliceFiles.entries()) {
21
- for (const sf of files) {
22
- ts.forEachChild(sf, (node) => {
23
- if (
24
- ts.isImportDeclaration(node) &&
25
- node.moduleSpecifier &&
26
- ts.isStringLiteral(node.moduleSpecifier)
27
- ) {
28
- const importPath = node.moduleSpecifier.text;
29
- const resolved = ts.resolveModuleName(
30
- importPath,
31
- sf.fileName,
32
- locator.program.getCompilerOptions(),
33
- ts.sys,
34
- );
35
- if (resolved.resolvedModule?.resolvedFileName) {
36
- const targetMatch = resolved.resolvedModule.resolvedFileName.match(
37
- locator.slicePattern,
38
- );
39
- if (targetMatch?.[1]) {
40
- const targetSlice = targetMatch[1];
41
- if (
42
- targetSlice !== sliceId &&
43
- locator.sliceIds.has(targetSlice)
44
- ) {
45
- ceMap.get(sliceId)?.add(targetSlice);
46
- caMap.get(targetSlice)?.add(sliceId);
47
- }
48
- }
49
- }
50
- }
51
- });
52
- }
53
- }
54
-
55
- for (const sliceId of locator.sliceIds) {
56
- const ce = ceMap.get(sliceId)?.size;
57
- const ca = caMap.get(sliceId)?.size;
58
-
59
- // biome-ignore lint/style/noNonNullAssertion: Safe map lookup
60
- const files = locator.sliceFiles.get(sliceId)!;
61
- let na = 0; // abstract classes + interfaces
62
- let nc = 0; // all classes + interfaces
63
-
64
- for (const sf of files) {
65
- const visit = (node: ts.Node) => {
66
- if (ts.isClassDeclaration(node)) {
67
- nc++;
68
- const modifiers = ts.canHaveModifiers(node)
69
- ? ts.getModifiers(node)
70
- : undefined;
71
- if (
72
- modifiers?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword)
73
- ) {
74
- na++;
75
- }
76
- } else if (ts.isInterfaceDeclaration(node)) {
77
- nc++;
78
- na++;
79
- }
80
- ts.forEachChild(node, visit);
81
- };
82
- visit(sf);
83
- }
84
-
85
- const I = ce + ca === 0 ? 0 : ce / (ca + ce);
86
- const A = nc === 0 ? 0 : na / nc;
87
-
88
- const D = Math.abs(A + I - 1);
89
- const exceeds = D > max;
90
-
91
- if (isNot && exceeds) {
92
- violations.push(
93
- `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}, but it shouldn't.`,
94
- );
95
- } else if (!isNot && exceeds) {
96
- violations.push(
97
- `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}.`,
98
- );
99
- }
100
- }
101
-
102
- return {
103
- pass: isNot ? violations.length > 0 : violations.length === 0,
104
- message: () =>
105
- violations.join('\n') ||
106
- (isNot
107
- ? 'Expected some slices to exceed maximum distance from main sequence, but none did.'
108
- : ''),
109
- };
110
- }
@@ -1,9 +0,0 @@
1
- import type * as ts from 'typescript';
2
-
3
- export interface SliceLocatorData {
4
- type: 'SliceLocator';
5
- slicePattern: RegExp;
6
- sliceIds: Set<string>;
7
- sliceFiles: Map<string, ts.SourceFile[]>;
8
- program: ts.Program;
9
- }
@@ -1,61 +0,0 @@
1
- import * as ts from 'typescript';
2
-
3
- export function createSourceFile(
4
- code: string,
5
- fileName = 'test.ts',
6
- ): ts.SourceFile {
7
- return ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true);
8
- }
9
-
10
- export function createMockProgram(sourceFiles: ts.SourceFile[]): ts.Program {
11
- const compilerOptions = {};
12
- const host = ts.createCompilerHost(compilerOptions);
13
-
14
- host.getSourceFile = (fileName) => {
15
- return sourceFiles.find((sf) => sf.fileName === fileName) || undefined;
16
- };
17
-
18
- return ts.createProgram({
19
- rootNames: sourceFiles.map((sf) => sf.fileName),
20
- options: compilerOptions,
21
- host: host,
22
- });
23
- }
24
-
25
- export function getClasses(sourceFile: ts.SourceFile): ts.ClassDeclaration[] {
26
- const classes: ts.ClassDeclaration[] = [];
27
- ts.forEachChild(sourceFile, (node) => {
28
- if (ts.isClassDeclaration(node)) classes.push(node);
29
- });
30
- return classes;
31
- }
32
-
33
- export function getFunctions(
34
- sourceFile: ts.SourceFile,
35
- ): ts.FunctionLikeDeclaration[] {
36
- const functions: ts.FunctionLikeDeclaration[] = [];
37
- ts.forEachChild(sourceFile, (node) => {
38
- if (
39
- ts.isFunctionDeclaration(node) ||
40
- ts.isMethodDeclaration(node) ||
41
- ts.isArrowFunction(node)
42
- ) {
43
- functions.push(node as ts.FunctionLikeDeclaration);
44
- }
45
- });
46
- return functions;
47
- }
48
-
49
- export function getProperties(
50
- sourceFile: ts.SourceFile,
51
- ): ts.PropertyDeclaration[] {
52
- const properties: ts.PropertyDeclaration[] = [];
53
- ts.forEachChild(sourceFile, (node) => {
54
- if (ts.isClassDeclaration(node)) {
55
- node.members.forEach((member) => {
56
- if (ts.isPropertyDeclaration(member)) properties.push(member);
57
- });
58
- }
59
- });
60
- return properties;
61
- }
package/src/core/types.ts DELETED
@@ -1,19 +0,0 @@
1
- import type { ClassLocatorData } from './classes/types';
2
- import type { FileLocatorData } from './files/types';
3
- import type { FunctionLocatorData } from './functions/types';
4
- import type { LayeredArchitectureData } from './layers/types';
5
- import type { PropertyLocatorData } from './properties/types';
6
- import type { SliceLocatorData } from './slices/types';
7
-
8
- export interface RuleResult {
9
- pass: boolean;
10
- message: () => string;
11
- }
12
-
13
- export type LocatorData =
14
- | FileLocatorData
15
- | ClassLocatorData
16
- | FunctionLocatorData
17
- | PropertyLocatorData
18
- | SliceLocatorData
19
- | LayeredArchitectureData;
@@ -1,24 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { ruleBuilder } from './ruleBuilder';
3
-
4
- describe('ruleBuilder edge cases', () => {
5
- it('should pass if items array is empty', () => {
6
- const result = ruleBuilder([], false, () => ({
7
- passes: false,
8
- failMessage: '',
9
- failNotMessage: '',
10
- }));
11
- expect(result.pass).toBe(true);
12
- });
13
-
14
- it('should generate correct violation message with NOT', () => {
15
- const items = [{ name: 'A' }];
16
- const result = ruleBuilder(items, true, () => ({
17
- passes: true,
18
- failMessage: '',
19
- failNotMessage: 'Item A should NOT be nice',
20
- }));
21
- expect(result.pass).toBe(false);
22
- expect(result.message()).toContain('Item A should NOT be nice');
23
- });
24
- });
@@ -1,28 +0,0 @@
1
- import type { RuleResult } from '../types';
2
-
3
- export function ruleBuilder<T>(
4
- items: T[],
5
- isNot: boolean,
6
- evaluate: (item: T) => {
7
- passes: boolean;
8
- failMessage: string;
9
- failNotMessage: string;
10
- },
11
- ): RuleResult {
12
- const violations: string[] = [];
13
-
14
- for (const item of items) {
15
- const { passes, failMessage, failNotMessage } = evaluate(item);
16
-
17
- if (isNot && passes) {
18
- if (failNotMessage) violations.push(failNotMessage);
19
- } else if (!isNot && !passes) {
20
- if (failMessage) violations.push(failMessage);
21
- }
22
- }
23
-
24
- return {
25
- pass: violations.length === 0,
26
- message: () => violations.join('\n'),
27
- };
28
- }
package/src/index.ts DELETED
@@ -1,35 +0,0 @@
1
- export * from './core/classes/classCheckExtendClass';
2
- export * from './core/classes/classCheckHaveMaxCyclomaticComplexity';
3
- export * from './core/classes/classCheckHaveModifier';
4
- export * from './core/classes/classCheckHaveNameMatchingFileName';
5
- export * from './core/classes/classCheckImplementInterface';
6
- export * from './core/classes/classCheckMatchNamePattern';
7
- export * from './core/classes/classCheckResideInFolder';
8
- export * from './core/classes/locateClasses';
9
- export * from './core/files/checkDependOnFilesInFolder';
10
- export * from './core/files/fileCheckBeFreeOfCycles';
11
- export * from './core/files/fileCheckHaveMaxCyclomaticComplexity';
12
- export * from './core/files/fileCheckHaveMaxExportedFunctions';
13
- export * from './core/files/fileCheckHaveMinMaintainabilityIndex';
14
- export * from './core/files/fileCheckMatchNamePattern';
15
- export * from './core/files/locateFiles';
16
- export * from './core/functions/functionCheckHaveExplicitReturnType';
17
- export * from './core/functions/functionCheckHaveMaxCyclomaticComplexity';
18
- export * from './core/functions/functionCheckHaveMinMaintainabilityIndex';
19
- export * from './core/functions/functionCheckHaveModifier';
20
- export * from './core/functions/functionCheckHaveNameMatchingFileName';
21
- export * from './core/functions/functionCheckMatchNamePattern';
22
- export * from './core/functions/locateFunctions';
23
- export * from './core/layers/checkLayeredArchitecture';
24
- export * from './core/layers/createLayeredArchitecture';
25
- export * from './core/layers/layer';
26
- export * from './core/layers/layerShouldNotBeAccessedByAnyLayer';
27
- export * from './core/layers/layerShouldOnlyBeAccessedBy';
28
- export { parseProject } from './core/project/parseProject';
29
- export * from './core/properties/locateProperties';
30
- export * from './core/properties/propertyCheckBeReadonly';
31
- export * from './core/slices/locateSlices';
32
- export * from './core/slices/sliceCheckBeFreeOfCycles';
33
- export * from './core/slices/sliceCheckHaveMaxDistanceFromMainSequence';
34
- export * from './core/types';
35
- export { setupMatchers } from './matchers';
@@ -1,331 +0,0 @@
1
- import { expect } from 'vitest';
2
- import { classCheckExtendClass } from '../core/classes/classCheckExtendClass';
3
- import { classCheckHaveMaxCyclomaticComplexity } from '../core/classes/classCheckHaveMaxCyclomaticComplexity';
4
- import { classCheckHaveModifier } from '../core/classes/classCheckHaveModifier';
5
- import { classCheckHaveNameMatchingFileName } from '../core/classes/classCheckHaveNameMatchingFileName';
6
- import { classCheckImplementInterface } from '../core/classes/classCheckImplementInterface';
7
- import { classCheckMatchNamePattern } from '../core/classes/classCheckMatchNamePattern';
8
- import { classCheckResideInFolder } from '../core/classes/classCheckResideInFolder';
9
- import { checkDependOnFilesInFolder } from '../core/files/checkDependOnFilesInFolder';
10
- import { fileCheckBeFreeOfCycles } from '../core/files/fileCheckBeFreeOfCycles';
11
- import { fileCheckHaveMaxCyclomaticComplexity } from '../core/files/fileCheckHaveMaxCyclomaticComplexity';
12
- import { fileCheckHaveMaxExportedFunctions } from '../core/files/fileCheckHaveMaxExportedFunctions';
13
- import { fileCheckHaveMinMaintainabilityIndex } from '../core/files/fileCheckHaveMinMaintainabilityIndex';
14
- import { fileCheckMatchNamePattern } from '../core/files/fileCheckMatchNamePattern';
15
- import { functionCheckHaveExplicitReturnType } from '../core/functions/functionCheckHaveExplicitReturnType';
16
- import { functionCheckHaveMaxCyclomaticComplexity } from '../core/functions/functionCheckHaveMaxCyclomaticComplexity';
17
- import { functionCheckHaveMinMaintainabilityIndex } from '../core/functions/functionCheckHaveMinMaintainabilityIndex';
18
- import { functionCheckHaveModifier } from '../core/functions/functionCheckHaveModifier';
19
- import { functionCheckHaveNameMatchingFileName } from '../core/functions/functionCheckHaveNameMatchingFileName';
20
- import { functionCheckMatchNamePattern } from '../core/functions/functionCheckMatchNamePattern';
21
- import { checkLayeredArchitecture } from '../core/layers/checkLayeredArchitecture';
22
-
23
- import { propertyCheckBeReadonly } from '../core/properties/propertyCheckBeReadonly';
24
-
25
- import { sliceCheckBeFreeOfCycles } from '../core/slices/sliceCheckBeFreeOfCycles';
26
- import { sliceCheckHaveMaxDistanceFromMainSequence } from '../core/slices/sliceCheckHaveMaxDistanceFromMainSequence';
27
- import type { LocatorData, RuleResult } from '../core/types';
28
-
29
- export function setupMatchers() {
30
- expect.extend({
31
- // biome-ignore lint/suspicious/noExplicitAny: Matcher signature
32
- toPass(received: any) {
33
- let result: RuleResult;
34
-
35
- if (received?.data && received.data.type === 'LayeredArchitecture') {
36
- result = checkLayeredArchitecture(received.data);
37
- } else {
38
- result = received as RuleResult;
39
- }
40
-
41
- const { pass, message } = result;
42
- return {
43
- pass: this.isNot ? !pass : pass,
44
- message: pass ? () => 'Expected rule not to pass' : () => message(),
45
- };
46
- },
47
-
48
- toResideInFolder(received: LocatorData, folder: string) {
49
- let result: RuleResult;
50
- if (received.type === 'ClassLocator') {
51
- result = classCheckResideInFolder(received, folder, this.isNot);
52
- } else {
53
- throw new Error(
54
- `toResideInFolder matcher does not support ${received.type}`,
55
- );
56
- }
57
- return {
58
- pass: this.isNot ? !result.pass : result.pass,
59
- message: result.message,
60
- };
61
- },
62
-
63
- toHaveModifier(received: LocatorData, modifier: string) {
64
- let result: RuleResult;
65
- if (received.type === 'ClassLocator') {
66
- result = classCheckHaveModifier(received, modifier, this.isNot);
67
- } else if (received.type === 'FunctionLocator') {
68
- result = functionCheckHaveModifier(received, modifier, this.isNot);
69
- } else {
70
- throw new Error(
71
- `toHaveModifier matcher does not support ${received.type}`,
72
- );
73
- }
74
- return {
75
- pass: this.isNot ? !result.pass : result.pass,
76
- message: result.message,
77
- };
78
- },
79
-
80
- toExtendClass(received: LocatorData, className: string) {
81
- let result: RuleResult;
82
- if (received.type === 'ClassLocator') {
83
- result = classCheckExtendClass(received, className, this.isNot);
84
- } else {
85
- throw new Error(
86
- `toExtendClass matcher does not support ${received.type}`,
87
- );
88
- }
89
- return {
90
- pass: this.isNot ? !result.pass : result.pass,
91
- message: result.message,
92
- };
93
- },
94
-
95
- toImplementInterface(received: LocatorData, interfaceName: string) {
96
- let result: RuleResult;
97
- if (received.type === 'ClassLocator') {
98
- result = classCheckImplementInterface(
99
- received,
100
- interfaceName,
101
- this.isNot,
102
- );
103
- } else {
104
- throw new Error(
105
- `toImplementInterface matcher does not support ${received.type}`,
106
- );
107
- }
108
- return {
109
- pass: this.isNot ? !result.pass : result.pass,
110
- message: result.message,
111
- };
112
- },
113
-
114
- toHaveExplicitReturnType(received: LocatorData) {
115
- let result: RuleResult;
116
- if (received.type === 'FunctionLocator') {
117
- result = functionCheckHaveExplicitReturnType(received, this.isNot);
118
- } else {
119
- throw new Error(
120
- `toHaveExplicitReturnType matcher does not support ${received.type}`,
121
- );
122
- }
123
- return {
124
- pass: this.isNot ? !result.pass : result.pass,
125
- message: result.message,
126
- };
127
- },
128
-
129
- toBeReadonly(received: LocatorData) {
130
- let result: RuleResult;
131
- if (received.type === 'PropertyLocator') {
132
- result = propertyCheckBeReadonly(received, this.isNot);
133
- } else {
134
- throw new Error(
135
- `toBeReadonly matcher does not support ${received.type}`,
136
- );
137
- }
138
- return {
139
- pass: this.isNot ? !result.pass : result.pass,
140
- message: result.message,
141
- };
142
- },
143
-
144
- toDependOnFilesInFolder(received: LocatorData, folder: string) {
145
- let result: RuleResult;
146
- if (received.type === 'FileLocator') {
147
- result = checkDependOnFilesInFolder(received, folder, this.isNot);
148
- } else {
149
- throw new Error(
150
- `toDependOnFilesInFolder matcher does not support ${received.type}`,
151
- );
152
- }
153
- return {
154
- pass: this.isNot ? !result.pass : result.pass,
155
- message: result.message,
156
- };
157
- },
158
-
159
- toBeFreeOfCycles(received: LocatorData) {
160
- let result: RuleResult;
161
- if (received.type === 'FileLocator') {
162
- result = fileCheckBeFreeOfCycles(received, this.isNot);
163
- } else if (received.type === 'SliceLocator') {
164
- result = sliceCheckBeFreeOfCycles(received, this.isNot);
165
- } else {
166
- throw new Error(
167
- `toBeFreeOfCycles matcher does not support ${received.type}`,
168
- );
169
- }
170
- return {
171
- pass: this.isNot ? !result.pass : result.pass,
172
- message: result.message,
173
- };
174
- },
175
-
176
- toMatchNamePattern(received: LocatorData, pattern: string | RegExp) {
177
- let result: RuleResult;
178
- if (received.type === 'FileLocator') {
179
- result = fileCheckMatchNamePattern(received, pattern, this.isNot);
180
- } else if (received.type === 'ClassLocator') {
181
- result = classCheckMatchNamePattern(received, pattern, this.isNot);
182
- } else if (received.type === 'FunctionLocator') {
183
- result = functionCheckMatchNamePattern(received, pattern, this.isNot);
184
- } else {
185
- throw new Error(
186
- `toMatchNamePattern matcher does not support ${received.type}`,
187
- );
188
- }
189
- return {
190
- pass: this.isNot ? !result.pass : result.pass,
191
- message: result.message,
192
- };
193
- },
194
-
195
- toHaveMaxCyclomaticComplexity(received: LocatorData, max: number) {
196
- let result: RuleResult;
197
- if (received.type === 'FileLocator') {
198
- result = fileCheckHaveMaxCyclomaticComplexity(
199
- received,
200
- max,
201
- this.isNot,
202
- );
203
- } else if (received.type === 'ClassLocator') {
204
- result = classCheckHaveMaxCyclomaticComplexity(
205
- received,
206
- max,
207
- this.isNot,
208
- );
209
- } else if (received.type === 'FunctionLocator') {
210
- result = functionCheckHaveMaxCyclomaticComplexity(
211
- received,
212
- max,
213
- this.isNot,
214
- );
215
- } else {
216
- throw new Error(
217
- `toHaveMaxCyclomaticComplexity matcher does not support ${received.type}`,
218
- );
219
- }
220
- return {
221
- pass: this.isNot ? !result.pass : result.pass,
222
- message: result.message,
223
- };
224
- },
225
-
226
- toHaveMinMaintainabilityIndex(received: LocatorData, min: number) {
227
- let result: RuleResult;
228
- if (received.type === 'FileLocator') {
229
- result = fileCheckHaveMinMaintainabilityIndex(
230
- received,
231
- min,
232
- this.isNot,
233
- );
234
- } else if (received.type === 'FunctionLocator') {
235
- result = functionCheckHaveMinMaintainabilityIndex(
236
- received,
237
- min,
238
- this.isNot,
239
- );
240
- } else {
241
- throw new Error(
242
- `toHaveMinMaintainabilityIndex matcher does not support ${received.type}`,
243
- );
244
- }
245
- return {
246
- pass: this.isNot ? !result.pass : result.pass,
247
- message: result.message,
248
- };
249
- },
250
-
251
- toHaveMaxDistanceFromMainSequence(received: LocatorData, max: number) {
252
- let result: RuleResult;
253
- if (received.type === 'SliceLocator') {
254
- result = sliceCheckHaveMaxDistanceFromMainSequence(
255
- received,
256
- max,
257
- this.isNot,
258
- );
259
- } else {
260
- throw new Error(
261
- `toHaveMaxDistanceFromMainSequence matcher does not support ${received.type}`,
262
- );
263
- }
264
- return {
265
- pass: this.isNot ? !result.pass : result.pass,
266
- message: result.message,
267
- };
268
- },
269
-
270
- toHaveNameMatchingFileName(received: LocatorData) {
271
- let result: RuleResult;
272
- if (received.type === 'FunctionLocator') {
273
- result = functionCheckHaveNameMatchingFileName(received, this.isNot);
274
- } else if (received.type === 'ClassLocator') {
275
- result = classCheckHaveNameMatchingFileName(received, this.isNot);
276
- } else {
277
- throw new Error(
278
- `toHaveNameMatchingFileName matcher does not support ${received.type}`,
279
- );
280
- }
281
- return {
282
- pass: this.isNot ? !result.pass : result.pass,
283
- message: result.message,
284
- };
285
- },
286
-
287
- toHaveMaxExportedFunctions(received: LocatorData, max: number) {
288
- let result: RuleResult;
289
- if (received.type === 'FileLocator') {
290
- result = fileCheckHaveMaxExportedFunctions(received, max, this.isNot);
291
- } else {
292
- throw new Error(
293
- `toHaveMaxExportedFunctions matcher does not support ${received.type}`,
294
- );
295
- }
296
- return {
297
- pass: this.isNot ? !result.pass : result.pass,
298
- message: result.message,
299
- };
300
- },
301
- });
302
- }
303
-
304
- declare module 'vitest' {
305
- // biome-ignore lint/suspicious/noExplicitAny: Matcher signature
306
- interface Assertion<T = any> {
307
- toPass(): void;
308
- toResideInFolder(folder: string): void;
309
- toHaveModifier(
310
- modifier:
311
- | 'export'
312
- | 'default'
313
- | 'abstract'
314
- | 'async'
315
- | 'private'
316
- | 'public',
317
- ): void;
318
- toExtendClass(className: string): void;
319
- toImplementInterface(interfaceName: string): void;
320
- toHaveExplicitReturnType(): void;
321
- toBeReadonly(): void;
322
- toDependOnFilesInFolder(folder: string): void;
323
- toBeFreeOfCycles(): void;
324
- toMatchNamePattern(pattern: string | RegExp): void;
325
- toHaveMaxCyclomaticComplexity(max: number): void;
326
- toHaveMinMaintainabilityIndex(min: number): void;
327
- toHaveMaxDistanceFromMainSequence(max: number): void;
328
- toHaveNameMatchingFileName(): void;
329
- toHaveMaxExportedFunctions(max: number): void;
330
- }
331
- }