pumuki-ast-hooks 5.6.11 → 5.6.13

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.
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki-ast-hooks",
3
- "version": "5.6.11",
3
+ "version": "5.6.13",
4
4
  "description": "Enterprise-grade AST Intelligence System with multi-platform support (iOS, Android, Backend, Frontend) and Feature-First + DDD + Clean Architecture enforcement. Includes dynamic violations API for intelligent querying.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -116,6 +116,7 @@
116
116
  "skills/",
117
117
  "hooks/",
118
118
  "docs/",
119
+ "assets/",
119
120
  "index.js",
120
121
  "README.md",
121
122
  "LICENSE"
@@ -498,3 +498,11 @@
498
498
  {"timestamp":1768158514231,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
499
499
  {"timestamp":1768158514231,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
500
500
  {"timestamp":1768158514232,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
501
+ {"timestamp":1768158974401,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
502
+ {"timestamp":1768158974401,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
503
+ {"timestamp":1768158974401,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
504
+ {"timestamp":1768158974402,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
505
+ {"timestamp":1768162663136,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
506
+ {"timestamp":1768162663136,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
507
+ {"timestamp":1768162663136,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
508
+ {"timestamp":1768162663136,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
@@ -2,6 +2,7 @@ jest.mock('../BDDTDDWorkflowRules', () => ({
2
2
  BDDTDDWorkflowRules: jest.fn().mockImplementation(() => ({ analyze: jest.fn() }))
3
3
  }));
4
4
 
5
+ const fs = require('fs');
5
6
  const { Project } = require('../../ast-core');
6
7
  const { runCommonIntelligence } = require('../ast-common');
7
8
 
@@ -28,6 +29,64 @@ describe('AST Common Module', () => {
28
29
  expect(findings.some(f => f.ruleId === 'common.testing.missing_makesut')).toBe(false);
29
30
  expect(findings.some(f => f.ruleId === 'common.testing.missing_track_for_memory_leaks')).toBe(false);
30
31
  });
32
+
33
+ it('does not report false positives for Swift test files when getFullText is empty (fallback to disk)', () => {
34
+ const project = new Project({
35
+ useInMemoryFileSystem: true,
36
+ skipAddingFilesFromTsConfig: true,
37
+ });
38
+
39
+ const swiftPath = '/tmp/FooTests.spec.swift';
40
+ const swiftContent = [
41
+ 'import XCTest',
42
+ 'final class FooTests: XCTestCase {',
43
+ ' private func makeSUT() -> Foo { Foo() }',
44
+ ' func test_example() {',
45
+ ' let sut = makeSUT()',
46
+ ' trackForMemoryLeaks(sut, testCase: self, file: #file, line: #line)',
47
+ ' }',
48
+ '}',
49
+ ].join('\n');
50
+
51
+ const sf = project.createSourceFile(swiftPath, swiftContent);
52
+ jest.spyOn(sf, 'getFullText').mockReturnValue('');
53
+ jest.spyOn(fs, 'readFileSync').mockReturnValue(swiftContent);
54
+
55
+ const findings = [];
56
+ runCommonIntelligence(project, findings);
57
+
58
+ expect(findings.some(f => f.ruleId === 'common.testing.missing_makesut')).toBe(false);
59
+ expect(findings.some(f => f.ruleId === 'common.testing.missing_track_for_memory_leaks')).toBe(false);
60
+ });
61
+
62
+ it('does not report false positives for Swift test files when getFullText is non-empty but incomplete (prefer disk)', () => {
63
+ const project = new Project({
64
+ useInMemoryFileSystem: true,
65
+ skipAddingFilesFromTsConfig: true,
66
+ });
67
+
68
+ const swiftPath = '/tmp/DomainAPIEndpointTests.spec.swift';
69
+ const swiftContent = [
70
+ 'import XCTest',
71
+ 'final class DomainAPIEndpointTests: XCTestCase {',
72
+ ' private func makeSUT() -> Foo { Foo() }',
73
+ ' func test_example() {',
74
+ ' let sut = makeSUT()',
75
+ ' trackForMemoryLeaks(sut, testCase: self, file: #file, line: #line)',
76
+ ' }',
77
+ '}',
78
+ ].join('\n');
79
+
80
+ const sf = project.createSourceFile(swiftPath, swiftContent);
81
+ jest.spyOn(sf, 'getFullText').mockReturnValue('import XCTest\nfinal class DomainAPIEndpointTests: XCTestCase {}');
82
+ jest.spyOn(fs, 'readFileSync').mockReturnValue(swiftContent);
83
+
84
+ const findings = [];
85
+ runCommonIntelligence(project, findings);
86
+
87
+ expect(findings.some(f => f.ruleId === 'common.testing.missing_makesut')).toBe(false);
88
+ expect(findings.some(f => f.ruleId === 'common.testing.missing_track_for_memory_leaks')).toBe(false);
89
+ });
31
90
  });
32
91
 
33
92
  describe('exports', () => {
@@ -1,4 +1,5 @@
1
1
  const path = require('path');
2
+ const fs = require('fs');
2
3
  const { pushFinding, SyntaxKind, platformOf, getRepoRoot } = require(path.join(__dirname, '../ast-core'));
3
4
  const { BDDTDDWorkflowRules } = require(path.join(__dirname, 'BDDTDDWorkflowRules'));
4
5
 
@@ -208,11 +209,24 @@ function runCommonIntelligence(project, findings) {
208
209
  if (/\/ast-(?:backend|frontend|android|ios|common|core|intelligence)\.js$/.test(filePath)) return;
209
210
 
210
211
  if (isTestFilePath(filePath)) {
211
- const content = sf.getFullText();
212
+ let content = sf.getFullText();
212
213
 
213
214
  const ext = path.extname(filePath).toLowerCase();
214
215
  const isSwiftOrKotlinTest = ext === '.swift' || ext === '.kt' || ext === '.kts';
215
216
 
217
+ if (isSwiftOrKotlinTest) {
218
+ try {
219
+ const diskContent = fs.readFileSync(filePath, 'utf8');
220
+ if (diskContent && diskContent.trim().length > 0) {
221
+ content = diskContent;
222
+ }
223
+ } catch (error) {
224
+ if (process.env.DEBUG) {
225
+ console.debug(`[ast-common] Failed to read test file content for ${filePath}: ${error.message}`);
226
+ }
227
+ }
228
+ }
229
+
216
230
  if (isSwiftOrKotlinTest) {
217
231
  if (!shouldSkipMakeSUTRule(filePath) && !hasMakeSUT(content)) {
218
232
  pushFinding(