Skip to content

Commit addbbb0

Browse files
authored
Merge pull request #27 from wokalski/14-NestedDiff
NestedDiff
2 parents 6cc7c09 + bd9b283 commit addbbb0

15 files changed

+1511
-119
lines changed

Diff.xcodeproj/project.pbxproj

+19
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
/* Begin PBXBuildFile section */
1010
900E03A41DE7C6C60033A799 /* Diff.h in Headers */ = {isa = PBXBuildFile; fileRef = C92178BB1CD0023E004642C7 /* Diff.h */; settings = {ATTRIBUTES = (Public, ); }; };
1111
900E03A51DE7C6D60033A799 /* Diff.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9EE87161CCFCA83006BD90E /* Diff.framework */; };
12+
C90CD7171DFB368200BE9114 /* NestedDiff.swift in Sources */ = {isa = PBXBuildFile; fileRef = C90CD7161DFB368200BE9114 /* NestedDiff.swift */; };
13+
C90CD7191DFB43C600BE9114 /* NestedDiffTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C90CD7181DFB43C600BE9114 /* NestedDiffTests.swift */; };
14+
C921BF711E15448300747566 /* NestedExtendedDiffTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C921BF701E15448300747566 /* NestedExtendedDiffTests.swift */; };
1215
C9278ADE1DE32B88009CE846 /* Diff+UIKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9278ADD1DE32B88009CE846 /* Diff+UIKit.swift */; };
1316
C96F41941DE0EEC500B8E135 /* ExtendedPatch+Apply.swift in Sources */ = {isa = PBXBuildFile; fileRef = C96F41931DE0EEC500B8E135 /* ExtendedPatch+Apply.swift */; };
1417
C9838FF41D29571000691BE8 /* DiffTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9838FF31D29571000691BE8 /* DiffTests.swift */; };
@@ -21,6 +24,7 @@
2124
C99118B81DE062BE00067A60 /* GenericPatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C99118B51DE0629000067A60 /* GenericPatch.swift */; };
2225
C9B03FC01DE1CA7500BC6F2A /* ExtendedDiff.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B03FBF1DE1CA7500BC6F2A /* ExtendedDiff.swift */; };
2326
C9C9247A1DBB97130006ACC4 /* PatchSortTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C924791DBB97130006ACC4 /* PatchSortTests.swift */; };
27+
C9D4BC961E1124CE00C79537 /* NestedExtendedDiff.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D4BC951E1124CE00C79537 /* NestedExtendedDiff.swift */; };
2428
C9EE87841CCFFB68006BD90E /* Diff.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EE87821CCFFB68006BD90E /* Diff.swift */; };
2529
C9EE87861CCFFB68006BD90E /* Patch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9EE87831CCFFB68006BD90E /* Patch.swift */; };
2630
/* End PBXBuildFile section */
@@ -29,8 +33,11 @@
2933
900E039F1DE7C3370033A799 /* Universal-Framework-Target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Universal-Framework-Target.xcconfig"; sourceTree = "<group>"; };
3034
900E03A01DE7C3370033A799 /* Universal-Target-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Universal-Target-Base.xcconfig"; sourceTree = "<group>"; };
3135
900E03AF1DE7F1E80033A799 /* Deployment-Targets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Deployment-Targets.xcconfig"; sourceTree = "<group>"; };
36+
C90CD7161DFB368200BE9114 /* NestedDiff.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NestedDiff.swift; sourceTree = "<group>"; };
37+
C90CD7181DFB43C600BE9114 /* NestedDiffTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NestedDiffTests.swift; sourceTree = "<group>"; };
3238
C92178BB1CD0023E004642C7 /* Diff.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Diff.h; path = Framework/Diff.h; sourceTree = "<group>"; };
3339
C92178BD1CD0023E004642C7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Framework/Info.plist; sourceTree = "<group>"; };
40+
C921BF701E15448300747566 /* NestedExtendedDiffTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NestedExtendedDiffTests.swift; sourceTree = "<group>"; };
3441
C9278ADD1DE32B88009CE846 /* Diff+UIKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Diff+UIKit.swift"; sourceTree = "<group>"; };
3542
C96F41931DE0EEC500B8E135 /* ExtendedPatch+Apply.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ExtendedPatch+Apply.swift"; sourceTree = "<group>"; };
3643
C9838FF11D29571000691BE8 /* DiffTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DiffTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -45,6 +52,7 @@
4552
C99118B51DE0629000067A60 /* GenericPatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenericPatch.swift; sourceTree = "<group>"; };
4653
C9B03FBF1DE1CA7500BC6F2A /* ExtendedDiff.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ExtendedDiff.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
4754
C9C924791DBB97130006ACC4 /* PatchSortTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = PatchSortTests.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
55+
C9D4BC951E1124CE00C79537 /* NestedExtendedDiff.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NestedExtendedDiff.swift; sourceTree = "<group>"; };
4856
C9EE87161CCFCA83006BD90E /* Diff.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Diff.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4957
C9EE87821CCFFB68006BD90E /* Diff.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Diff.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
5058
C9EE87831CCFFB68006BD90E /* Patch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Patch.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
@@ -86,6 +94,8 @@
8694
C991189D1DDB4F1100067A60 /* PatchApplyTests.swift */,
8795
C99118AB1DDDAD6E00067A60 /* ExtendedPatchSortTests.swift */,
8896
C9838FF31D29571000691BE8 /* DiffTests.swift */,
97+
C90CD7181DFB43C600BE9114 /* NestedDiffTests.swift */,
98+
C921BF701E15448300747566 /* NestedExtendedDiffTests.swift */,
8999
C9838FF51D29571000691BE8 /* Info.plist */,
90100
);
91101
path = DiffTests;
@@ -116,6 +126,8 @@
116126
children = (
117127
C9EE87821CCFFB68006BD90E /* Diff.swift */,
118128
C9B03FBF1DE1CA7500BC6F2A /* ExtendedDiff.swift */,
129+
C90CD7161DFB368200BE9114 /* NestedDiff.swift */,
130+
C9D4BC951E1124CE00C79537 /* NestedExtendedDiff.swift */,
119131
C9278ADD1DE32B88009CE846 /* Diff+UIKit.swift */,
120132
C9EE87831CCFFB68006BD90E /* Patch.swift */,
121133
C99118971DDB4C3000067A60 /* Patch+Sort.swift */,
@@ -231,6 +243,8 @@
231243
C9C9247A1DBB97130006ACC4 /* PatchSortTests.swift in Sources */,
232244
C9838FF41D29571000691BE8 /* DiffTests.swift in Sources */,
233245
C99118AC1DDDAD6E00067A60 /* ExtendedPatchSortTests.swift in Sources */,
246+
C921BF711E15448300747566 /* NestedExtendedDiffTests.swift in Sources */,
247+
C90CD7191DFB43C600BE9114 /* NestedDiffTests.swift in Sources */,
234248
);
235249
runOnlyForDeploymentPostprocessing = 0;
236250
};
@@ -242,12 +256,14 @@
242256
C99118951DDB1BA800067A60 /* LinkedList.swift in Sources */,
243257
C99118B81DE062BE00067A60 /* GenericPatch.swift in Sources */,
244258
C9EE87861CCFFB68006BD90E /* Patch.swift in Sources */,
259+
C9D4BC961E1124CE00C79537 /* NestedExtendedDiff.swift in Sources */,
245260
C99118981DDB4C3000067A60 /* Patch+Sort.swift in Sources */,
246261
C9278ADE1DE32B88009CE846 /* Diff+UIKit.swift in Sources */,
247262
C991189B1DDB4EAB00067A60 /* Patch+Apply.swift in Sources */,
248263
C96F41941DE0EEC500B8E135 /* ExtendedPatch+Apply.swift in Sources */,
249264
C9EE87841CCFFB68006BD90E /* Diff.swift in Sources */,
250265
C99118B01DDDB02D00067A60 /* ExtendedPatch.swift in Sources */,
266+
C90CD7171DFB368200BE9114 /* NestedDiff.swift in Sources */,
251267
);
252268
runOnlyForDeploymentPostprocessing = 0;
253269
};
@@ -380,6 +396,7 @@
380396
INFOPLIST_FILE = "$(SRCROOT)/Framework/Info.plist";
381397
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
382398
SKIP_INSTALL = YES;
399+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
383400
};
384401
name = Debug;
385402
};
@@ -391,9 +408,11 @@
391408
DYLIB_COMPATIBILITY_VERSION = 1;
392409
DYLIB_CURRENT_VERSION = 1;
393410
DYLIB_INSTALL_NAME_BASE = "@rpath";
411+
GCC_OPTIMIZATION_LEVEL = 0;
394412
INFOPLIST_FILE = "$(SRCROOT)/Framework/Info.plist";
395413
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
396414
SKIP_INSTALL = YES;
415+
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
397416
};
398417
name = Release;
399418
};

DiffTests/NestedDiffTests.swift

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
2+
import XCTest
3+
@testable import Diff
4+
5+
struct KeyedIntArray: Equatable {
6+
let elements: [Int]
7+
let key: Int
8+
9+
public static func ==(fst: KeyedIntArray, snd: KeyedIntArray) -> Bool {
10+
return fst.key == snd.key
11+
}
12+
}
13+
14+
extension Array: Equatable {
15+
public static func ==<T>(fst: Array<T>, snd: Array<T>) -> Bool {
16+
return fst.count == snd.count
17+
}
18+
}
19+
20+
extension KeyedIntArray: Collection {
21+
public func index(after i: Int) -> Int {
22+
return i + 1
23+
}
24+
25+
public typealias IndexType = Array<Int>.Index
26+
27+
public var startIndex: IndexType {
28+
return elements.startIndex
29+
}
30+
31+
public var endIndex: IndexType {
32+
return elements.endIndex
33+
}
34+
35+
public subscript(i: IndexType) -> Int {
36+
return elements[i]
37+
}
38+
}
39+
40+
class NestedDiffTests: XCTestCase {
41+
42+
func testDiffOutputs() {
43+
44+
let keyedExpectations = [
45+
(
46+
[],
47+
[
48+
KeyedIntArray(elements: [1, 2], key: 0),
49+
KeyedIntArray(elements: [1], key: 1),
50+
],
51+
"IS(0)IS(1)"
52+
),
53+
(
54+
[
55+
KeyedIntArray(elements: [2], key: 0),
56+
KeyedIntArray(elements: [1], key: 1),
57+
],
58+
[
59+
KeyedIntArray(elements: [1], key: 0),
60+
KeyedIntArray(elements: [], key: 1),
61+
],
62+
"DE(0,0)IE(0,0)DE(0,1)"
63+
),
64+
(
65+
[
66+
KeyedIntArray(elements: [2], key: 0),
67+
KeyedIntArray(elements: [0], key: 5),
68+
KeyedIntArray(elements: [1], key: 1),
69+
],
70+
[
71+
KeyedIntArray(elements: [1], key: 0),
72+
KeyedIntArray(elements: [], key: 1),
73+
],
74+
"DS(1)DE(0,0)IE(0,0)DE(0,2)"
75+
),
76+
(
77+
[
78+
KeyedIntArray(elements: [2], key: 0),
79+
KeyedIntArray(elements: [0], key: 5),
80+
KeyedIntArray(elements: [1], key: 1),
81+
],
82+
[
83+
KeyedIntArray(elements: [1], key: 0),
84+
KeyedIntArray(elements: [], key: 1),
85+
],
86+
"DS(1)DE(0,0)IE(0,0)DE(0,2)"
87+
),
88+
(
89+
[
90+
KeyedIntArray(elements: [2], key: 0),
91+
KeyedIntArray(elements: [1, 2, 3], key: -1),
92+
KeyedIntArray(elements: [1], key: 1),
93+
],
94+
[
95+
KeyedIntArray(elements: [2, 3], key: 0),
96+
KeyedIntArray(elements: [1, 2], key: 1),
97+
],
98+
"DS(1)IE(1,0)IE(1,1)"
99+
),
100+
(
101+
[
102+
KeyedIntArray(elements: [2], key: 0),
103+
KeyedIntArray(elements: [1], key: 1),
104+
],
105+
[
106+
KeyedIntArray(elements: [2, 1], key: 0),
107+
KeyedIntArray(elements: [], key: 1),
108+
],
109+
"IE(1,0)DE(0,1)"
110+
),
111+
(
112+
[
113+
KeyedIntArray(elements: [], key: 0),
114+
KeyedIntArray(elements: [1, 2], key: 1),
115+
],
116+
[
117+
KeyedIntArray(elements: [2], key: 0),
118+
KeyedIntArray(elements: [], key: 1),
119+
],
120+
"IE(0,0)DE(0,1)DE(1,1)"
121+
),
122+
(
123+
[
124+
KeyedIntArray(elements: [1, 2], key: 0),
125+
KeyedIntArray(elements: [], key: 1),
126+
],
127+
[
128+
KeyedIntArray(elements: [], key: 0),
129+
KeyedIntArray(elements: [1], key: 1),
130+
],
131+
"DE(0,0)DE(1,0)IE(0,1)"
132+
),
133+
(
134+
[
135+
KeyedIntArray(elements: [], key: 0),
136+
KeyedIntArray(elements: [1], key: 1),
137+
KeyedIntArray(elements: [2], key: 2),
138+
],
139+
[
140+
KeyedIntArray(elements: [1, 2], key: 0),
141+
KeyedIntArray(elements: [], key: 1),
142+
KeyedIntArray(elements: [], key: 2),
143+
],
144+
"IE(0,0)IE(1,0)DE(0,1)DE(0,2)"
145+
),
146+
]
147+
148+
let expectations: [([[Int]], [[Int]], String)] = [
149+
(
150+
[],
151+
[
152+
[1, 2],
153+
[1],
154+
],
155+
"IS(0)IS(1)"
156+
),
157+
(
158+
[
159+
[1, 2],
160+
[],
161+
],
162+
[],
163+
"DS(0)DS(1)"
164+
),
165+
(
166+
[[1, 2], [], [1]],
167+
[[1, 2], [], [1]],
168+
""
169+
),
170+
(
171+
[[1, 2], [1, 4]],
172+
[[5, 2], [10, 4, 8]],
173+
"DS(1)IS(1)DE(0,0)IE(0,0)"
174+
),
175+
(
176+
[[1]],
177+
[[], [1, 2]],
178+
"DS(0)IS(0)IS(1)"
179+
),
180+
(
181+
[[1]],
182+
[[], [2]],
183+
"IS(0)DE(0,0)IE(0,1)"
184+
),
185+
]
186+
187+
for expectation in expectations {
188+
XCTAssertEqual(
189+
_test(from: expectation.0, to: expectation.1),
190+
expectation.2)
191+
}
192+
193+
for expectation in keyedExpectations {
194+
XCTAssertEqual(
195+
_test(from: expectation.0, to: expectation.1),
196+
expectation.2)
197+
}
198+
}
199+
200+
func _test<T: Collection>(
201+
from: [T],
202+
to: [T]) -> String
203+
where
204+
T: Equatable,
205+
T.Iterator.Element: Equatable {
206+
return from
207+
.nestedDiff(to: to)
208+
.reduce("") { $0 + $1.debugDescription }
209+
}
210+
}

0 commit comments

Comments
 (0)