Skip to content

Commit bd9661a

Browse files
committed
Adds stress tests
1 parent 814ab7c commit bd9661a

File tree

6 files changed

+97
-26
lines changed

6 files changed

+97
-26
lines changed

RxDataSources.xcodeproj/project.pbxproj

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
845F61FB1CCFDED600A8BE32 /* TitleSteperTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845F61FA1CCFDED600A8BE32 /* TitleSteperTableViewCell.swift */; };
1818
845F61FD1CCFF63600A8BE32 /* UIKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845F61FC1CCFF63600A8BE32 /* UIKitExtensions.swift */; };
1919
84FC6BEE1CA4830A00D3C605 /* Example3_TableViewEditing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FC6BED1CA4830A00D3C605 /* Example3_TableViewEditing.swift */; };
20-
888669D71D11F67C008DC240 /* NumberSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C87DF3441D0219A7006308C5 /* NumberSection.swift */; };
21-
888669D81D11F68B008DC240 /* Randomizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C87DF3451D0219A7006308C5 /* Randomizer.swift */; };
2220
888669D91D11F762008DC240 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C87DF3431D0219A7006308C5 /* AppDelegate.swift */; };
2321
9FCDA16B1C3AF4A2000F5F94 /* Changeset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C85EE5481C36F1FC0090614D /* Changeset.swift */; };
2422
9FCDA16C1C3AF4A2000F5F94 /* CollectionViewSectionedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C85EE5491C36F1FC0090614D /* CollectionViewSectionedDataSource.swift */; };
@@ -52,6 +50,10 @@
5250
C8595DAB1DEA3DB000FA20CD /* i.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8595DAA1DEA3DB000FA20CD /* i.swift */; };
5351
C8595DAD1DEA3DB900FA20CD /* s.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8595DAC1DEA3DB900FA20CD /* s.swift */; };
5452
C8595DB11DEA494500FA20CD /* XCTest+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8595DB01DEA494500FA20CD /* XCTest+Extensions.swift */; };
53+
C8595DB51DEA66E500FA20CD /* NumberSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8595DB31DEA66E500FA20CD /* NumberSection.swift */; };
54+
C8595DB61DEA66E500FA20CD /* NumberSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8595DB31DEA66E500FA20CD /* NumberSection.swift */; };
55+
C8595DB71DEA66E500FA20CD /* Randomizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8595DB41DEA66E500FA20CD /* Randomizer.swift */; };
56+
C8595DB81DEA66E500FA20CD /* Randomizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8595DB41DEA66E500FA20CD /* Randomizer.swift */; };
5557
C85EE5571C36F1FC0090614D /* Changeset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C85EE5481C36F1FC0090614D /* Changeset.swift */; };
5658
C85EE5581C36F1FC0090614D /* CollectionViewSectionedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C85EE5491C36F1FC0090614D /* CollectionViewSectionedDataSource.swift */; };
5759
C85EE55A1C36F1FC0090614D /* Differentiator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C85EE54B1C36F1FC0090614D /* Differentiator.swift */; };
@@ -63,8 +65,6 @@
6365
C85EE5621C36F1FC0090614D /* RxTableViewSectionedAnimatedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C85EE5541C36F1FC0090614D /* RxTableViewSectionedAnimatedDataSource.swift */; };
6466
C85EE5631C36F1FC0090614D /* RxTableViewSectionedReloadDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C85EE5551C36F1FC0090614D /* RxTableViewSectionedReloadDataSource.swift */; };
6567
C87DF3461D0219A7006308C5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C87DF3431D0219A7006308C5 /* AppDelegate.swift */; };
66-
C87DF3471D0219A7006308C5 /* NumberSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C87DF3441D0219A7006308C5 /* NumberSection.swift */; };
67-
C87DF3481D0219A7006308C5 /* Randomizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C87DF3451D0219A7006308C5 /* Randomizer.swift */; };
6868
C8984C5E1C36AF35001E4272 /* RxDataSources.h in Headers */ = {isa = PBXBuildFile; fileRef = C8984C5D1C36AF35001E4272 /* RxDataSources.h */; settings = {ATTRIBUTES = (Public, ); }; };
6969
C8984CA01C36B6FA001E4272 /* Example2_RandomizedSectionsAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8984C9F1C36B6FA001E4272 /* Example2_RandomizedSectionsAnimation.swift */; };
7070
C8984CA31C36B6FA001E4272 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C8984CA11C36B6FA001E4272 /* Main.storyboard */; };
@@ -224,6 +224,8 @@
224224
C8595DAA1DEA3DB000FA20CD /* i.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = i.swift; sourceTree = "<group>"; };
225225
C8595DAC1DEA3DB900FA20CD /* s.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = s.swift; sourceTree = "<group>"; };
226226
C8595DB01DEA494500FA20CD /* XCTest+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "XCTest+Extensions.swift"; sourceTree = "<group>"; };
227+
C8595DB31DEA66E500FA20CD /* NumberSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberSection.swift; sourceTree = "<group>"; };
228+
C8595DB41DEA66E500FA20CD /* Randomizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Randomizer.swift; sourceTree = "<group>"; };
227229
C85EE5481C36F1FC0090614D /* Changeset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Changeset.swift; sourceTree = "<group>"; };
228230
C85EE5491C36F1FC0090614D /* CollectionViewSectionedDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewSectionedDataSource.swift; sourceTree = "<group>"; };
229231
C85EE54B1C36F1FC0090614D /* Differentiator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Differentiator.swift; sourceTree = "<group>"; };
@@ -235,8 +237,6 @@
235237
C85EE5541C36F1FC0090614D /* RxTableViewSectionedAnimatedDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewSectionedAnimatedDataSource.swift; sourceTree = "<group>"; };
236238
C85EE5551C36F1FC0090614D /* RxTableViewSectionedReloadDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewSectionedReloadDataSource.swift; sourceTree = "<group>"; };
237239
C87DF3431D0219A7006308C5 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
238-
C87DF3441D0219A7006308C5 /* NumberSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberSection.swift; sourceTree = "<group>"; };
239-
C87DF3451D0219A7006308C5 /* Randomizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Randomizer.swift; sourceTree = "<group>"; };
240240
C8984C5A1C36AF35001E4272 /* RxDataSources.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxDataSources.framework; sourceTree = BUILT_PRODUCTS_DIR; };
241241
C8984C5D1C36AF35001E4272 /* RxDataSources.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RxDataSources.h; sourceTree = "<group>"; };
242242
C8984C5F1C36AF35001E4272 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -397,13 +397,15 @@
397397
C81905AF1DEA019100AE679C /* Tests */ = {
398398
isa = PBXGroup;
399399
children = (
400+
C8595DB31DEA66E500FA20CD /* NumberSection.swift */,
401+
C8595DB41DEA66E500FA20CD /* Randomizer.swift */,
400402
C81905B91DEA0BD700AE679C /* ChangeSet+TestExtensions.swift */,
401403
C81905BD1DEA104400AE679C /* Array+Extensions.swift */,
402404
C8595DA81DEA3D4800FA20CD /* AlgorithmTests.swift */,
403405
C8595DAA1DEA3DB000FA20CD /* i.swift */,
404406
C8595DAC1DEA3DB900FA20CD /* s.swift */,
405-
C81905B21DEA019100AE679C /* Info.plist */,
406407
C8595DB01DEA494500FA20CD /* XCTest+Extensions.swift */,
408+
C81905B21DEA019100AE679C /* Info.plist */,
407409
);
408410
path = Tests;
409411
sourceTree = "<group>";
@@ -459,8 +461,6 @@
459461
isa = PBXGroup;
460462
children = (
461463
C87DF3431D0219A7006308C5 /* AppDelegate.swift */,
462-
C87DF3441D0219A7006308C5 /* NumberSection.swift */,
463-
C87DF3451D0219A7006308C5 /* Randomizer.swift */,
464464
);
465465
path = Support;
466466
sourceTree = "<group>";
@@ -969,8 +969,10 @@
969969
C81905BA1DEA0BD700AE679C /* ChangeSet+TestExtensions.swift in Sources */,
970970
C8595DAD1DEA3DB900FA20CD /* s.swift in Sources */,
971971
C8595DB11DEA494500FA20CD /* XCTest+Extensions.swift in Sources */,
972+
C8595DB61DEA66E500FA20CD /* NumberSection.swift in Sources */,
972973
C81905BE1DEA104400AE679C /* Array+Extensions.swift in Sources */,
973974
C8595DA91DEA3D4800FA20CD /* AlgorithmTests.swift in Sources */,
975+
C8595DB81DEA66E500FA20CD /* Randomizer.swift in Sources */,
974976
C8595DAB1DEA3DB000FA20CD /* i.swift in Sources */,
975977
);
976978
runOnlyForDeploymentPostprocessing = 0;
@@ -1010,12 +1012,12 @@
10101012
isa = PBXSourcesBuildPhase;
10111013
buildActionMask = 2147483647;
10121014
files = (
1013-
C87DF3471D0219A7006308C5 /* NumberSection.swift in Sources */,
1015+
C8595DB51DEA66E500FA20CD /* NumberSection.swift in Sources */,
10141016
845F61F71CCFDE6A00A8BE32 /* ImageTitleTableViewCell.swift in Sources */,
10151017
84FC6BEE1CA4830A00D3C605 /* Example3_TableViewEditing.swift in Sources */,
10161018
C8984CA01C36B6FA001E4272 /* Example2_RandomizedSectionsAnimation.swift in Sources */,
10171019
C87DF3461D0219A7006308C5 /* AppDelegate.swift in Sources */,
1018-
C87DF3481D0219A7006308C5 /* Randomizer.swift in Sources */,
1020+
C8595DB71DEA66E500FA20CD /* Randomizer.swift in Sources */,
10191021
845F61F41CCFD96800A8BE32 /* Example4_DifferentSectionAndItemTypes.swift in Sources */,
10201022
845F61FB1CCFDED600A8BE32 /* TitleSteperTableViewCell.swift in Sources */,
10211023
845F61F91CCFDEA800A8BE32 /* TitleSwitchTableViewCell.swift in Sources */,
@@ -1043,9 +1045,7 @@
10431045
C8EBA5E81CD3DDF400E745F3 /* Example4_DifferentSectionAndItemTypes.swift in Sources */,
10441046
C8EBA5EB1CD3DE0A00E745F3 /* TitleSteperTableViewCell.swift in Sources */,
10451047
C8EBA5EA1CD3DE0A00E745F3 /* TitleSwitchTableViewCell.swift in Sources */,
1046-
888669D81D11F68B008DC240 /* Randomizer.swift in Sources */,
10471048
C8153A511CC6C2F70050C990 /* Example1_CustomizationUsingTableViewDelegate.swift in Sources */,
1048-
888669D71D11F67C008DC240 /* NumberSection.swift in Sources */,
10491049
C8EBA5EC1CD3DE0A00E745F3 /* UIKitExtensions.swift in Sources */,
10501050
);
10511051
runOnlyForDeploymentPostprocessing = 0;

Tests/AlgorithmTests.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,5 +540,34 @@ extension AlgorithmTests {
540540

541541
// stress test
542542
extension AlgorithmTests {
543-
543+
func testStress() {
544+
func initialValue() -> [NumberSection] {
545+
let nSections = 100
546+
let nItems = 100
547+
548+
/*
549+
let nSections = 10
550+
let nItems = 2
551+
*/
552+
553+
return (0 ..< nSections).map { (i: Int) in
554+
let items = Array(i * nItems ..< (i + 1) * nItems).map { IntItem(number: $0, date: Date.distantPast) }
555+
return NumberSection(header: "Section \(i + 1)", numbers: items, updated: Date.distantPast)
556+
}
557+
}
558+
559+
let initialRandomizedSections = Randomizer(rng: PseudoRandomGenerator(4, 3), sections: initialValue())
560+
561+
var sections = initialRandomizedSections
562+
for i in 0 ..< 1000 {
563+
if i % 100 == 0 {
564+
print(i)
565+
}
566+
let newSections = sections.randomize()
567+
let differences = try! differencesForSectionedView(sections.sections, finalSections: newSections.sections)
568+
569+
XCTAssertEqual(sections.sections.apply(differences), newSections.sections)
570+
sections = newSections
571+
}
572+
}
544573
}

Tests/ChangeSet+TestExtensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ extension SectionModelTypeWrapper {
248248
}
249249
}
250250

251-
extension Array where Element: SectionModelType, Element: Equatable {
251+
extension Array where Element: AnimatableSectionModelType, Element: Equatable {
252252

253253
func apply(_ changes: [Changeset<Element>]) -> [Element] {
254254
return changes.reduce(self) { sections, changes in

Example/Support/NumberSection.swift renamed to Tests/NumberSection.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ struct NumberSection {
2525
}
2626
}
2727

28-
2928
struct IntItem {
3029
let number: Int
3130
let date: Date
@@ -55,7 +54,9 @@ extension NumberSection
5554
extension NumberSection
5655
: CustomDebugStringConvertible {
5756
var debugDescription: String {
58-
return "NumberSection(header: \"\(self.header)\", numbers: \(numbers.debugDescription), updated: date)"
57+
let interval = updated.timeIntervalSince1970
58+
let numbersDescription = numbers.map { "\n\($0.debugDescription)" }.joined(separator: "")
59+
return "NumberSection(header: \"\(self.header)\", numbers: \(numbersDescription)\n, updated: \(interval))"
5960
}
6061
}
6162

@@ -78,7 +79,7 @@ func == (lhs: IntItem, rhs: IntItem) -> Bool {
7879
extension IntItem
7980
: CustomDebugStringConvertible {
8081
var debugDescription: String {
81-
return "IntItem(number: \(number), date: date)"
82+
return "IntItem(number: \(number), date: \(date.timeIntervalSince1970))"
8283
}
8384
}
8485

@@ -89,3 +90,11 @@ extension IntItem
8990
return "\(number)"
9091
}
9192
}
93+
94+
extension NumberSection: Equatable {
95+
96+
}
97+
98+
func == (lhs: NumberSection, rhs: NumberSection) -> Bool {
99+
return lhs.header == rhs.header && lhs.items == rhs.items && lhs.updated == rhs.updated
100+
}

Example/Support/Randomizer.swift renamed to Tests/Randomizer.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ struct Randomizer {
4444

4545
let unusedItems: [IntItem]
4646
let unusedSections: [String]
47+
let dateCounter: Int
4748

48-
init(rng: PseudoRandomGenerator, sections: [NumberSection], unusedItems: [IntItem] = [], unusedSections: [String] = []) {
49+
init(rng: PseudoRandomGenerator, sections: [NumberSection], unusedItems: [IntItem] = [], unusedSections: [String] = [], dateCounter: Int = 0) {
4950
self.rng = rng
5051
self.sections = sections
5152

5253
self.unusedSections = unusedSections
5354
self.unusedItems = unusedItems
55+
self.dateCounter = dateCounter
5456
}
5557

5658
func countTotalItems(sections: [NumberSection]) -> Int {
@@ -70,11 +72,11 @@ struct Randomizer {
7072

7173
(nextRng, randomValue) = nextRng.get_random()
7274

73-
let date = Date()
75+
let date = Date(timeIntervalSince1970: TimeInterval(dateCounter))
7476

7577
// update updates in current items if needed
7678
var sections = self.sections.map {
77-
updateDates ? NumberSection(header: $0.header, numbers: $0.numbers.map { x in IntItem(number: x.number, date: date) }, updated: date) : $0
79+
updateDates ? NumberSection(header: $0.header, numbers: $0.numbers.map { x in IntItem(number: x.number, date: date) }, updated: Date.distantPast) : $0
7880
}
7981

8082
let currentUnusedItems = self.unusedItems.map {
@@ -93,7 +95,7 @@ struct Randomizer {
9395
(nextRng, randomValue) = nextRng.get_random()
9496
let index = randomValue % (sections.count + 1)
9597
if insertSections {
96-
sections.insert(NumberSection(header: section, numbers: [], updated: Date()), at: index)
98+
sections.insert(NumberSection(header: section, numbers: [], updated: Date.distantPast), at: index)
9799
}
98100
else {
99101
nextUnusedSections.append(section)
@@ -249,6 +251,11 @@ struct Randomizer {
249251
assert(countTotalItems(sections: sections) + nextUnusedItems.count == startItemCount)
250252
assert(sections.count + nextUnusedSections.count == startSectionCount)
251253

252-
return Randomizer(rng: nextRng, sections: sections, unusedItems: nextUnusedItems, unusedSections: nextUnusedSections)
254+
return Randomizer(
255+
rng: nextRng,
256+
sections: sections,
257+
unusedItems: nextUnusedItems,
258+
unusedSections: nextUnusedSections,
259+
dateCounter: dateCounter + 1)
253260
}
254261
}

Tests/XCTest+Extensions.swift

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import Foundation
1010
import XCTest
1111
import RxDataSources
1212

13-
func XCAssertEqual<S: SectionModelType where S: Equatable>(_ lhs: [S], _ rhs: [S], file: StaticString = #file, line: UInt = #line) {
13+
func XCAssertEqual<S: AnimatableSectionModelType where S: Equatable>(_ lhs: [S], _ rhs: [S], file: StaticString = #file, line: UInt = #line) {
1414
let areEqual = lhs == rhs
1515
if !areEqual {
16-
printSequenceDifferences(lhs, rhs, { $0 == $1 })
16+
printSectionModelDifferences(lhs, rhs)
1717
}
1818

1919
XCTAssertTrue(areEqual, file: file, line: line)
@@ -31,7 +31,7 @@ func == <E: Equatable>(lhs: EquatableArray<E>, rhs: EquatableArray<E>) -> Bool {
3131
}
3232

3333
func printSequenceDifferences<E>(_ lhs: [E], _ rhs: [E], _ equal: (E, E) -> Bool) {
34-
print("Differences:")
34+
print("Differences in sequence:")
3535
for (index, elements) in zip(lhs, rhs).enumerated() {
3636
let l = elements.0
3737
let r = elements.1
@@ -49,3 +49,29 @@ func printSequenceDifferences<E>(_ lhs: [E], _ rhs: [E], _ equal: (E, E) -> Bool
4949
print("rhs[\(index + shortest)]:\n \(element)")
5050
}
5151
}
52+
53+
func printSectionModelDifferences<S: AnimatableSectionModelType where S: Equatable>(_ lhs: [S], _ rhs: [S]) {
54+
print("Differences in sections:")
55+
for (index, elements) in zip(lhs, rhs).enumerated() {
56+
let l = elements.0
57+
let r = elements.1
58+
if l != r {
59+
if l.identity != r.identity {
60+
print("lhs.identity[\(index)] (\(l.identity)) != rhs.identity[\(index)] (\(r.identity))\n")
61+
}
62+
if l.items != r.items {
63+
print("Difference in items for \(l.identity) and \(r.identity)")
64+
printSequenceDifferences(l.items, r.items, { $0 == $1 })
65+
}
66+
}
67+
}
68+
69+
let shortest = min(lhs.count, rhs.count)
70+
for (index, element) in lhs[shortest ..< lhs.count].enumerated() {
71+
print("missing lhs[\(index + shortest)]:\n \(element)")
72+
}
73+
for (index, element) in rhs[shortest ..< rhs.count].enumerated() {
74+
print("missing rhs[\(index + shortest)]:\n \(element)")
75+
}
76+
}
77+

0 commit comments

Comments
 (0)