pumuki 6.3.257 → 6.3.259
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,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [6.3.259] - 2026-05-14
|
|
4
|
+
|
|
5
|
+
- iOS: `skills.ios.prefer-swift-testing` now emits actionable AST-style evidence for modernizable `XCTestCase` suites, including exact lines, primary/related nodes and native Swift Testing `import Testing`/`@Suite`/`@Test` remediation.
|
|
6
|
+
|
|
7
|
+
## [6.3.258] - 2026-05-14
|
|
8
|
+
|
|
9
|
+
- iOS: `skills.ios.no-xctunwrap` now emits actionable AST-style evidence for legacy `XCTUnwrap` calls, including exact lines, primary/related nodes and native Swift Testing `#require` remediation.
|
|
10
|
+
|
|
3
11
|
## [6.3.257] - 2026-05-14
|
|
4
12
|
|
|
5
13
|
- iOS: `skills.ios.no-xctassert` now emits actionable AST-style evidence for XCTest assertion calls, including exact lines, primary/related nodes and native Swift Testing `#expect` remediation.
|
|
@@ -6,11 +6,13 @@ import {
|
|
|
6
6
|
findSwiftOpenClosedSwitchMatch,
|
|
7
7
|
findSwiftConcreteDependencyDipMatch,
|
|
8
8
|
findSwiftPresentationSrpMatch,
|
|
9
|
+
collectSwiftModernizableXCTestSuiteLines,
|
|
9
10
|
collectSwiftLegacyExpectationDescriptionLines,
|
|
10
11
|
collectSwiftMixedTestingFrameworkLines,
|
|
11
12
|
collectSwiftQuickNimbleLines,
|
|
12
13
|
collectSwiftWaitForExpectationsLines,
|
|
13
14
|
collectSwiftXCTestAssertionLines,
|
|
15
|
+
collectSwiftXCTUnwrapLines,
|
|
14
16
|
hasSwiftAnyViewUsage,
|
|
15
17
|
hasSwiftAsyncWithoutAwaitUsage,
|
|
16
18
|
hasSwiftCallbackStyleSignature,
|
|
@@ -1623,6 +1625,8 @@ final class LoginUITests: XCTestCase {
|
|
|
1623
1625
|
assert.equal(hasSwiftModernizableXCTestSuiteUsage(legacySuite), true);
|
|
1624
1626
|
assert.equal(hasSwiftModernizableXCTestSuiteUsage(mixedSuite), false);
|
|
1625
1627
|
assert.equal(hasSwiftModernizableXCTestSuiteUsage(uiSuite), false);
|
|
1628
|
+
assert.deepEqual(collectSwiftModernizableXCTestSuiteLines(legacySuite), [2, 4, 5]);
|
|
1629
|
+
assert.deepEqual(collectSwiftModernizableXCTestSuiteLines(mixedSuite), []);
|
|
1626
1630
|
});
|
|
1627
1631
|
|
|
1628
1632
|
test('hasSwiftMixedTestingFrameworksUsage detecta mezcla XCTestCase y Testing/@Test', () => {
|
|
@@ -1755,6 +1759,8 @@ let text = "XCTUnwrap(optionalValue)"
|
|
|
1755
1759
|
|
|
1756
1760
|
assert.equal(hasSwiftXCTUnwrapUsage(source), true);
|
|
1757
1761
|
assert.equal(hasSwiftXCTUnwrapUsage(ignored), false);
|
|
1762
|
+
assert.deepEqual(collectSwiftXCTUnwrapLines(source), [2]);
|
|
1763
|
+
assert.deepEqual(collectSwiftXCTUnwrapLines(ignored), []);
|
|
1758
1764
|
});
|
|
1759
1765
|
|
|
1760
1766
|
test('hasSwiftWaitForExpectationsUsage detecta waits legacy y excluye await fulfillment', () => {
|
|
@@ -1328,6 +1328,18 @@ export const hasSwiftModernizableXCTestSuiteUsage = (source: string): boolean =>
|
|
|
1328
1328
|
return true;
|
|
1329
1329
|
};
|
|
1330
1330
|
|
|
1331
|
+
export const collectSwiftModernizableXCTestSuiteLines = (source: string): readonly number[] => {
|
|
1332
|
+
if (!hasSwiftModernizableXCTestSuiteUsage(source)) {
|
|
1333
|
+
return [];
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
return sortedUniqueLines([
|
|
1337
|
+
...collectSwiftRegexLines(source, /\bimport\s+XCTest\b/),
|
|
1338
|
+
...collectSwiftRegexLines(source, /\bclass\s+[A-Za-z_][A-Za-z0-9_]*\s*:\s*XCTestCase\b/),
|
|
1339
|
+
...collectSwiftRegexLines(source, /^\s*(?:override\s+)?func\s+test[A-Za-z0-9_]*\s*\(/),
|
|
1340
|
+
]);
|
|
1341
|
+
};
|
|
1342
|
+
|
|
1331
1343
|
export const hasSwiftMixedTestingFrameworksUsage = (source: string): boolean => {
|
|
1332
1344
|
if (!hasSwiftXCTestImportUsage(source) || !hasSwiftXCTestCaseSubclassUsage(source)) {
|
|
1333
1345
|
return false;
|
|
@@ -1391,6 +1403,10 @@ export const hasSwiftXCTUnwrapUsage = (source: string): boolean => {
|
|
|
1391
1403
|
return collectSwiftRegexLines(source, /\bXCTUnwrap\s*\(/).length > 0;
|
|
1392
1404
|
};
|
|
1393
1405
|
|
|
1406
|
+
export const collectSwiftXCTUnwrapLines = (source: string): readonly number[] => {
|
|
1407
|
+
return sortedUniqueLines(collectSwiftRegexLines(source, /\bXCTUnwrap\s*\(/));
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1394
1410
|
const hasSwiftAwaitFulfillmentUsage = (source: string): boolean => {
|
|
1395
1411
|
return hasSwiftSanitizedRegexMatch(source, /\bawait\s+fulfillment\s*\(\s*of\s*:/);
|
|
1396
1412
|
};
|
|
@@ -717,9 +717,9 @@ const textDetectorRegistry: ReadonlyArray<TextDetectorRegistryEntry> = [
|
|
|
717
717
|
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftLegacyOnChangeUsage, ruleId: 'heuristics.ios.legacy-onchange.ast', code: 'HEURISTICS_IOS_LEGACY_ONCHANGE_AST', message: 'AST heuristic detected legacy onChange usage where modern overloads may be preferred.' },
|
|
718
718
|
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftUIScreenMainBoundsUsage, ruleId: 'heuristics.ios.uiscreen-main-bounds.ast', code: 'HEURISTICS_IOS_UISCREEN_MAIN_BOUNDS_AST', message: 'AST heuristic detected UIScreen.main.bounds usage.' },
|
|
719
719
|
{ platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftLegacyXCTestImportUsage, ruleId: 'heuristics.ios.testing.xctest-import.ast', code: 'HEURISTICS_IOS_TESTING_XCTEST_IMPORT_AST', message: 'AST heuristic detected XCTest-only test usage where Swift Testing may be preferred.' },
|
|
720
|
-
{ platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftModernizableXCTestSuiteUsage, ruleId: 'heuristics.ios.testing.xctest-suite-modernizable.ast', code: 'HEURISTICS_IOS_TESTING_XCTEST_SUITE_MODERNIZABLE_AST', message: 'AST heuristic detected XCTestCase/test... suite
|
|
720
|
+
{ platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftModernizableXCTestSuiteUsage, locateLines: TextIOS.collectSwiftModernizableXCTestSuiteLines, primaryNode: (lines) => ({ kind: 'class', name: 'modernizable XCTestCase test suite', lines }), relatedNodes: (lines) => [{ kind: 'class', name: 'replacement: Swift Testing @Suite/@Test suite', lines }], why: 'XCTestCase suites with test... methods keep unit tests on the legacy XCTest lifecycle even when the file can be expressed as a native Swift Testing suite.', impact: 'New or modernizable tests drift away from the preferred Swift Testing contract, making suite migration, diagnostics and rule enforcement harder to audit.', expected_fix: 'Replace import XCTest and XCTestCase/test... unit suites with import Testing, @Suite where useful and @Test functions. Keep XCTestCase only for explicit UI, performance or brownfield compatibility cases.', ruleId: 'heuristics.ios.testing.xctest-suite-modernizable.ast', code: 'HEURISTICS_IOS_TESTING_XCTEST_SUITE_MODERNIZABLE_AST', message: 'AST heuristic detected modernizable XCTestCase/test... suite; use native Swift Testing where applicable.' },
|
|
721
721
|
{ platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftXCTestAssertionUsage, locateLines: TextIOS.collectSwiftXCTestAssertionLines, primaryNode: (lines) => ({ kind: 'call', name: 'legacy XCTest assertion call', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: #expect(...)', lines }], why: 'XCTAssert* and XCTFail keep modern unit tests tied to XCTest assertion APIs even when Swift Testing can express the same expectation natively.', impact: 'Assertion style drifts across the test suite and makes migration to Swift Testing harder to audit because failures use mixed vocabularies and diagnostics.', expected_fix: 'Replace XCTAssert* and XCTFail with Swift Testing #expect(...) or a thrown test failure pattern when the target already supports Swift Testing. Keep XCTest assertions only for explicit legacy, UI or performance test compatibility.', ruleId: 'heuristics.ios.testing.xctassert.ast', code: 'HEURISTICS_IOS_TESTING_XCTASSERT_AST', message: 'AST heuristic detected legacy XCTest assertion calls; use native Swift Testing #expect where applicable.' },
|
|
722
|
-
{ platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftXCTUnwrapUsage, ruleId: 'heuristics.ios.testing.xctunwrap.ast', code: 'HEURISTICS_IOS_TESTING_XCTUNWRAP_AST', message: 'AST heuristic detected XCTUnwrap
|
|
722
|
+
{ platform: 'ios', pathCheck: isIOSSwiftTestPath, excludePaths: [], detect: TextIOS.hasSwiftXCTUnwrapUsage, locateLines: TextIOS.collectSwiftXCTUnwrapLines, primaryNode: (lines) => ({ kind: 'call', name: 'legacy XCTest unwrap call', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: #require(...)', lines }], why: 'XCTUnwrap keeps optional unwrapping tied to XCTest even when Swift Testing can express required values natively.', impact: 'Tests retain mixed assertion vocabulary and weaker migration traceability because required optional values are not represented through Swift Testing diagnostics.', expected_fix: 'Replace try XCTUnwrap(optionalValue) with try #require(optionalValue) when the target already supports Swift Testing. Keep XCTUnwrap only for explicit XCTest compatibility, UI or performance test cases.', ruleId: 'heuristics.ios.testing.xctunwrap.ast', code: 'HEURISTICS_IOS_TESTING_XCTUNWRAP_AST', message: 'AST heuristic detected legacy XCTUnwrap calls; use native Swift Testing #require where applicable.' },
|
|
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.' },
|
|
@@ -6,6 +6,14 @@ 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.259)
|
|
10
|
+
|
|
11
|
+
- Published `pumuki@6.3.259` with AST-style line/node evidence for `skills.ios.prefer-swift-testing`, making modernizable `XCTestCase` suites remediable through native Swift Testing `import Testing`, `@Suite` and `@Test`.
|
|
12
|
+
|
|
13
|
+
### 2026-05-14 (v6.3.258)
|
|
14
|
+
|
|
15
|
+
- Published `pumuki@6.3.258` with AST-style line/node evidence for `skills.ios.no-xctunwrap`, making legacy `XCTUnwrap` calls remediable through Swift Testing `#require`.
|
|
16
|
+
|
|
9
17
|
### 2026-05-14 (v6.3.257)
|
|
10
18
|
|
|
11
19
|
- Published `pumuki@6.3.257` with AST-style line/node evidence for `skills.ios.no-xctassert`, making legacy `XCTAssert*`/`XCTFail` assertions remediable through Swift Testing `#expect`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.259",
|
|
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": {
|