Skip to content

Commit fe1cd9f

Browse files
author
Ivo Silva
committed
Distinguish between section mutations and item mutations
1 parent d9e58fe commit fe1cd9f

File tree

2 files changed

+120
-24
lines changed

2 files changed

+120
-24
lines changed

FlexibleDiff/SectionedChangeset.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,10 @@ public struct SectionedChangeset {
126126
identifier: itemIdentifier,
127127
areEqual: areItemsEqual)
128128

129-
let isMutated = !changeset.hasNoChanges
130-
|| metadata.mutations.contains(sourceOffset)
129+
let isMutatedMetadata = metadata.mutations.contains(sourceOffset)
131130
|| mutatedMoveDests.contains(destinationOffset)
132131

133-
if isMutated {
132+
if changeset.hasNoChanges == false {
134133
let section = SectionedChangeset.MutatedSection(source: sourceOffset,
135134
destination: destinationOffset,
136135
changeset: changeset)
@@ -140,8 +139,8 @@ public struct SectionedChangeset {
140139
if isMove {
141140
moves.append(Changeset.Move(source: sourceOffset,
142141
destination: destinationOffset,
143-
isMutated: isMutated))
144-
} else if isMutated {
142+
isMutated: isMutatedMetadata))
143+
} else if isMutatedMetadata {
145144
mutations.insert(sourceOffset)
146145
}
147146
}

FlexibleDiffTests/SectionedChangesetSpec.swift

Lines changed: 116 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class SectionedChangesetSpec: QuickSpec {
130130
}
131131

132132
describe("mutation") {
133-
it("should reflect a mutated section") {
133+
it("should only reflect a mutation in the section's items") {
134134
diffTest(
135135
previous: [
136136
Section(identifier: "A", items: [])
@@ -140,6 +140,44 @@ class SectionedChangesetSpec: QuickSpec {
140140
Section.Item(identifier: "A0", value: .max)
141141
])
142142
],
143+
expected: SectionedChangeset(
144+
sections: Changeset(),
145+
mutatedSections: [
146+
SectionedChangeset.MutatedSection(
147+
source: 0,
148+
destination: 0,
149+
changeset: Changeset(inserts: [0])
150+
)
151+
]
152+
)
153+
)
154+
}
155+
156+
it("should only reflect a mutation in the section") {
157+
diffTest(
158+
previous: [
159+
Section(identifier: "A", metadata: "old", items: [])
160+
],
161+
current: [
162+
Section(identifier: "A", metadata: "new", items: [])
163+
],
164+
expected: SectionedChangeset(
165+
sections: Changeset(mutations: [0]),
166+
mutatedSections: []
167+
)
168+
)
169+
}
170+
171+
it("should reflect a mutation in the section and its items") {
172+
diffTest(
173+
previous: [
174+
Section(identifier: "A", metadata: "old", items: [])
175+
],
176+
current: [
177+
Section(identifier: "A", metadata: "new", items: [
178+
Section.Item(identifier: "A0", value: .max)
179+
])
180+
],
143181
expected: SectionedChangeset(
144182
sections: Changeset(mutations: [0]),
145183
mutatedSections: [
@@ -177,7 +215,30 @@ class SectionedChangesetSpec: QuickSpec {
177215
)
178216
}
179217

180-
it("should reflect a section moved with mutations made") {
218+
it("should reflect a section moved with one section mutation") {
219+
diffTest(
220+
previous: [
221+
Section(identifier: "A", metadata: "old", items: []),
222+
Section(identifier: "B", metadata: "old", items: []),
223+
Section(identifier: "C", metadata: "old", items: [])
224+
],
225+
current: [
226+
Section(identifier: "C", metadata: "old", items: []),
227+
Section(identifier: "B", metadata: "old", items: []),
228+
Section(identifier: "A", metadata: "new", items: [])
229+
],
230+
expected: SectionedChangeset(
231+
sections: Changeset(moves: [
232+
Changeset.Move(source: 0, destination: 2, isMutated: true),
233+
Changeset.Move(source: 2, destination: 0, isMutated: false)
234+
]),
235+
mutatedSections: []
236+
)
237+
)
238+
}
239+
240+
241+
it("should reflect a section moved with item mutations made") {
181242
diffTest(
182243
previous: [
183244
Section(identifier: "A", items: [
@@ -200,8 +261,8 @@ class SectionedChangesetSpec: QuickSpec {
200261
],
201262
expected: SectionedChangeset(
202263
sections: Changeset(moves: [
203-
Changeset.Move(source: 0, destination: 2, isMutated: true),
204-
Changeset.Move(source: 2, destination: 0, isMutated: true)
264+
Changeset.Move(source: 0, destination: 2, isMutated: false),
265+
Changeset.Move(source: 2, destination: 0, isMutated: false)
205266
]),
206267
mutatedSections: [
207268
SectionedChangeset.MutatedSection(
@@ -219,7 +280,49 @@ class SectionedChangesetSpec: QuickSpec {
219280
)
220281
}
221282

222-
it("should reflect a section moved with mutations made to replace a removal") {
283+
it("should reflect a section moved with section and item mutations") {
284+
diffTest(
285+
previous: [
286+
Section(identifier: "A", metadata: "old", items: [
287+
Section.Item(identifier: "A0", value: .max)
288+
]),
289+
Section(identifier: "B", metadata: "old", items: []),
290+
Section(identifier: "C", metadata: "old", items: [
291+
Section.Item(identifier: "C0", value: .min)
292+
])
293+
],
294+
current: [
295+
Section(identifier: "C", metadata: "old", items: [
296+
Section.Item(identifier: "C1", value: .max),
297+
Section.Item(identifier: "C0", value: .min)
298+
]),
299+
Section(identifier: "B", metadata: "old", items: []),
300+
Section(identifier: "A", metadata: "new", items: [
301+
Section.Item(identifier: "A1", value: .min)
302+
])
303+
],
304+
expected: SectionedChangeset(
305+
sections: Changeset(moves: [
306+
Changeset.Move(source: 0, destination: 2, isMutated: true),
307+
Changeset.Move(source: 2, destination: 0, isMutated: false)
308+
]),
309+
mutatedSections: [
310+
SectionedChangeset.MutatedSection(
311+
source: 0,
312+
destination: 2,
313+
changeset: Changeset(inserts: [0], removals: [0])
314+
),
315+
SectionedChangeset.MutatedSection(
316+
source: 2,
317+
destination: 0,
318+
changeset: Changeset(inserts: [0])
319+
)
320+
]
321+
)
322+
)
323+
}
324+
325+
it("should reflect a section moved with item mutations made to replace a removal") {
223326
diffTest(
224327
previous: [
225328
Section(identifier: "A", items: [
@@ -241,7 +344,7 @@ class SectionedChangesetSpec: QuickSpec {
241344
sections: Changeset(
242345
removals: [0],
243346
moves: [
244-
Changeset.Move(source: 2, destination: 0, isMutated: true)
347+
Changeset.Move(source: 2, destination: 0, isMutated: false)
245348
]
246349
),
247350
mutatedSections: [
@@ -308,8 +411,10 @@ private func reproducibilityTest(
308411

309412
let allRemovals = changeset.sections.removals
310413
.union(IndexSet(changeset.sections.moves.map { $0.source }))
311-
let allInsertions: [(Int?, Int)] = [changeset.sections.inserts.map { (nil, $0) },
312-
changeset.sections.moves.map { ($0.source as Int?, $0.destination) }]
414+
let allInsertions: [(Int?, Int)] = [
415+
changeset.sections.inserts.map { (nil, $0) },
416+
changeset.sections.moves.map { ($0.isMutated ? nil : $0.source, $0.destination) }
417+
]
313418
.flatMap { $0 }
314419
.sorted { lhs, rhs in lhs.1 < rhs.1 }
315420

@@ -325,19 +430,11 @@ private func reproducibilityTest(
325430
}
326431
}
327432

328-
let mutatedMoves = Set(changeset.sections.moves.lazy
329-
.filter { $0.isMutated }
330-
.compactMap { Tuple2($0.source, $0.destination) })
331-
let mutatedSections = Set(changeset.sections.mutations.map { Tuple2($0, $0) })
332-
.union(mutatedMoves)
333-
let records = Set(changeset.mutatedSections.map { Tuple2($0.source, $0.destination) })
334-
335-
// [BUG] It seems occasionally `Set.==` is not being picked up.
336-
// Nimble 7.3.1.
337-
expect(records).to(equal(mutatedSections))
433+
for index in changeset.sections.mutations {
434+
values[index].metadata = current[index].metadata
435+
}
338436

339437
for record in changeset.mutatedSections {
340-
values[record.destination].metadata = current[record.destination].metadata
341438
values[record.destination].items = reproduce(applying: record.changeset,
342439
to: values[record.destination].items,
343440
expecting: current[record.destination].items,

0 commit comments

Comments
 (0)