Implement snapshot version history
This commit is contained in:
@@ -324,6 +324,25 @@ public extension SongProject {
|
|||||||
vocalists[index].assignedSections.removeAll { $0 == sectionID }
|
vocalists[index].assignedSections.removeAll { $0 == sectionID }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutating func createVersion(
|
||||||
|
id: String = UUID().uuidString,
|
||||||
|
label: String,
|
||||||
|
createdAt: Date = Date()
|
||||||
|
) -> SongVersion {
|
||||||
|
let version = SongVersion(
|
||||||
|
id: id,
|
||||||
|
label: label,
|
||||||
|
snapshot: SongProjectSnapshot(project: self),
|
||||||
|
createdAt: createdAt
|
||||||
|
)
|
||||||
|
versions.append(version)
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
|
func version(id versionID: String) -> SongVersion? {
|
||||||
|
versions.first { $0.id == versionID }
|
||||||
|
}
|
||||||
|
|
||||||
mutating func appendSection(_ section: SongSection) {
|
mutating func appendSection(_ section: SongSection) {
|
||||||
var orderedSection = section
|
var orderedSection = section
|
||||||
orderedSection.order = nextSectionOrder
|
orderedSection.order = nextSectionOrder
|
||||||
|
|||||||
@@ -89,6 +89,36 @@ final class SongProjectModelTests: XCTestCase {
|
|||||||
XCTAssertEqual(version.snapshot.instruments, project.instruments)
|
XCTAssertEqual(version.snapshot.instruments, project.instruments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testVersionHistoryStoresIndependentSnapshots() {
|
||||||
|
var project = SongProject(
|
||||||
|
id: "versioned-project",
|
||||||
|
title: "First Title",
|
||||||
|
idea: "Original idea",
|
||||||
|
genres: [GenreStyle(id: "folk", name: "Folk")]
|
||||||
|
)
|
||||||
|
let createdAt = Date(timeIntervalSince1970: 500)
|
||||||
|
|
||||||
|
let version = project.createVersion(
|
||||||
|
id: "version-1",
|
||||||
|
label: "Initial snapshot",
|
||||||
|
createdAt: createdAt
|
||||||
|
)
|
||||||
|
|
||||||
|
project.title = "Changed Title"
|
||||||
|
project.idea = "Changed idea"
|
||||||
|
project.selectGenreStyle(GenreStyle(id: "electronic", name: "Electronic"))
|
||||||
|
|
||||||
|
XCTAssertEqual(project.versions.count, 1)
|
||||||
|
XCTAssertEqual(project.version(id: "version-1"), version)
|
||||||
|
XCTAssertEqual(project.versions.first?.label, "Initial snapshot")
|
||||||
|
XCTAssertEqual(project.versions.first?.createdAt, createdAt)
|
||||||
|
XCTAssertEqual(project.versions.first?.snapshot.title, "First Title")
|
||||||
|
XCTAssertEqual(project.versions.first?.snapshot.idea, "Original idea")
|
||||||
|
XCTAssertEqual(project.versions.first?.snapshot.genres, [GenreStyle(id: "folk", name: "Folk")])
|
||||||
|
XCTAssertEqual(project.title, "Changed Title")
|
||||||
|
XCTAssertEqual(project.genres.map(\.id), ["folk", "electronic"])
|
||||||
|
}
|
||||||
|
|
||||||
func testGenreStylesAreModeledAsMultiSelect() {
|
func testGenreStylesAreModeledAsMultiSelect() {
|
||||||
let arabicPop = GenreStyle(id: "arabic-pop", name: "Arabic Pop")
|
let arabicPop = GenreStyle(id: "arabic-pop", name: "Arabic Pop")
|
||||||
let synthwave = GenreStyle(id: "synthwave", name: "Synthwave")
|
let synthwave = GenreStyle(id: "synthwave", name: "Synthwave")
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ requirement is missing and blocks implementation, record it in
|
|||||||
|
|
||||||
- [x] Create new/open/save song projects locally.
|
- [x] Create new/open/save song projects locally.
|
||||||
- [x] Implement project list.
|
- [x] Implement project list.
|
||||||
- [ ] Implement immutable or snapshot-based version history.
|
- [x] Implement immutable or snapshot-based version history.
|
||||||
- [ ] Restore a previous version without destroying later versions.
|
- [ ] Restore a previous version without destroying later versions.
|
||||||
- [ ] Add autosave strategy that does not create excessive versions.
|
- [ ] Add autosave strategy that does not create excessive versions.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user