pumuki 6.3.255 → 6.3.256

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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## [6.3.256] - 2026-05-14
4
+
5
+ - iOS: `skills.ios.guideline.ios.quick-nimble-prohibido-usar-swift-testing-nativo` now emits actionable AST-style evidence for Quick/Nimble legacy tests, including exact lines, primary/related nodes and native Swift Testing remediation.
6
+
3
7
  ## [6.3.255] - 2026-05-14
4
8
 
5
9
  - iOS: `skills.ios.no-mixed-testing-frameworks` now emits actionable AST-style evidence for files mixing `XCTestCase` with Swift Testing markers, including exact lines, primary/related nodes and a concrete split-or-migrate remediation.
@@ -8,6 +8,7 @@ import {
8
8
  findSwiftPresentationSrpMatch,
9
9
  collectSwiftLegacyExpectationDescriptionLines,
10
10
  collectSwiftMixedTestingFrameworkLines,
11
+ collectSwiftQuickNimbleLines,
11
12
  collectSwiftWaitForExpectationsLines,
12
13
  hasSwiftAnyViewUsage,
13
14
  hasSwiftAsyncWithoutAwaitUsage,
@@ -1693,6 +1694,40 @@ let text = "import Quick"
1693
1694
  assert.equal(hasSwiftQuickNimbleUsage(ignored), false);
1694
1695
  });
1695
1696
 
1697
+ test('collectSwiftQuickNimbleLines localiza nodos Quick/Nimble legacy', () => {
1698
+ const quickSpec = `
1699
+ import Quick
1700
+ import Nimble
1701
+
1702
+ final class LoginSpec: QuickSpec {
1703
+ override class func spec() {
1704
+ describe("login") {
1705
+ context("valid credentials") {
1706
+ it("opens the session") {
1707
+ expect(true).to(beTrue())
1708
+ }
1709
+ }
1710
+ }
1711
+ }
1712
+ }
1713
+ `;
1714
+ const swiftTesting = `
1715
+ import Testing
1716
+
1717
+ @Suite
1718
+ struct LoginTests {
1719
+ @Test func login() async {
1720
+ #expect(true)
1721
+ }
1722
+ }
1723
+ `;
1724
+
1725
+ assert.equal(hasSwiftQuickNimbleUsage(quickSpec), true);
1726
+ assert.deepEqual(collectSwiftQuickNimbleLines(quickSpec), [2, 3, 5, 7, 8, 9, 10]);
1727
+ assert.equal(hasSwiftQuickNimbleUsage(swiftTesting), false);
1728
+ assert.deepEqual(collectSwiftQuickNimbleLines(swiftTesting), []);
1729
+ });
1730
+
1696
1731
  test('hasSwiftXCTestAssertionUsage detecta XCTAssert y XCTFail reales', () => {
1697
1732
  const source = `
1698
1733
  XCTAssertEqual(value, expected)
@@ -1356,6 +1356,19 @@ export const hasSwiftQuickNimbleUsage = (source: string): boolean => {
1356
1356
  );
1357
1357
  };
1358
1358
 
1359
+ export const collectSwiftQuickNimbleLines = (source: string): readonly number[] => {
1360
+ if (!hasSwiftQuickNimbleUsage(source)) {
1361
+ return [];
1362
+ }
1363
+
1364
+ return sortedUniqueLines([
1365
+ ...collectSwiftRegexLines(source, /\bimport\s+(?:Quick|Nimble)\b/),
1366
+ ...collectSwiftRegexLines(source, /\bclass\s+[A-Za-z_][A-Za-z0-9_]*\s*:\s*QuickSpec\b/),
1367
+ ...collectSwiftRegexLines(source, /\b(?:describe|context|it)\s*\(/),
1368
+ ...collectSwiftRegexLines(source, /\bexpect\s*\(/),
1369
+ ]);
1370
+ };
1371
+
1359
1372
  export const hasSwiftXCTestAssertionUsage = (source: string): boolean => {
1360
1373
  return (
1361
1374
  collectSwiftRegexLines(source, /\bXCTAssert[A-Za-z0-9_]*\s*\(/).length > 0 ||
@@ -723,7 +723,7 @@ const textDetectorRegistry: ReadonlyArray<TextDetectorRegistryEntry> = [
723
723
  { platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftWaitForExpectationsUsage, locateLines: TextIOS.collectSwiftWaitForExpectationsLines, primaryNode: (lines) => ({ kind: 'call', name: 'legacy XCTest wait call', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: await fulfillment(of:timeout:)', lines }], why: 'Legacy XCTest wait APIs block the current test thread and hide async intent that Swift concurrency can express directly.', impact: 'Async tests become less deterministic, harder to cancel and easier to keep tied to XCTest-only migration paths.', expected_fix: 'Replace wait(for:timeout:), self.wait(for:timeout:) or waitForExpectations(timeout:) with await fulfillment(of:timeout:) when the test target supports async XCTest migration.', ruleId: 'heuristics.ios.testing.wait-for-expectations.ast', code: 'HEURISTICS_IOS_TESTING_WAIT_FOR_EXPECTATIONS_AST', message: 'AST heuristic detected wait(for:)/waitForExpectations usage where await fulfillment(of:) may be preferred.' },
724
724
  { platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftLegacyExpectationDescriptionUsage, locateLines: TextIOS.collectSwiftLegacyExpectationDescriptionLines, primaryNode: (lines) => ({ kind: 'call', name: 'legacy XCTest expectation(description:) call', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: await confirmation or awaited fulfillment flow', lines }], why: 'Legacy expectation(description:) scaffolding keeps async tests coupled to XCTest-style callbacks instead of expressing confirmation intent directly.', impact: 'Tests can remain harder to read and migrate because the assertion flow is split between expectation creation, callback fulfillment and a later wait.', expected_fix: 'Prefer await confirmation(...) for callback confirmation, or pair legacy expectations with await fulfillment(of:timeout:) when the target still requires XCTest compatibility.', ruleId: 'heuristics.ios.testing.legacy-expectation-description.ast', code: 'HEURISTICS_IOS_TESTING_LEGACY_EXPECTATION_DESCRIPTION_AST', message: 'AST heuristic detected expectation(description:) usage without modern fulfillment/confirmation flow.' },
725
725
  { platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftMixedTestingFrameworksUsage, locateLines: TextIOS.collectSwiftMixedTestingFrameworkLines, primaryNode: (lines) => ({ kind: 'class', name: 'mixed XCTestCase and Swift Testing suite', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: isolate XCTest compatibility from Swift Testing suites', lines }], why: 'Mixing XCTestCase and Swift Testing markers in the same file makes the test contract ambiguous and hides whether the target is legacy XCTest compatibility or modern Swift Testing.', impact: 'Migration work becomes harder to audit because one file can carry two lifecycle models, assertion styles and setup conventions at once.', expected_fix: 'Split XCTest compatibility tests and Swift Testing suites into separate files, or migrate the legacy XCTestCase suite fully to import Testing with @Suite/@Test and #expect/#require.', ruleId: 'heuristics.ios.testing.mixed-frameworks.ast', code: 'HEURISTICS_IOS_TESTING_MIXED_FRAMEWORKS_AST', message: 'AST heuristic detected XCTestCase and Swift Testing markers mixed in the same test file without explicit compatibility reason.' },
726
- { platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftQuickNimbleUsage, ruleId: 'heuristics.ios.testing.quick-nimble.ast', code: 'HEURISTICS_IOS_TESTING_QUICK_NIMBLE_AST', message: 'AST heuristic detected Quick/Nimble usage where native Swift Testing remains the preferred baseline.' },
726
+ { platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftQuickNimbleUsage, locateLines: TextIOS.collectSwiftQuickNimbleLines, primaryNode: (lines) => ({ kind: 'class', name: 'QuickSpec legacy test suite', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: Swift Testing @Suite/@Test with #expect/#require', lines }], why: 'Quick and Nimble introduce a third-party BDD lifecycle and matcher vocabulary that diverges from the native Swift Testing contract expected for new tests.', impact: 'New tests become harder to migrate, audit and run consistently because they depend on legacy DSL hooks instead of Swift Testing suites and assertions.', expected_fix: 'For new tests, replace QuickSpec/describe/context/it/expect with native Swift Testing @Suite/@Test and #expect/#require. Keep existing Quick/Nimble only as explicit brownfield legacy until migrated.', ruleId: 'heuristics.ios.testing.quick-nimble.ast', code: 'HEURISTICS_IOS_TESTING_QUICK_NIMBLE_AST', message: 'AST heuristic detected Quick/Nimble legacy test nodes; use native Swift Testing for new test code.' },
727
727
  { platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftNSManagedObjectBoundaryUsage, ruleId: 'heuristics.ios.core-data.nsmanagedobject-boundary.ast', code: 'HEURISTICS_IOS_CORE_DATA_NSMANAGEDOBJECT_BOUNDARY_AST', message: 'AST heuristic detected NSManagedObject in a shared boundary.' },
728
728
  { platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftNSManagedObjectAsyncBoundaryUsage, ruleId: 'heuristics.ios.core-data.nsmanagedobject-async-boundary.ast', code: 'HEURISTICS_IOS_CORE_DATA_NSMANAGEDOBJECT_ASYNC_BOUNDARY_AST', message: 'AST heuristic detected NSManagedObject in an async boundary.' },
729
729
  { platform: 'ios', pathCheck: isIOSApplicationOrPresentationPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftCoreDataLayerLeakUsage, ruleId: 'heuristics.ios.core-data.layer-leak.ast', code: 'HEURISTICS_IOS_CORE_DATA_LAYER_LEAK_AST', message: 'AST heuristic detected Core Data APIs leaking into application/presentation code.' },
@@ -6,6 +6,10 @@ This file keeps only the operational highlights and rollout notes that matter wh
6
6
 
7
7
  ## 2026-04 (CLI stability and macOS notifications)
8
8
 
9
+ ### 2026-05-14 (v6.3.256)
10
+
11
+ - Published `pumuki@6.3.256` with AST-style line/node evidence for the Quick/Nimble legacy iOS testing rule, preserving brownfield visibility while making native Swift Testing the actionable remediation for new test code.
12
+
9
13
  ### 2026-05-14 (v6.3.255)
10
14
 
11
15
  - Published `pumuki@6.3.255` with AST-style line/node evidence for `skills.ios.no-mixed-testing-frameworks`, closing the XCTestCase + Swift Testing mixed-suite parity gap with a remediable split/migrate contract.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.255",
3
+ "version": "6.3.256",
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": {