app-store
App Store optimization and marketing skills for descriptions, screenshots, keywords, review responses, and comprehensive promotional strategy. Use when user…
Generate protocol/interface test suites that any implementation must pass. Define the contract once, test every implementation. Use when designing protocols or swapping implementations.
$ npx -y skills add rshankras/claude-code-apple-skills --skill test-contract --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/test-contractContext preview
The summary Claude sees to decide when to auto-load this skill.
Generate protocol/interface test suites that any implementation must pass. Define the contract once, test every implementation. Use when designing protocols or swapping implementations.
name: test-contract description: Generate protocol/interface test suites that any implementation must pass. Define the contract once, test every implementation. Use when designing protocols or swapping implementations. allowed-tools: [Read, Write, Edit, Glob, Grep, Bash, AskUserQuestion] last_verified: 2026-07-16 review_by: 2027-06-22
Define behavioral contracts as test suites. Any class conforming to a protocol must pass the contract tests. Ensures consistent behavior across implementations — human-written, AI-generated, or mock.
Use this skill when the user:
Protocol: DataStore ├── SQLiteDataStore → must pass contract tests ├── InMemoryDataStore → must pass contract tests ├── MockDataStore → must pass contract tests └── CloudDataStore → must pass contract tests
Write the contract once. Every implementation proves it works by passing the same tests.
Grep: "protocol.*\\{" to find protocols
Read: protocol definitionUnderstand:
For each protocol method, define required behaviors:
## DataStore Contract ### save(_ item:) - Saving a new item increases count by 1 - Saved item is retrievable by ID ### fetch(id:) - Returns item when it exists - Returns nil when item doesn't exist - Returns most recently saved version ### delete(id:) - Deleting existing item decreases count by 1 - Deleted item is no longer fetchable ### fetchAll() - Returns all saved items - Returns empty array when store is empty - Items are in consistent order (insertion or specified) ### Invariants - count == fetchAll().count (always) - save then fetch returns same item - delete then fetch returns nil
import Testing
/// Contract tests for any DataStore implementation.
/// Subclass or call with your concrete implementation.
struct DataStoreContractTests<Store: DataStore> {
let makeStore: () -> Store
init(makeStore: @escaping () -> Store) {
self.makeStore = makeStore
}
// MARK: - save(_ item:)
@Test("save increases count")
func saveIncreasesCount() async throws {
let store = makeStore()
let item = Item(id: "1", title: "Test")
try await store.save(item)
#expect(store.count == 1)
}
@Test("save then fetch returns same item")
func saveAndFetch() async throws {
let store = makeStore()
let item = Item(id: "1", title: "Test")
try await store.save(item)
let fetched = try await store.fetch(id: "1")
#expect(fetched?.title == "Test")
}
@Test("save existing item updates it")
func saveUpdates() async throws {
let store = makeStore()
try await store.save(Item(id: "1", title: "Original"))
try await store.save(Item(id: "1", title: "Updated"))
let fetched = try await store.fetch(id: "1")
#expect(fetched?.title == "Updated")
#expect(store.count == 1)
}
@Test("save throws on invalid item")
func saveInvalidThrows() async {
let store = makeStore()
let invalid = Item(id: "1", title: "")
await #expect(throws: DataStoreError.invalidItem) {
try await store.save(invalid)
}
}
// MARK: - fetch(id:)
@Test("fetch returns nil for non-existent ID")
func fetchNonExistent() async throws {
let store = makeStore()
let result = try await store.fetch(id: "nonexistent")
#expect(result == nil)
}
// MARK: - delete(id:)
@Test("delete removes item")
func deleteRemoves() async throws {
let store = makeStore()
try await store.save(Item(id: "1", title: "Test"))
try await store.delete(id: "1")
#expect(store.count == 0)
let fetched = try await store.fetch(id: "1")
#expect(fetched == nil)
}
@Test("delete non-existent does nothing")
func deleteNonExistent() async throws {
let store = makeStore()
try await store.delete(id: "nonexistent")
#expect(store.count == 0)
}
// MARK: - fetchAll()
@Test("fetchAll returns all items")
func fetchAll() async throws {
let store = makeStore()
try await store.save(Item(id: "1", title: "A"))
try await store.save(Item(id: "2", title: "B"))
let all = try await store.fetchAll()
#expect(all.count == 2)
}
@Test("fetchAll returns empty when store is empty")
func fetchAllEmpty() async throws {
let store = makeStore()
let all = try await store.fetchAll()
#expect(all.isEmpty)
}
// MARK: - Invariants
@Test("count matches fetchAll count")
func countInvariant() async throws {
let store = makeStore()
try await store.save(Item(id: "1", title: "A"))
try await store.save(Item(id: "2", title: "B"))
try await store.delete(id: "1")
let all = try await store.fetchAll()
#expect(store.count == all.count)
}
}@Suite("InMemoryDataStore Contract")
struct InMemoryDataStoreContractTests {
let contract = DataStoreContractTests { InMemoryDataStore() }
@Test("save increases count")
func saveIncreasesCount() async throA collection of Claude Code skills for iOS, macOS, watchOS, visionOS, and Apple platform development. These skills help you plan and build apps, maintain code quality, ensure HIG compliance, and guide you from idea to App Store.
Repo: rshankras/claude-code-apple-skills
App Store optimization and marketing skills for descriptions, screenshots, keywords, review responses, and comprehensive promotional strategy. Use when user…
Privacy-preserving ad measurement with AdAttributionKit (SKAdNetwork's successor) — install and re-engagement attribution, conversion-value strategy under…
Generate compelling App Store descriptions that convert browsers into users. Use when writing initial descriptions, improving existing copy, or drafting…
Apple Search Ads campaign strategy for indie developers — paid acquisition, keyword bidding, budget planning, and ROAS optimization. Use when user asks about…
Take a one-time in-app purchase from MISSING_METADATA to READY_TO_SUBMIT in App Store Connect — set its price schedule and localized display name/description…
Optimize app title, subtitle, and keywords for maximum App Store discoverability. Use when launching a new app, improving search rankings, entering new…