listless

A simple list app for Apple platforms
Log | Files | Refs | README | LICENSE

commit b519835d06d458d99207703f426a5648a16dd12a
parent 802ee8b3a94b99ed4820174626a05f62faf2fb04
Author: Michael Camilleri <[email protected]>
Date:   Fri, 13 Mar 2026 12:00:05 +0900

Add macOS as a target for test suite

This commit does not add any Mac specific tests but instead ensures that
the unit tests that currently can be run with an iOS-based test scheme
can now also be run with a macOS-based test scheme.

Co-Authored-By: Claude 4.6 Opus <[email protected]>

Diffstat:
MListless.xcodeproj/project.pbxproj | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MListless.xcodeproj/xcshareddata/xcschemes/Listless macOS.xcscheme | 12++++++++++++
MTests/Support/TestHelpers.swift | 4++++
MTests/Unit/CloudKitErrorClassifierTests.swift | 4++++
MTests/Unit/TaskStoreCompletionTests.swift | 4++++
MTests/Unit/TaskStoreEdgeCaseTests.swift | 4++++
MTests/Unit/TaskStoreOrderingTests.swift | 4++++
MTests/Unit/TaskStoreTests.swift | 4++++
Mproject.yml | 21+++++++++++++++++++++
9 files changed, 158 insertions(+), 0 deletions(-)

diff --git a/Listless.xcodeproj/project.pbxproj b/Listless.xcodeproj/project.pbxproj @@ -38,6 +38,7 @@ 5035EC4C7518A5FF9AD454CA /* TaskRowDragGesture.swift in Sources */ = {isa = PBXBuildFile; fileRef = F416DD868A4C044F0D64F8D0 /* TaskRowDragGesture.swift */; }; 53700EA974FE4AD771FE89EC /* CloudKitSyncMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3E82F6093EEFC94A41FED9 /* CloudKitSyncMonitor.swift */; }; 543C8A0C8A9E2F77B2C0060F /* AccentColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DD7EDA74DAAFA27C84CA08 /* AccentColor.swift */; }; + 54FCE72978F20AA64855B521 /* TaskStoreEdgeCaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2BBE01D99CDA278BCB9F49 /* TaskStoreEdgeCaseTests.swift */; }; 568635BB34CD7EBE24E66A15 /* SyncDiagnosticsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF3374CE58E7D9378C6997D2 /* SyncDiagnosticsView.swift */; }; 5761B201BF46FCA9C5C98CEF /* PlatformScrollIndicatorsModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 466F9B0E407DF1F5B4789531 /* PlatformScrollIndicatorsModifier.swift */; }; 57E864F71C9C84B63A28E14F /* TaskStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3DEE364304587D280C5672 /* TaskStore.swift */; }; @@ -60,12 +61,14 @@ 882695E7AE463C0F39ACFF3C /* HoverCursorModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F5D8B5866362D422A2A331C /* HoverCursorModifier.swift */; }; 889DCB2BB3C01DDA281EA81A /* CloudKitSyncMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3E82F6093EEFC94A41FED9 /* CloudKitSyncMonitor.swift */; }; 8A8D164CAA7B95B4C7435A7C /* TaskListView+PullToClear.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A6D74EDDD7E3FC150064FB5 /* TaskListView+PullToClear.swift */; }; + 8FA8398315B67F12EA25FA35 /* TaskStoreCompletionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E88DDD119EEEECCD45F36D2 /* TaskStoreCompletionTests.swift */; }; 91EDF52C7C5C0B35E9D8B51E /* TaskStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3DEE364304587D280C5672 /* TaskStore.swift */; }; 93275BD83342D6CE94272E6A /* TaskListTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F9754B32B2FD5AF8552BC85 /* TaskListTypes.swift */; }; 96617677059FABDBB80D642B /* Listless.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C093494053E6C348F245D4EC /* Listless.xcdatamodeld */; }; 99977BFA37FBAAA49AF6B71E /* TaskStoreEdgeCaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2BBE01D99CDA278BCB9F49 /* TaskStoreEdgeCaseTests.swift */; }; 99D17075DA3F00F52A18BB4D /* AccentColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17DD7EDA74DAAFA27C84CA08 /* AccentColor.swift */; }; A0AA8FD4C542E9AEB2437BC2 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14858BDFD1FD5119F1F24A6 /* PersistenceController.swift */; }; + A10BF9D0C850105E4FA1A2AD /* CloudKitErrorClassifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C3B9FF63645B35E09CF1B1 /* CloudKitErrorClassifierTests.swift */; }; A119D0130DB77E30FBCB5436 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14858BDFD1FD5119F1F24A6 /* PersistenceController.swift */; }; A8D5A7B0DFBEC87501FD0526 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9404C09EE1A4D91DFF338464 /* Media.xcassets */; }; B7CFDCA5EA48EDE1C768FA21 /* AppCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C79ABB39A40D3E1828716C7 /* AppCommands.swift */; }; @@ -76,9 +79,12 @@ CAB42FAA253E2B347AB0594B /* CloudKitErrorClassifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68A677CC11ACE0BF743AFCE5 /* CloudKitErrorClassifier.swift */; }; CAD142ED738A83371DFF8F5B /* TaskListView+Logic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72B4668483D05A6ECA142B89 /* TaskListView+Logic.swift */; }; CC99A96BBC089C423F582E4F /* TaskListViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2C018476BD91B73870244B9 /* TaskListViewProtocol.swift */; }; + CDE538A0B3CA14B1CB421ED8 /* TaskStoreOrderingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3A2DDCE24E54ABCCFBBD4C /* TaskStoreOrderingTests.swift */; }; DB5FF6C1AA57D4C9BDDD50FD /* ClickableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D640E7D21735C62A30A26DA4 /* ClickableTextField.swift */; }; DC73A39A269AB495BCE1AC48 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14858BDFD1FD5119F1F24A6 /* PersistenceController.swift */; }; DEE187A790A4058FE4AFDB2E /* PlatformTextFieldWidthModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8448C5778F75F52719114AF /* PlatformTextFieldWidthModifier.swift */; }; + E12C1304464FC7799856B2BA /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75B048B19C5219862BBED2E7 /* TestHelpers.swift */; }; + E14F8177232BBC75FEEE1E2C /* TaskStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 967F7ECEB3915CEDCE584872 /* TaskStoreTests.swift */; }; E429067963379F99DD184FED /* CloudKitSyncMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E3E82F6093EEFC94A41FED9 /* CloudKitSyncMonitor.swift */; }; E47136CA7428927395D8C7C7 /* PullToCreate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF7D84B54AE70036D205CA4 /* PullToCreate.swift */; }; E4BD761E34CBB84CE80F7F49 /* CloudKitErrorClassifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68A677CC11ACE0BF743AFCE5 /* CloudKitErrorClassifier.swift */; }; @@ -96,6 +102,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 1CECC2E7FCB78843443C0C46 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3256C2BF8F1DAF371DA32120 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0FB4F07A37999BBC6DFE4DBB; + remoteInfo = "Listless macOS"; + }; 642EE6A5908DB4216F049E9C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 3256C2BF8F1DAF371DA32120 /* Project object */; @@ -176,6 +189,7 @@ A2EF927F09D67532F44BB80D /* TaskRowMetrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskRowMetrics.swift; sourceTree = "<group>"; }; AC245331D715EA85887C0BA0 /* ListlessiOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListlessiOSApp.swift; sourceTree = "<group>"; }; B7588879D0FA1C2A8BCEF14F /* HoverCursorModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoverCursorModifier.swift; sourceTree = "<group>"; }; + B88DC6E36FA41DCB6CEB9647 /* Listless macOS Unit Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Listless macOS Unit Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; BAE264D30C7692457B92E518 /* KeyValueSyncBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueSyncBridge.swift; sourceTree = "<group>"; }; BC845482926A73B0BF820328 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; BFF7D84B54AE70036D205CA4 /* PullToCreate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PullToCreate.swift; sourceTree = "<group>"; }; @@ -240,6 +254,7 @@ children = ( C71466C5CD1A5BA984352F8D /* Listless iOS Unit Tests.xctest */, 126108860D7878DDC3BECC4B /* Listless iOS.app */, + B88DC6E36FA41DCB6CEB9647 /* Listless macOS Unit Tests.xctest */, 5B0E22B8F7B2B7283CAF749E /* Listless macOS.app */, C6812E535A24C599C28F9278 /* Listless watchOS.app */, ); @@ -485,6 +500,24 @@ productReference = 126108860D7878DDC3BECC4B /* Listless iOS.app */; productType = "com.apple.product-type.application"; }; + 7F0B17D1EC9FD4A80BC99002 /* Listless macOS Unit Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D6218056DB7B3D1C0ACF1443 /* Build configuration list for PBXNativeTarget "Listless macOS Unit Tests" */; + buildPhases = ( + 0421851ACA269BDB6CCA11C0 /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + A71FF92EBBB4C01F921B128B /* PBXTargetDependency */, + ); + name = "Listless macOS Unit Tests"; + packageProductDependencies = ( + ); + productName = "Listless macOS Unit Tests"; + productReference = B88DC6E36FA41DCB6CEB9647 /* Listless macOS Unit Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 9BDC1B2175AB9CE26790448D /* Listless watchOS */ = { isa = PBXNativeTarget; buildConfigurationList = A549D68557611D588CB834B2 /* Build configuration list for PBXNativeTarget "Listless watchOS" */; @@ -538,6 +571,10 @@ DevelopmentTeam = 7TD7PZBNXP; ProvisioningStyle = Automatic; }; + 7F0B17D1EC9FD4A80BC99002 = { + DevelopmentTeam = 7TD7PZBNXP; + ProvisioningStyle = Automatic; + }; 9BDC1B2175AB9CE26790448D = { DevelopmentTeam = 7TD7PZBNXP; ProvisioningStyle = Automatic; @@ -565,6 +602,7 @@ 34A03D42B91730DEAC2EBD8E /* Listless iOS */, D533FDEDCE6DFCA2E8CB70F5 /* Listless iOS Unit Tests */, 0FB4F07A37999BBC6DFE4DBB /* Listless macOS */, + 7F0B17D1EC9FD4A80BC99002 /* Listless macOS Unit Tests */, 9BDC1B2175AB9CE26790448D /* Listless watchOS */, ); }; @@ -599,6 +637,19 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 0421851ACA269BDB6CCA11C0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A10BF9D0C850105E4FA1A2AD /* CloudKitErrorClassifierTests.swift in Sources */, + 8FA8398315B67F12EA25FA35 /* TaskStoreCompletionTests.swift in Sources */, + 54FCE72978F20AA64855B521 /* TaskStoreEdgeCaseTests.swift in Sources */, + CDE538A0B3CA14B1CB421ED8 /* TaskStoreOrderingTests.swift in Sources */, + E14F8177232BBC75FEEE1E2C /* TaskStoreTests.swift in Sources */, + E12C1304464FC7799856B2BA /* TestHelpers.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 409D108909CBEC2F69B56D0E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -721,9 +772,32 @@ target = 9BDC1B2175AB9CE26790448D /* Listless watchOS */; targetProxy = 642EE6A5908DB4216F049E9C /* PBXContainerItemProxy */; }; + A71FF92EBBB4C01F921B128B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0FB4F07A37999BBC6DFE4DBB /* Listless macOS */; + targetProxy = 1CECC2E7FCB78843443C0C46 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 05B5A346110EC651C700E86E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = net.inqk.listless.macos.unittests; + SDKROOT = macosx; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Listless.app/Contents/MacOS/Listless"; + }; + name = Release; + }; 2D4E3CC5FF8E6299F754CCFC /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -873,6 +947,24 @@ }; name = Debug; }; + CF2E8B9803D045F7F301E05E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = net.inqk.listless.macos.unittests; + SDKROOT = macosx; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Listless.app/Contents/MacOS/Listless"; + }; + name = Debug; + }; D1B900A3E25ED5B39F0D9716 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = D43D37CE25806380C0B13466 /* BuildNumber.xcconfig */; @@ -1047,6 +1139,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; + D6218056DB7B3D1C0ACF1443 /* Build configuration list for PBXNativeTarget "Listless macOS Unit Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CF2E8B9803D045F7F301E05E /* Debug */, + 05B5A346110EC651C700E86E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ diff --git a/Listless.xcodeproj/xcshareddata/xcschemes/Listless macOS.xcscheme b/Listless.xcodeproj/xcshareddata/xcschemes/Listless macOS.xcscheme @@ -55,6 +55,18 @@ </BuildableReference> </MacroExpansion> <Testables> + <TestableReference + skipped = "NO" + parallelizable = "YES" + testExecutionOrdering = "random"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "7F0B17D1EC9FD4A80BC99002" + BuildableName = "Listless macOS Unit Tests.xctest" + BlueprintName = "Listless macOS Unit Tests" + ReferencedContainer = "container:Listless.xcodeproj"> + </BuildableReference> + </TestableReference> </Testables> </TestAction> <LaunchAction diff --git a/Tests/Support/TestHelpers.swift b/Tests/Support/TestHelpers.swift @@ -1,7 +1,11 @@ import Foundation import Testing +#if os(macOS) +@testable import Listless +#else @testable import Listless_iOS +#endif /// Creates a fresh TaskStore with in-memory persistence for isolated testing. @MainActor diff --git a/Tests/Unit/CloudKitErrorClassifierTests.swift b/Tests/Unit/CloudKitErrorClassifierTests.swift @@ -2,7 +2,11 @@ import CloudKit import Foundation import Testing +#if os(macOS) +@testable import Listless +#else @testable import Listless_iOS +#endif @Suite("CloudKitErrorClassifier") struct CloudKitErrorClassifierTests { diff --git a/Tests/Unit/TaskStoreCompletionTests.swift b/Tests/Unit/TaskStoreCompletionTests.swift @@ -1,7 +1,11 @@ import Foundation import Testing +#if os(macOS) +@testable import Listless +#else @testable import Listless_iOS +#endif @Suite("TaskStore Completion Behavior", .serialized) @MainActor diff --git a/Tests/Unit/TaskStoreEdgeCaseTests.swift b/Tests/Unit/TaskStoreEdgeCaseTests.swift @@ -2,7 +2,11 @@ import Foundation import CoreData import Testing +#if os(macOS) +@testable import Listless +#else @testable import Listless_iOS +#endif @Suite("TaskStore Edge Cases", .serialized) @MainActor diff --git a/Tests/Unit/TaskStoreOrderingTests.swift b/Tests/Unit/TaskStoreOrderingTests.swift @@ -1,7 +1,11 @@ import Foundation import Testing +#if os(macOS) +@testable import Listless +#else @testable import Listless_iOS +#endif @Suite("TaskStore Task Reordering", .serialized) @MainActor diff --git a/Tests/Unit/TaskStoreTests.swift b/Tests/Unit/TaskStoreTests.swift @@ -1,7 +1,11 @@ import Foundation import Testing +#if os(macOS) +@testable import Listless +#else @testable import Listless_iOS +#endif @Suite("TaskStore CRUD Operations", .serialized) @MainActor diff --git a/project.yml b/project.yml @@ -161,6 +161,21 @@ targets: BUNDLE_LOADER: $(TEST_HOST) GENERATE_INFOPLIST_FILE: YES + Listless macOS Unit Tests: + type: bundle.unit-test + platform: macOS + sources: + - Tests/Unit + - Tests/Support + dependencies: + - target: Listless macOS + settings: + PRODUCT_BUNDLE_IDENTIFIER: net.inqk.listless.macos.unittests + CODE_SIGN_STYLE: Automatic + TEST_HOST: $(BUILT_PRODUCTS_DIR)/Listless.app/Contents/MacOS/Listless + BUNDLE_LOADER: $(TEST_HOST) + GENERATE_INFOPLIST_FILE: YES + schemes: Listless iOS: build: @@ -201,6 +216,12 @@ schemes: settingsTarget: Listless macOS run: config: Debug + test: + config: Debug + targets: + - name: Listless macOS Unit Tests + parallelizable: true + randomExecutionOrder: true profile: config: Release analyze: