@mmerterden/multi-agent-pipeline 20.6.0 → 20.8.0
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 +27 -0
- package/LICENSE +0 -10
- package/docs/facts.json +1 -1
- package/manifest.json +328 -329
- package/package.json +2 -2
- package/pipeline/multi-agent-refs/features/design-conformance.md +62 -64
- package/pipeline/scripts/_notices.mjs +12 -1
- package/pipeline/scripts/gen-skills-index.mjs +1 -1
- package/pipeline/skills/.skill-manifest.json +106 -106
- package/pipeline/skills/shared/README.md +71 -71
- package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +1 -0
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
- package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
- package/pipeline/skills/shared/external/android-architecture/SKILL.md +2 -0
- package/pipeline/skills/shared/external/android-performance/SKILL.md +2 -0
- package/pipeline/skills/shared/external/android-security/SKILL.md +2 -0
- package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
- package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
- package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
- package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
- package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
- package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
- package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
- package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
- package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
- package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
- package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
- package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
- package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
- package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
- package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
- package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
- package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
- package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
- package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
- package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
- package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
- package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
- package/pipeline/skills/shared/external/backlog/BACKLOG.md +1 -1
- package/pipeline/skills/shared/external/backlog/SKILL.md +56 -33
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
- package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
- package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +1 -0
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
- package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
- package/pipeline/skills/shared/external/compose-components/SKILL.md +2 -0
- package/pipeline/skills/shared/external/compose-navigation/SKILL.md +3 -2
- package/pipeline/skills/shared/external/compose-testing/SKILL.md +2 -0
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
- package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
- package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
- package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
- package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
- package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
- package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
- package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
- package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
- package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
- package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
- package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
- package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
- package/pipeline/skills/shared/external/council/SKILL.md +1 -0
- package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
- package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
- package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
- package/pipeline/skills/shared/external/css-modern/SKILL.md +1 -0
- package/pipeline/skills/shared/external/database-patterns/SKILL.md +1 -0
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
- package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
- package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
- package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
- package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
- package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
- package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
- package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
- package/pipeline/skills/shared/external/evidence-github/SKILL.md +2 -0
- package/pipeline/skills/shared/external/evidence-registry/SKILL.md +2 -0
- package/pipeline/skills/shared/external/gradle-kotlin-dsl/SKILL.md +2 -0
- package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
- package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
- package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
- package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
- package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
- package/pipeline/skills/shared/external/html-semantic/SKILL.md +1 -0
- package/pipeline/skills/shared/external/humanizer/SKILL.md +1 -0
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
- package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
- package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
- package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
- package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
- package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +1 -0
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
- package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
- package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
- package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +1 -0
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
- package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
- package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
- package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
- package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
- package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
- package/pipeline/skills/shared/external/ios-security/SKILL.md +2 -0
- package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
- package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
- package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
- package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
- package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +91 -283
- package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +119 -151
- package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +60 -90
- package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +119 -156
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +726 -787
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +253 -288
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +243 -304
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +88 -104
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +181 -235
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-key-shots.py +198 -263
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +461 -466
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +145 -151
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +123 -141
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +146 -157
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/snapshot-resources.sh +22 -19
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +156 -140
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
- package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
- package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
- package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
- package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
- package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
- package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
- package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
- package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +1 -0
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
- package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
- package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
- package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
- package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
- package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
- package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
- package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
- package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
- package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
- package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
- package/pipeline/skills/shared/external/play-store-review/SKILL.md +2 -0
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
- package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
- package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
- package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
- package/pipeline/skills/shared/external/python-patterns/SKILL.md +1 -0
- package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -0
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
- package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
- package/pipeline/skills/shared/external/rest-api-design/SKILL.md +1 -0
- package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +2 -0
- package/pipeline/skills/shared/external/room-database/SKILL.md +2 -0
- package/pipeline/skills/shared/external/search-first/SKILL.md +1 -0
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
- package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
- package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
- package/pipeline/skills/shared/external/signal-community/SKILL.md +2 -0
- package/pipeline/skills/shared/external/skill-creator/SKILL.md +80 -41
- package/pipeline/skills/shared/external/skill-creator/audit.md +63 -59
- package/pipeline/skills/shared/external/skill-creator/checklist.md +28 -20
- package/pipeline/skills/shared/external/skill-creator/examples.md +40 -40
- package/pipeline/skills/shared/external/skill-creator/label-check.md +48 -36
- package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +91 -100
- package/pipeline/skills/shared/external/skill-creator/template.md +51 -39
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
- package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
- package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
- package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
- package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
- package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
- package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
- package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
- package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
- package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
- package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
- package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
- package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
- package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
- package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
- package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
- package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
- package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
- package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
- package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
- package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
- package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
- package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
- package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
- package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
- package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
- package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
- package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
- package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
- package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
- package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
- package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
- package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
- package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
- package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
- package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
- package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
- package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
- package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
- package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
- package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
- package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
- package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
- package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
- package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
- package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
- package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
- package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
- package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
- package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
- package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
- package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
- package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
- package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
- package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
- package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
- package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
- package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
- package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
- package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
- package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
- package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
- package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
- package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
- package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
- package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
- package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
- package/pipeline/skills/shared/external/tailwind-css/SKILL.md +1 -0
- package/pipeline/skills/shared/external/testing-backend/SKILL.md +1 -0
- package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
- package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
- package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +1 -0
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
- package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
- package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
- package/pipeline/skills/shared/external/vue-composition/SKILL.md +1 -0
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
- package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
- package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -0
- package/pipeline/skills/shared/external/web-performance/SKILL.md +1 -0
- package/pipeline/skills/shared/external/web-testing/SKILL.md +1 -0
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
- package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
|
@@ -1,264 +1,277 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: swift-testing
|
|
3
|
-
description: "
|
|
3
|
+
description: "Writing, migrating and reviewing Swift Testing tests: @Test, @Suite, #expect, #require, confirmation, traits, withKnownIssue, Attachment.record, exit tests with processExitsWith and capture lists, Test.cancel, Issue.record warnings and manual failures, XCTest conversion (XCTUnwrap, XCTFail), mocking, async patterns, test organisation. Use when writing or migrating Swift tests, checking which Swift Testing APIs a toolchain supports, or deciding where XCTest and XCUITest still belong for UI, performance and snapshot tests."
|
|
4
4
|
metadata:
|
|
5
|
-
source:
|
|
5
|
+
source: multi-agent-pipeline
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Swift Testing
|
|
9
9
|
|
|
10
|
-
Swift Testing
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- [Basic Tests](#basic-tests)
|
|
15
|
-
- [`@Test Traits`](#test-traits)
|
|
16
|
-
- [#expect and #require](#expect-and-require)
|
|
17
|
-
- [`@Suite and Test Organization`](#suite-and-test-organization)
|
|
18
|
-
- [Execution Model](#execution-model)
|
|
19
|
-
- [XCTest Migration Boundaries](#xctest-migration-boundaries)
|
|
20
|
-
- [Known Issues](#known-issues)
|
|
21
|
-
- [Additional Patterns](#additional-patterns)
|
|
22
|
-
- [Common Mistakes](#common-mistakes)
|
|
23
|
-
- [Test Attachments](#test-attachments)
|
|
24
|
-
- [Exit Testing](#exit-testing)
|
|
25
|
-
- [Version-Gated APIs](#version-gated-apis)
|
|
26
|
-
- [Advanced API Review Checklist](#advanced-api-review-checklist)
|
|
27
|
-
- [Review Checklist](#review-checklist)
|
|
28
|
-
- [References](#references)
|
|
10
|
+
Swift Testing needs Xcode 16 or later and Swift 6 or later. Use it for every
|
|
11
|
+
new unit test. XCTest keeps UI tests (XCUITest), performance measurements and
|
|
12
|
+
most snapshot workflows.
|
|
29
13
|
|
|
30
|
-
|
|
14
|
+
More material: [patterns and migration](references/testing-patterns.md) and
|
|
15
|
+
[newer APIs and version gates](references/testing-advanced.md).
|
|
31
16
|
|
|
32
|
-
##
|
|
17
|
+
## A First Test
|
|
33
18
|
|
|
34
19
|
```swift
|
|
35
20
|
import Testing
|
|
21
|
+
@testable import Ledger
|
|
36
22
|
|
|
37
|
-
@Test("
|
|
38
|
-
func
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
#expect(user.name == "Bob")
|
|
23
|
+
@Test("A new account starts with a zero balance")
|
|
24
|
+
func newAccountIsEmpty() {
|
|
25
|
+
let account = Account(owner: "Ada")
|
|
26
|
+
#expect(account.balance == 0)
|
|
42
27
|
}
|
|
43
28
|
```
|
|
44
29
|
|
|
45
|
-
##
|
|
30
|
+
## Traits
|
|
46
31
|
|
|
47
32
|
```swift
|
|
48
|
-
@Test("
|
|
49
|
-
|
|
50
|
-
@Test(.disabled("Server migration in progress")) // disabled
|
|
51
|
-
@Test(.enabled(if: ProcessInfo.processInfo.environment["CI"] != nil)) // conditional
|
|
52
|
-
@Test(.bug("https://github.com/org/repo/issues/42")) // bug reference
|
|
53
|
-
@Test(.timeLimit(.minutes(1))) // time limit
|
|
54
|
-
@Test("Timeout handling", .tags(.networking), .timeLimit(.seconds(30))) // combined
|
|
55
|
-
```
|
|
33
|
+
@Test("Rejects malformed IBANs", .tags(.validation, .banking))
|
|
34
|
+
func rejectsMalformedIBAN() { }
|
|
56
35
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```swift
|
|
60
|
-
// #expect records failure but continues execution
|
|
61
|
-
#expect(result == 42)
|
|
62
|
-
#expect(name.isEmpty == false)
|
|
63
|
-
#expect(items.count > 0, "Items should not be empty")
|
|
64
|
-
|
|
65
|
-
// #expect with error type checking
|
|
66
|
-
#expect(throws: ValidationError.self) {
|
|
67
|
-
try validate(email: "not-an-email")
|
|
68
|
-
}
|
|
36
|
+
@Test(.disabled("Waiting for the sandbox to come back"))
|
|
37
|
+
func sandboxTransfer() { }
|
|
69
38
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
try validate(email: "")
|
|
73
|
-
} throws: { error in
|
|
74
|
-
guard let err = error as? ValidationError else { return false }
|
|
75
|
-
return err == .empty
|
|
76
|
-
}
|
|
39
|
+
@Test(.enabled(if: ProcessInfo.processInfo.environment["CI"] == "true"))
|
|
40
|
+
func nightlyReconciliation() { }
|
|
77
41
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
#expect(user.name == "Alice")
|
|
42
|
+
@Test(.bug("https://tracker.example.com/issue/481"))
|
|
43
|
+
func roundingRegression() { }
|
|
81
44
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
#expect(first.isValid)
|
|
45
|
+
@Test("Imports a year of statements", .tags(.slow), .timeLimit(.minutes(2)))
|
|
46
|
+
func importsAYear() async throws { }
|
|
85
47
|
```
|
|
86
48
|
|
|
87
|
-
|
|
49
|
+
- The first string argument is the display name.
|
|
50
|
+
- `.tags(...)`, `.disabled("reason")`, `.enabled(if:)`, `.bug(...)` and
|
|
51
|
+
`.timeLimit(...)` combine freely in one `@Test`.
|
|
52
|
+
- `.timeLimit` takes whole minutes only (`.minutes(_:)`). There is no
|
|
53
|
+
`.seconds` form.
|
|
88
54
|
|
|
89
|
-
##
|
|
55
|
+
## `#expect` and `#require`
|
|
90
56
|
|
|
91
|
-
|
|
57
|
+
```swift
|
|
58
|
+
@Test func transferValidation() async throws {
|
|
59
|
+
let ledger = Ledger()
|
|
92
60
|
|
|
93
|
-
|
|
61
|
+
#expect(ledger.accounts.isEmpty, "A fresh ledger has no accounts")
|
|
94
62
|
|
|
95
|
-
|
|
63
|
+
#expect(throws: LedgerError.self) {
|
|
64
|
+
try ledger.transfer(amount: -5, from: "A", to: "B")
|
|
65
|
+
}
|
|
96
66
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
67
|
+
let error = #expect(throws: LedgerError.self) {
|
|
68
|
+
try ledger.transfer(amount: 10, from: "A", to: "A")
|
|
69
|
+
}
|
|
70
|
+
#expect(error == .sameAccount)
|
|
71
|
+
|
|
72
|
+
let first = try #require(await ledger.loadAccounts().first)
|
|
73
|
+
#expect(first.currency == "EUR")
|
|
102
74
|
}
|
|
103
75
|
```
|
|
104
76
|
|
|
105
|
-
|
|
77
|
+
- `#expect` records a failure and lets the test continue. An optional message
|
|
78
|
+
follows the condition.
|
|
79
|
+
- `#expect(throws: SomeError.self) { ... }` checks the error type. Since Swift
|
|
80
|
+
6.1 it returns the thrown error, so you can inspect its value afterwards. The
|
|
81
|
+
older form with a trailing `throws: { error in ... }` predicate closure is
|
|
82
|
+
deprecated.
|
|
83
|
+
- `try #require(...)` records a failure and stops the test, like `XCTUnwrap`.
|
|
84
|
+
It unwraps optionals and accepts `await` expressions.
|
|
85
|
+
- Pick `#require` when the rest of the test needs that value to exist; pick
|
|
86
|
+
`#expect` for checks that stand on their own.
|
|
106
87
|
|
|
107
|
-
|
|
108
|
-
- Each test must set up its own state.
|
|
109
|
-
- Shared mutable globals are a bug unless protected or intentionally serialized.
|
|
110
|
-
- `@Suite(.serialized)` is for exclusive execution, not for expressing logical ordering between tests.
|
|
111
|
-
- If tests depend on sequence, combine them into one test or move the sequence into shared helper code.
|
|
88
|
+
## How Tests Run
|
|
112
89
|
|
|
113
|
-
|
|
90
|
+
Unless told otherwise, Swift Testing runs tests concurrently. Never count on an
|
|
91
|
+
order, on one suite instance shared between tests, or on having anything to
|
|
92
|
+
yourself.
|
|
114
93
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
94
|
+
```swift
|
|
95
|
+
@Suite(.serialized)
|
|
96
|
+
struct KeychainStoreTests {
|
|
97
|
+
@Test func savesToken() throws { }
|
|
98
|
+
@Test func deletesToken() throws { }
|
|
99
|
+
}
|
|
100
|
+
```
|
|
120
101
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
102
|
+
`.serialized` makes the tests in that suite run one at a time. It does not
|
|
103
|
+
affect tests outside the suite.
|
|
104
|
+
|
|
105
|
+
- Every test builds its own state.
|
|
106
|
+
- A shared mutable global is a bug unless it is protected or serialized.
|
|
107
|
+
- `.serialized` is for exclusive access, not for ordering.
|
|
108
|
+
- Steps that depend on each other belong in one test or a shared helper.
|
|
109
|
+
|
|
110
|
+
## Migrating from XCTest
|
|
111
|
+
|
|
112
|
+
- Swift Testing tests do not subclass `XCTestCase`. Put `@Test` on a free
|
|
113
|
+
function, or on a method of a `struct`, `class` or `actor` suite. Use a
|
|
114
|
+
`static` or `class` method when no instance fixture is needed.
|
|
115
|
+
- Do not rewrite every assertion as `#expect`. Keep a mapping so required
|
|
116
|
+
unwraps and explicit failures keep their meaning, even when asked to "just
|
|
117
|
+
use #expect everywhere".
|
|
118
|
+
- XCTest and Swift Testing can live side by side while you migrate.
|
|
119
|
+
- Leave UI automation, performance measurements and common snapshot flows on
|
|
120
|
+
XCTest, XCUITest or the snapshot tool. Separate files or targets help when
|
|
121
|
+
they make it clear which runner owns what.
|
|
122
|
+
|
|
123
|
+
| XCTest | Swift Testing |
|
|
124
|
+
|--------|---------------|
|
|
125
|
+
| `XCTAssert...` | `#expect(...)` |
|
|
126
|
+
| `XCTUnwrap`, or a value later checks rely on | `try #require(...)` |
|
|
127
|
+
| `XCTFail("...")`, any unconditional failure | `Issue.record("...")` |
|
|
127
128
|
|
|
128
129
|
```swift
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
@Test func parsesHeader() throws {
|
|
131
|
+
guard let header = Header(raw: "v2;utf8") else {
|
|
132
|
+
Issue.record("Header did not parse")
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
#expect(header.version == 2)
|
|
135
136
|
}
|
|
136
137
|
```
|
|
137
138
|
|
|
138
|
-
|
|
139
|
+
Put `@available` on the individual `@Test` function, never on a suite type or
|
|
140
|
+
the type that contains it.
|
|
139
141
|
|
|
140
142
|
## Known Issues
|
|
141
143
|
|
|
142
|
-
Mark expected failures so they do not cause test failure:
|
|
143
|
-
|
|
144
144
|
```swift
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
@Test func legacyExport() {
|
|
146
|
+
withKnownIssue("Exporter drops the BOM; fix scheduled") {
|
|
147
|
+
#expect(Exporter().csv().hasPrefix("\u{FEFF}"))
|
|
148
|
+
}
|
|
147
149
|
}
|
|
148
150
|
|
|
149
|
-
|
|
150
|
-
withKnownIssue(isIntermittent: true) {
|
|
151
|
-
|
|
151
|
+
@Test func flakyMirror() async {
|
|
152
|
+
await withKnownIssue(isIntermittent: true) {
|
|
153
|
+
try await ReplicaSync.run()
|
|
154
|
+
}
|
|
152
155
|
}
|
|
153
156
|
|
|
154
|
-
|
|
155
|
-
withKnownIssue {
|
|
156
|
-
|
|
157
|
-
} when: {
|
|
158
|
-
|
|
157
|
+
@Test func arm64OnlyBug() {
|
|
158
|
+
withKnownIssue {
|
|
159
|
+
#expect(Checksum.fast([1, 2, 3]) == Checksum.slow([1, 2, 3]))
|
|
160
|
+
} when: {
|
|
161
|
+
Platform.isARM64
|
|
162
|
+
}
|
|
159
163
|
}
|
|
160
164
|
```
|
|
161
165
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
See [references/testing-patterns.md](references/testing-patterns.md) for parameterized tests, tags and suites, async testing, traits, and execution-model details.
|
|
167
|
-
|
|
168
|
-
## Test Attachments
|
|
166
|
+
A known issue does not fail the test. If the body records no issue at all,
|
|
167
|
+
Swift Testing reports a separate issue telling you the problem may have been
|
|
168
|
+
fixed, so the marker does not linger.
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
## Attachments
|
|
171
171
|
|
|
172
172
|
```swift
|
|
173
|
-
@Test func
|
|
174
|
-
let
|
|
175
|
-
Attachment.record(
|
|
176
|
-
#expect(
|
|
173
|
+
@Test func exportsReport() throws {
|
|
174
|
+
let data = try ReportBuilder().json()
|
|
175
|
+
Attachment.record(data, named: "report.json")
|
|
176
|
+
#expect(!data.isEmpty)
|
|
177
177
|
}
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
Images (Swift 6.3, Xcode 26.4 or later) need the UI framework imported next to
|
|
181
|
+
`Testing`:
|
|
181
182
|
|
|
182
183
|
```swift
|
|
183
184
|
import Testing
|
|
184
185
|
import UIKit
|
|
185
186
|
|
|
186
|
-
@
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
@MainActor
|
|
188
|
+
@Test func rendersGauge() {
|
|
189
|
+
let gauge = GaugeView(frame: CGRect(x: 0, y: 0, width: 160, height: 160))
|
|
190
|
+
let image = UIGraphicsImageRenderer(bounds: gauge.bounds).image { _ in
|
|
191
|
+
gauge.drawHierarchy(in: gauge.bounds, afterScreenUpdates: true)
|
|
192
|
+
}
|
|
193
|
+
Attachment.record(image, named: "gauge", as: .png)
|
|
189
194
|
}
|
|
190
195
|
```
|
|
191
196
|
|
|
192
|
-
## Exit
|
|
197
|
+
## Exit Tests
|
|
193
198
|
|
|
194
|
-
|
|
199
|
+
Exit tests check code that ends the process: `exit()`, `fatalError()`,
|
|
200
|
+
`preconditionFailure()`. They need Swift 6.2 (Xcode 26.0) and run on macOS,
|
|
201
|
+
Linux, FreeBSD, OpenBSD and Windows. They are not available on iOS, tvOS or
|
|
202
|
+
watchOS. When fixing exit-test code, state both limits: the toolchain floor and
|
|
203
|
+
the platforms it runs on.
|
|
195
204
|
|
|
196
205
|
```swift
|
|
197
|
-
@Test func
|
|
206
|
+
@Test func rejectsCorruptConfig() async {
|
|
198
207
|
await #expect(processExitsWith: .failure) {
|
|
199
|
-
|
|
208
|
+
_ = Config.loadOrDie(path: "/dev/null")
|
|
200
209
|
}
|
|
201
210
|
}
|
|
202
211
|
```
|
|
203
212
|
|
|
204
|
-
## Version
|
|
213
|
+
## Version Gates
|
|
214
|
+
|
|
215
|
+
Check the toolchain before recommending newer APIs, and name the gate for each
|
|
216
|
+
API you correct.
|
|
205
217
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
218
|
+
| API | Needs |
|
|
219
|
+
|-----|-------|
|
|
220
|
+
| Exit tests (`processExitsWith:`) | Swift 6.2, Xcode 26.0; not iOS, tvOS, watchOS |
|
|
221
|
+
| Capture lists in exit tests | Swift 6.3 compiler; captured values must be `Sendable` and `Codable` |
|
|
222
|
+
| `Test.cancel(_:)`, `Issue.record(_:severity:)`, image attachments | Swift 6.3, Xcode 26.4 |
|
|
211
223
|
|
|
212
224
|
```swift
|
|
213
|
-
@Test func
|
|
214
|
-
let
|
|
215
|
-
await #expect(processExitsWith: .
|
|
216
|
-
exit(
|
|
225
|
+
@Test func exitsWithConfiguredCode() async {
|
|
226
|
+
let status: Int32 = 42
|
|
227
|
+
await #expect(processExitsWith: .exitCode(status)) { [status = status as Int32] in
|
|
228
|
+
exit(status)
|
|
217
229
|
}
|
|
218
230
|
}
|
|
219
231
|
```
|
|
220
232
|
|
|
221
|
-
|
|
233
|
+
Give each captured value an explicit type (`[name = name as Type]`). A bare
|
|
234
|
+
`[status]` fails to compile with "Type of captured value is ambiguous",
|
|
235
|
+
because the macro cannot infer the type on its own.
|
|
236
|
+
|
|
237
|
+
A test that calls `Test.cancel(_:)` must be `throws` or `async throws`.
|
|
222
238
|
|
|
223
|
-
|
|
239
|
+
## Correcting Advanced API Code
|
|
224
240
|
|
|
225
|
-
|
|
|
226
|
-
|
|
227
|
-
| `#expect(exitsWith:)` |
|
|
228
|
-
| Exit-test closure
|
|
229
|
-
| `Test.cancel()` in a test that
|
|
230
|
-
|
|
|
231
|
-
| `Attachment(image, named:).record()` |
|
|
241
|
+
| Found | Replace with |
|
|
242
|
+
|-------|--------------|
|
|
243
|
+
| `#expect(exitsWith:)` | `await #expect(processExitsWith: .failure) { ... }`. In an iOS app target, test the logic behind a smaller API that does not exit, or move the exit test to a supported host or tool target. |
|
|
244
|
+
| Exit-test closure reading outer values with no capture list | An explicit, typed capture list (`[code = code as Int32]`); Swift 6.3 compiler; values `Sendable` and `Codable` |
|
|
245
|
+
| `Test.cancel()` in a test that is not throwing | Mark the test `async throws` and call `try Test.cancel("reason")` |
|
|
246
|
+
| A warning that should not fail the run | `Issue.record("message", severity: .warning)`: reported, test still passes; Swift 6.3, Xcode 26.4 |
|
|
247
|
+
| `Attachment(image, named:).record()` | `Attachment.record(image, named: "...", as: .png)`; accepts `UIImage`, `CGImage`, `CIImage`, `NSImage`; Swift 6.3, Xcode 26.4 |
|
|
232
248
|
|
|
233
249
|
## Common Mistakes
|
|
234
250
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
251
|
+
- Testing how the code works instead of what it does.
|
|
252
|
+
- No tests for the error paths of throwing functions.
|
|
253
|
+
- Waiting with sleeps in async tests. Use `confirmation` with an expected
|
|
254
|
+
count, an injected clock, or `withKnownIssue` for known flakiness.
|
|
255
|
+
- Shared mutable state between tests. Set up in the suite's `init()`.
|
|
256
|
+
- UI tests without accessibility identifiers; XCUITest queries rely on them.
|
|
257
|
+
- Never testing that a `Task` stops when cancelled.
|
|
258
|
+
- Unclear migration boundaries. Both frameworks may share a file, but separate
|
|
259
|
+
files are usually clearer for imports, ownership and runner expectations.
|
|
260
|
+
- Non-`Sendable` helpers shared across concurrent tests. Mark test code that
|
|
261
|
+
needs the main actor `@MainActor`.
|
|
262
|
+
- Relying on declaration order.
|
|
263
|
+
- Using `.serialized` to chain the steps of a workflow. Put dependent steps in
|
|
264
|
+
one test.
|
|
246
265
|
|
|
247
266
|
## Review Checklist
|
|
248
267
|
|
|
249
|
-
- [ ]
|
|
250
|
-
- [ ]
|
|
251
|
-
- [ ] Error paths have
|
|
252
|
-
- [ ] Async
|
|
253
|
-
- [ ]
|
|
254
|
-
- [ ] Tags
|
|
255
|
-
- [ ] Mocks conform to protocols
|
|
256
|
-
- [ ] No shared mutable state
|
|
257
|
-
- [ ]
|
|
258
|
-
- [ ]
|
|
259
|
-
- [ ] Cancellation tested for cancellable async operations
|
|
260
|
-
|
|
261
|
-
## References
|
|
262
|
-
|
|
263
|
-
- Testing patterns: [references/testing-patterns.md](references/testing-patterns.md)
|
|
264
|
-
- Advanced testing (warnings, cancellation, image attachments): [references/testing-advanced.md](references/testing-advanced.md)
|
|
268
|
+
- [ ] New tests use `@Test` and `#expect`, not XCTest assertions
|
|
269
|
+
- [ ] Names describe behaviour (`fetchUserReturnsNilOnNetworkError`, not `testFetchUser`)
|
|
270
|
+
- [ ] Error paths have their own tests
|
|
271
|
+
- [ ] Async events verified with `confirmation()` rather than `Task.sleep`
|
|
272
|
+
- [ ] Repetitive variations are parameterized
|
|
273
|
+
- [ ] Tags such as `.critical` or `.slow` exist for filtering
|
|
274
|
+
- [ ] Mocks conform to protocols; no subclassing of concrete types
|
|
275
|
+
- [ ] No shared mutable state, no dependence on order or on a shared suite instance
|
|
276
|
+
- [ ] `.serialized` used only for exclusive resources
|
|
277
|
+
- [ ] Cancellable async work has a cancellation test
|
|
@@ -2,42 +2,44 @@
|
|
|
2
2
|
"skill_name": "swift-testing",
|
|
3
3
|
"evals": [
|
|
4
4
|
{
|
|
5
|
-
"id":
|
|
6
|
-
"prompt": "
|
|
7
|
-
"expected_output": "A migration review that
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "I'm moving our CartServiceTests from XCTest to Swift Testing. My plan: keep `final class CartServiceTests: XCTestCase` but add @Test to the methods, share one CartService through a static singleton so setUp goes away, put @available(iOS 18, *) on the class, turn every assertion including XCTUnwrap into #expect, and move the checkout UI tests into the same Swift Testing file. Review it.",
|
|
7
|
+
"expected_output": "A migration review that corrects each part of the plan and explains how the two frameworks coexist.",
|
|
8
8
|
"files": [],
|
|
9
9
|
"assertions": [
|
|
10
|
-
"Rejects keeping XCTestCase
|
|
11
|
-
"Recommends per
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"Keeps
|
|
10
|
+
"Rejects keeping XCTestCase as the parent of Swift Testing tests and proposes a struct, class or actor suite or free functions.",
|
|
11
|
+
"Recommends a fresh fixture per test through the suite init() instead of a shared singleton.",
|
|
12
|
+
"Moves @available onto the individual @Test functions, not the suite type.",
|
|
13
|
+
"Converts XCTUnwrap to try #require and XCTFail to Issue.record rather than turning everything into #expect.",
|
|
14
|
+
"Keeps the checkout UI tests on XCTest with XCUITest.",
|
|
15
|
+
"States that XCTest and Swift Testing can coexist during the migration."
|
|
15
16
|
]
|
|
16
17
|
},
|
|
17
18
|
{
|
|
18
|
-
"id":
|
|
19
|
-
"prompt": "
|
|
20
|
-
"expected_output": "
|
|
19
|
+
"id": 2,
|
|
20
|
+
"prompt": "We build with Xcode 26.4 and Swift 6.3 for an iOS 26 app. Review these tests: `#expect(exitsWith: .failure) { Vault.unlock(code: badCode) }` where badCode is a local, `func skipsOffline() { Test.cancel(\"offline\") }`, `Issue.record(\"slow parse\")` that should only warn, and `Attachment(chartImage, named: \"chart\").record()`.",
|
|
21
|
+
"expected_output": "Each API corrected to its current spelling, with the toolchain gate and platform limits named for every change.",
|
|
21
22
|
"files": [],
|
|
22
23
|
"assertions": [
|
|
23
|
-
"Replaces
|
|
24
|
-
"States that exit
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"Uses Issue.record
|
|
24
|
+
"Replaces exitsWith: with await #expect(processExitsWith: .failure).",
|
|
25
|
+
"States that exit tests need Swift 6.2 and Xcode 26.0 and do not run on iOS, tvOS or watchOS, and suggests testing the non-exiting logic in the app target.",
|
|
26
|
+
"Adds an explicit capture list for badCode, requiring the Swift 6.3 compiler and Sendable plus Codable values.",
|
|
27
|
+
"Makes the cancelling test async throws (or throws) and calls try Test.cancel.",
|
|
28
|
+
"Uses Issue.record with severity: .warning and names the Swift 6.3 and Xcode 26.4 gate.",
|
|
29
|
+
"Uses Attachment.record(chartImage, named:, as: .png) and names the Swift 6.3 and Xcode 26.4 gate."
|
|
28
30
|
]
|
|
29
31
|
},
|
|
30
32
|
{
|
|
31
|
-
"id":
|
|
32
|
-
"prompt": "Plan tests for
|
|
33
|
-
"expected_output": "A
|
|
33
|
+
"id": 3,
|
|
34
|
+
"prompt": "Plan the tests for our checkout feature: a price calculator with discounts, a coupon service that posts async events, the login-to-checkout flow, a launch-time benchmark, and screenshots in dark mode and at large text sizes.",
|
|
35
|
+
"expected_output": "A test plan that assigns each area to the right framework or tool.",
|
|
34
36
|
"files": [],
|
|
35
37
|
"assertions": [
|
|
36
|
-
"Uses Swift Testing
|
|
37
|
-
"Uses confirmation
|
|
38
|
-
"
|
|
39
|
-
"Keeps performance
|
|
40
|
-
"
|
|
38
|
+
"Uses Swift Testing (@Test, #expect, parameterized arguments) for the price calculator.",
|
|
39
|
+
"Uses confirmation for the async coupon events and rules out sleeps.",
|
|
40
|
+
"Uses XCUITest for the login-to-checkout flow.",
|
|
41
|
+
"Keeps the benchmark on XCTest performance APIs and the dark-mode and Dynamic Type screenshots on snapshot tooling.",
|
|
42
|
+
"Says both frameworks may share a target during migration but recommends clear file or target separation."
|
|
41
43
|
]
|
|
42
44
|
}
|
|
43
45
|
]
|