pumuki 6.3.158 → 6.3.160

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.
@@ -659,40 +659,70 @@ let text = "XCTUnwrap(optionalValue)"
659
659
  });
660
660
 
661
661
  test('hasSwiftWaitForExpectationsUsage detecta waits legacy y excluye await fulfillment', () => {
662
- const legacyWait = `
662
+ const legacyAsyncWait = `
663
+ func testLegacyAsync() async {
663
664
  let expectation = expectation(description: "Done")
664
665
  wait(for: [expectation], timeout: 1)
665
666
  waitForExpectations(timeout: 1)
667
+ }
668
+ `;
669
+ const legacySyncWait = `
670
+ func testLegacySync() {
671
+ let expectation = expectation(description: "Done")
672
+ wait(for: [expectation], timeout: 1)
673
+ }
666
674
  `;
667
675
  const modernWait = `
676
+ func testModernAsync() async {
668
677
  let expectation = expectation(description: "Done")
669
678
  await fulfillment(of: [expectation], timeout: 1)
679
+ }
670
680
  `;
671
681
 
672
- assert.equal(hasSwiftWaitForExpectationsUsage(legacyWait), true);
682
+ assert.equal(hasSwiftWaitForExpectationsUsage(legacyAsyncWait), true);
683
+ assert.equal(hasSwiftWaitForExpectationsUsage(legacySyncWait), false);
673
684
  assert.equal(hasSwiftWaitForExpectationsUsage(modernWait), false);
674
685
  });
675
686
 
676
- test('hasSwiftLegacyExpectationDescriptionUsage detecta expectation(description:) sin flujo moderno', () => {
677
- const legacyExpectation = `
687
+ test('hasSwiftLegacyExpectationDescriptionUsage detecta expectation(description:) en tests async sin flujo moderno', () => {
688
+ const legacyAsyncExpectation = `
689
+ func testLegacyAsync() async {
678
690
  let expectation = expectation(description: "Done")
679
691
  doWork { expectation.fulfill() }
680
- waitForExpectations(timeout: 1)
692
+ }
681
693
  `;
682
- const modernExpectation = `
694
+ const legacySyncExpectation = `
695
+ func testLegacySync() {
696
+ let expectation = expectation(description: "Done")
697
+ doWork { expectation.fulfill() }
698
+ }
699
+ `;
700
+ const modernAsyncExpectation = `
701
+ func testModernAsync() async {
683
702
  let expectation = expectation(description: "Done")
684
703
  doWork { expectation.fulfill() }
685
704
  await fulfillment(of: [expectation], timeout: 1)
705
+ }
686
706
  `;
687
- const confirmationOnly = `
707
+ const confirmationFlow = `
708
+ func testConfirmation() async {
688
709
  await confirmation("Done") { confirm in
689
710
  await doWork { confirm() }
690
711
  }
712
+ }
713
+ `;
714
+ const commentedExpectation = `
715
+ func testModernAsync() async {
716
+ // let expectation = expectation(description: "Done")
717
+ await confirmation("Done") { confirm in confirm() }
718
+ }
691
719
  `;
692
720
 
693
- assert.equal(hasSwiftLegacyExpectationDescriptionUsage(legacyExpectation), true);
694
- assert.equal(hasSwiftLegacyExpectationDescriptionUsage(modernExpectation), false);
695
- assert.equal(hasSwiftLegacyExpectationDescriptionUsage(confirmationOnly), false);
721
+ assert.equal(hasSwiftLegacyExpectationDescriptionUsage(legacyAsyncExpectation), true);
722
+ assert.equal(hasSwiftLegacyExpectationDescriptionUsage(legacySyncExpectation), false);
723
+ assert.equal(hasSwiftLegacyExpectationDescriptionUsage(modernAsyncExpectation), false);
724
+ assert.equal(hasSwiftLegacyExpectationDescriptionUsage(confirmationFlow), false);
725
+ assert.equal(hasSwiftLegacyExpectationDescriptionUsage(commentedExpectation), false);
696
726
  });
697
727
 
698
728
  test('hasSwiftNSManagedObjectBoundaryUsage detecta boundaries con NSManagedObject y excluye IDs o subclases', () => {
@@ -100,6 +100,63 @@ const hasSwiftSanitizedRegexMatch = (source: string, regex: RegExp): boolean =>
100
100
  return regex.test(sanitizeSwiftSourceForMultilineRegex(source));
101
101
  };
102
102
 
103
+ type SwiftFunctionDeclaration = {
104
+ signature: string;
105
+ body: string;
106
+ };
107
+
108
+ const collectSwiftFunctionDeclarations = (source: string): readonly SwiftFunctionDeclaration[] => {
109
+ const lines = source.split(/\r?\n/);
110
+ const functions: SwiftFunctionDeclaration[] = [];
111
+
112
+ for (let index = 0; index < lines.length; index += 1) {
113
+ const firstLine = stripSwiftLineForSemanticScan(lines[index] ?? '');
114
+ if (!/\bfunc\b/.test(firstLine)) {
115
+ continue;
116
+ }
117
+
118
+ const signatureLines: string[] = [];
119
+ let cursor = index;
120
+ let openingLineIndex = -1;
121
+ for (; cursor < lines.length && cursor < index + 24; cursor += 1) {
122
+ const line = stripSwiftLineForSemanticScan(lines[cursor] ?? '');
123
+ signatureLines.push(line);
124
+ if (line.includes('{')) {
125
+ openingLineIndex = cursor;
126
+ break;
127
+ }
128
+ if (line.includes('}')) {
129
+ break;
130
+ }
131
+ }
132
+
133
+ if (openingLineIndex < 0) {
134
+ continue;
135
+ }
136
+
137
+ const bodyLines: string[] = [];
138
+ let braceDepth = 0;
139
+ for (let bodyCursor = openingLineIndex; bodyCursor < lines.length; bodyCursor += 1) {
140
+ const line = stripSwiftLineForSemanticScan(lines[bodyCursor] ?? '');
141
+ braceDepth += countTokenOccurrences(line, '{');
142
+ braceDepth -= countTokenOccurrences(line, '}');
143
+ bodyLines.push(line);
144
+ if (bodyCursor > openingLineIndex && braceDepth <= 0) {
145
+ cursor = bodyCursor;
146
+ break;
147
+ }
148
+ }
149
+
150
+ functions.push({
151
+ signature: signatureLines.join('\n'),
152
+ body: bodyLines.join('\n'),
153
+ });
154
+ index = cursor;
155
+ }
156
+
157
+ return functions;
158
+ };
159
+
103
160
  const hasSwiftUiModernizationSnapshotMatch = (source: string, entryId: string): boolean => {
104
161
  const entry = getIosSwiftUiModernizationEntry(entryId);
105
162
  if (!entry) {
@@ -855,27 +912,26 @@ const hasSwiftConfirmationUsage = (source: string): boolean => {
855
912
  };
856
913
 
857
914
  export const hasSwiftWaitForExpectationsUsage = (source: string): boolean => {
858
- return hasSwiftSanitizedRegexMatch(
859
- source,
860
- /\bwait\s*\(\s*for\s*:|\bwaitForExpectations\s*\(/
861
- );
915
+ const legacyWaitPattern = /\bwait\s*\(\s*for\s*:|\bwaitForExpectations\s*\(/;
916
+ return collectSwiftFunctionDeclarations(source).some((declaration) => {
917
+ if (!/\basync\b/.test(declaration.signature)) {
918
+ return false;
919
+ }
920
+ legacyWaitPattern.lastIndex = 0;
921
+ return legacyWaitPattern.test(declaration.body);
922
+ });
862
923
  };
863
924
 
864
925
  export const hasSwiftLegacyExpectationDescriptionUsage = (source: string): boolean => {
865
- const hasLegacyExpectation = collectSwiftRegexLines(
866
- source,
867
- /\bexpectation\s*\(\s*description\s*:/
868
- ).length > 0;
869
-
870
- if (!hasLegacyExpectation) {
871
- return false;
872
- }
873
-
874
- if (hasSwiftAwaitFulfillmentUsage(source) || hasSwiftConfirmationUsage(source)) {
875
- return false;
876
- }
877
-
878
- return true;
926
+ return collectSwiftFunctionDeclarations(source).some((declaration) => {
927
+ if (!/\basync\b/.test(declaration.signature)) {
928
+ return false;
929
+ }
930
+ if (!hasSwiftSanitizedRegexMatch(declaration.body, /\bexpectation\s*\(\s*description\s*:/)) {
931
+ return false;
932
+ }
933
+ return !hasSwiftAwaitFulfillmentUsage(declaration.body) && !hasSwiftConfirmationUsage(declaration.body);
934
+ });
879
935
  };
880
936
 
881
937
  export const hasSwiftNSManagedObjectBoundaryUsage = (source: string): boolean => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.158",
3
+ "version": "6.3.160",
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": {