diff --git a/Music.xcodeproj/project.pbxproj b/Music.xcodeproj/project.pbxproj
index 261c04e..a8ed464 100644
--- a/Music.xcodeproj/project.pbxproj
+++ b/Music.xcodeproj/project.pbxproj
@@ -29,7 +29,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
- C46B2C8D2FC2448700F95A24 /* Music.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Music.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ C46B2C8D2FC2448700F95A24 /* Mumu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Mumu.app; sourceTree = BUILT_PRODUCTS_DIR; };
C46B2C9A2FC2448800F95A24 /* MusicTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MusicTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C46B2CA42FC2448800F95A24 /* MusicUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MusicUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -108,7 +108,7 @@
C46B2C8E2FC2448700F95A24 /* Products */ = {
isa = PBXGroup;
children = (
- C46B2C8D2FC2448700F95A24 /* Music.app */,
+ C46B2C8D2FC2448700F95A24 /* Mumu.app */,
C46B2C9A2FC2448800F95A24 /* MusicTests.xctest */,
C46B2CA42FC2448800F95A24 /* MusicUITests.xctest */,
);
@@ -138,7 +138,7 @@
C46B2CBF2FC2449900F95A24 /* GRDB */,
);
productName = Music;
- productReference = C46B2C8D2FC2448700F95A24 /* Music.app */;
+ productReference = C46B2C8D2FC2448700F95A24 /* Mumu.app */;
productType = "com.apple.product-type.application";
};
C46B2C992FC2448800F95A24 /* MusicTests */ = {
@@ -426,13 +426,14 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = 526E96RFNP;
ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
ENABLE_USER_SELECTED_FILES = readonly;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_CFBundleDisplayName = Mumu;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "Music uses the microphone to identify songs with Shazam.";
@@ -442,7 +443,8 @@
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.mu;
- PRODUCT_NAME = "$(TARGET_NAME)";
+ PRODUCT_MODULE_NAME = Music;
+ PRODUCT_NAME = Mumu;
REGISTER_APP_GROUPS = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
@@ -462,13 +464,14 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 8;
DEVELOPMENT_TEAM = 526E96RFNP;
ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
ENABLE_USER_SELECTED_FILES = readonly;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_CFBundleDisplayName = Mumu;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "Music uses the microphone to identify songs with Shazam.";
@@ -478,7 +481,8 @@
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.staxriver.mu;
- PRODUCT_NAME = "$(TARGET_NAME)";
+ PRODUCT_MODULE_NAME = Music;
+ PRODUCT_NAME = Mumu;
REGISTER_APP_GROUPS = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
@@ -506,7 +510,7 @@
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Music.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Music";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mumu.app/Contents/MacOS/Mumu";
};
name = Debug;
};
@@ -527,7 +531,7 @@
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Music.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Music";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mumu.app/Contents/MacOS/Mumu";
};
name = Release;
};
diff --git a/Music.xcodeproj/xcshareddata/xcschemes/Music.xcscheme b/Music.xcodeproj/xcshareddata/xcschemes/Music.xcscheme
new file mode 100644
index 0000000..3bccbe6
--- /dev/null
+++ b/Music.xcodeproj/xcshareddata/xcschemes/Music.xcscheme
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Music/Models/SmartPlaylist.swift b/Music/Models/SmartPlaylist.swift
new file mode 100644
index 0000000..62f54e6
--- /dev/null
+++ b/Music/Models/SmartPlaylist.swift
@@ -0,0 +1,34 @@
+import Foundation
+import GRDB
+
+nonisolated struct SmartPlaylist: Codable, Identifiable, Equatable, Hashable, Sendable {
+ var id: Int64?
+ var name: String
+ var searchQuery: String
+ var createdAt: Date
+}
+
+nonisolated extension SmartPlaylist: FetchableRecord, MutablePersistableRecord {
+ static let databaseTableName = "smart_playlists"
+
+ mutating func didInsert(_ inserted: InsertionSuccess) {
+ id = inserted.rowID
+ }
+}
+
+extension SmartPlaylist: PlaylistRepresentable {
+ var isSmartPlaylist: Bool { true }
+}
+
+#if DEBUG
+extension SmartPlaylist {
+ static func fixture(
+ id: Int64? = nil,
+ name: String = "Test Smart Playlist",
+ searchQuery: String = "test query",
+ createdAt: Date = Date()
+ ) -> SmartPlaylist {
+ SmartPlaylist(id: id, name: name, searchQuery: searchQuery, createdAt: createdAt)
+ }
+}
+#endif
diff --git a/Music/Music.entitlements b/Music/Music.entitlements
index 65c81d1..ff87a79 100644
--- a/Music/Music.entitlements
+++ b/Music/Music.entitlements
@@ -4,6 +4,8 @@
com.apple.security.app-sandbox
+ com.apple.security.get-task-allow
+
com.apple.security.files.user-selected.read-only
com.apple.security.files.bookmarks.app-scope
diff --git a/Music/MusicApp.swift b/Music/MusicApp.swift
index 0020b33..587fd16 100644
--- a/Music/MusicApp.swift
+++ b/Music/MusicApp.swift
@@ -78,7 +78,7 @@ struct MusicApp: App {
Task {
await scanner.rescan(url)
}
- } else {
+ } else if !isRunningTests {
DispatchQueue.main.async {
pickFolder()
}
@@ -88,6 +88,10 @@ struct MusicApp: App {
}
}
+ private var isRunningTests: Bool {
+ ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil
+ }
+
private func pickFolder() {
let panel = NSOpenPanel()
panel.canChooseFiles = false
diff --git a/MusicTests/SmartPlaylistTests.swift b/MusicTests/SmartPlaylistTests.swift
new file mode 100644
index 0000000..5d1ce8c
--- /dev/null
+++ b/MusicTests/SmartPlaylistTests.swift
@@ -0,0 +1,18 @@
+import Foundation
+import Testing
+@testable import Music
+
+struct SmartPlaylistTests {
+ // Creates a SmartPlaylist in memory and verifies its properties.
+ @Test func smartPlaylistProperties() throws {
+ let sp = SmartPlaylist(
+ id: nil,
+ name: "Miles Davis",
+ searchQuery: "miles davis",
+ createdAt: Date()
+ )
+ #expect(sp.name == "Miles Davis")
+ #expect(sp.searchQuery == "miles davis")
+ #expect(sp.isSmartPlaylist == true)
+ }
+}