├── .gitignore
├── Package.swift
├── README.md
├── Resources
├── Sdift
│ ├── Info-iOS.plist
│ └── Sdift.h
└── SdiftTests
│ └── Info-iOS.plist
├── Sdift.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ └── Sdift-iOS.xcscheme
├── Sources
└── Sdift
│ ├── Algorithm.swift
│ ├── BackwardDirection.swift
│ ├── Difference.swift
│ ├── ForwardDirection.swift
│ ├── ProgressTable.swift
│ └── Slice.swift
└── Tests
├── LinuxMain.swift
└── SdiftTests
├── SdiftTests.swift
└── XCTestManifests.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | xcuserdata
5 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:4.0
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "Sdift",
7 | products: [
8 | .library(name: "Sdift", targets: ["Sdift"]),
9 | ],
10 | dependencies: [
11 | ],
12 | targets: [
13 | .target(name: "Sdift", dependencies: []),
14 | .testTarget(name: "SdiftTests", dependencies: ["Sdift"]),
15 | ]
16 | )
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Sdift
2 |
3 | Swift myers diff library.
4 |
5 | Algorithm is based on this webpage.
6 |
7 | http://blog.robertelder.org/diff-algorithm/
8 |
9 | ### example
10 |
11 | https://github.com/omochi/SdiftExample
12 |
--------------------------------------------------------------------------------
/Resources/Sdift/Info-iOS.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Resources/Sdift/Sdift.h:
--------------------------------------------------------------------------------
1 | //
2 | // Sdift.h
3 | // Sdift
4 | //
5 | // Created by omochimetaru on 2018/06/29.
6 | // Copyright © 2018年 omochimetaru.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for Sdift.
12 | FOUNDATION_EXPORT double SdiftVersionNumber;
13 |
14 | //! Project version string for Sdift.
15 | FOUNDATION_EXPORT const unsigned char SdiftVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Resources/SdiftTests/Info-iOS.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Sdift.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | D62FC84B20E5E1E2003EF7A6 /* Sdift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D62FC84120E5E1E2003EF7A6 /* Sdift.framework */; };
11 | D62FC88220E5E2D8003EF7A6 /* Sdift.h in Headers */ = {isa = PBXBuildFile; fileRef = D62FC87320E5E2D7003EF7A6 /* Sdift.h */; settings = {ATTRIBUTES = (Public, ); }; };
12 | D62FC88420E5E2D8003EF7A6 /* BackwardDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62FC87720E5E2D7003EF7A6 /* BackwardDirection.swift */; };
13 | D62FC88520E5E2D8003EF7A6 /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62FC87820E5E2D7003EF7A6 /* Algorithm.swift */; };
14 | D62FC88620E5E2D8003EF7A6 /* Slice.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62FC87920E5E2D7003EF7A6 /* Slice.swift */; };
15 | D62FC88720E5E2D8003EF7A6 /* Difference.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62FC87A20E5E2D7003EF7A6 /* Difference.swift */; };
16 | D62FC88820E5E2D8003EF7A6 /* ProgressTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62FC87B20E5E2D7003EF7A6 /* ProgressTable.swift */; };
17 | D62FC88920E5E2D8003EF7A6 /* ForwardDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62FC87C20E5E2D7003EF7A6 /* ForwardDirection.swift */; };
18 | D62FC88B20E5E2DF003EF7A6 /* SdiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62FC86C20E5E2D7003EF7A6 /* SdiftTests.swift */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXContainerItemProxy section */
22 | D62FC84C20E5E1E2003EF7A6 /* PBXContainerItemProxy */ = {
23 | isa = PBXContainerItemProxy;
24 | containerPortal = D62FC83820E5E1E2003EF7A6 /* Project object */;
25 | proxyType = 1;
26 | remoteGlobalIDString = D62FC84020E5E1E2003EF7A6;
27 | remoteInfo = Sdift;
28 | };
29 | /* End PBXContainerItemProxy section */
30 |
31 | /* Begin PBXFileReference section */
32 | D62FC84120E5E1E2003EF7A6 /* Sdift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Sdift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
33 | D62FC84A20E5E1E2003EF7A6 /* SdiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SdiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
34 | D62FC86B20E5E2D7003EF7A6 /* XCTestManifests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestManifests.swift; sourceTree = ""; };
35 | D62FC86C20E5E2D7003EF7A6 /* SdiftTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SdiftTests.swift; sourceTree = ""; };
36 | D62FC86D20E5E2D7003EF7A6 /* LinuxMain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinuxMain.swift; sourceTree = ""; };
37 | D62FC87120E5E2D7003EF7A6 /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; };
38 | D62FC87320E5E2D7003EF7A6 /* Sdift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sdift.h; sourceTree = ""; };
39 | D62FC87420E5E2D7003EF7A6 /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; };
40 | D62FC87720E5E2D7003EF7A6 /* BackwardDirection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackwardDirection.swift; sourceTree = ""; };
41 | D62FC87820E5E2D7003EF7A6 /* Algorithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Algorithm.swift; sourceTree = ""; };
42 | D62FC87920E5E2D7003EF7A6 /* Slice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Slice.swift; sourceTree = ""; };
43 | D62FC87A20E5E2D7003EF7A6 /* Difference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Difference.swift; sourceTree = ""; };
44 | D62FC87B20E5E2D7003EF7A6 /* ProgressTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressTable.swift; sourceTree = ""; };
45 | D62FC87C20E5E2D7003EF7A6 /* ForwardDirection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForwardDirection.swift; sourceTree = ""; };
46 | /* End PBXFileReference section */
47 |
48 | /* Begin PBXFrameworksBuildPhase section */
49 | D62FC83E20E5E1E2003EF7A6 /* Frameworks */ = {
50 | isa = PBXFrameworksBuildPhase;
51 | buildActionMask = 2147483647;
52 | files = (
53 | );
54 | runOnlyForDeploymentPostprocessing = 0;
55 | };
56 | D62FC84720E5E1E2003EF7A6 /* Frameworks */ = {
57 | isa = PBXFrameworksBuildPhase;
58 | buildActionMask = 2147483647;
59 | files = (
60 | D62FC84B20E5E1E2003EF7A6 /* Sdift.framework in Frameworks */,
61 | );
62 | runOnlyForDeploymentPostprocessing = 0;
63 | };
64 | /* End PBXFrameworksBuildPhase section */
65 |
66 | /* Begin PBXGroup section */
67 | D62FC83720E5E1E2003EF7A6 = {
68 | isa = PBXGroup;
69 | children = (
70 | D62FC86E20E5E2D7003EF7A6 /* Resources */,
71 | D62FC87520E5E2D7003EF7A6 /* Sources */,
72 | D62FC86920E5E2D7003EF7A6 /* Tests */,
73 | D62FC84220E5E1E2003EF7A6 /* Products */,
74 | );
75 | sourceTree = "";
76 | };
77 | D62FC84220E5E1E2003EF7A6 /* Products */ = {
78 | isa = PBXGroup;
79 | children = (
80 | D62FC84120E5E1E2003EF7A6 /* Sdift.framework */,
81 | D62FC84A20E5E1E2003EF7A6 /* SdiftTests.xctest */,
82 | );
83 | name = Products;
84 | sourceTree = "";
85 | };
86 | D62FC86920E5E2D7003EF7A6 /* Tests */ = {
87 | isa = PBXGroup;
88 | children = (
89 | D62FC86A20E5E2D7003EF7A6 /* SdiftTests */,
90 | D62FC86D20E5E2D7003EF7A6 /* LinuxMain.swift */,
91 | );
92 | path = Tests;
93 | sourceTree = "";
94 | };
95 | D62FC86A20E5E2D7003EF7A6 /* SdiftTests */ = {
96 | isa = PBXGroup;
97 | children = (
98 | D62FC86B20E5E2D7003EF7A6 /* XCTestManifests.swift */,
99 | D62FC86C20E5E2D7003EF7A6 /* SdiftTests.swift */,
100 | );
101 | path = SdiftTests;
102 | sourceTree = "";
103 | };
104 | D62FC86E20E5E2D7003EF7A6 /* Resources */ = {
105 | isa = PBXGroup;
106 | children = (
107 | D62FC87220E5E2D7003EF7A6 /* Sdift */,
108 | D62FC86F20E5E2D7003EF7A6 /* SdiftTests */,
109 | );
110 | path = Resources;
111 | sourceTree = "";
112 | };
113 | D62FC86F20E5E2D7003EF7A6 /* SdiftTests */ = {
114 | isa = PBXGroup;
115 | children = (
116 | D62FC87120E5E2D7003EF7A6 /* Info-iOS.plist */,
117 | );
118 | path = SdiftTests;
119 | sourceTree = "";
120 | };
121 | D62FC87220E5E2D7003EF7A6 /* Sdift */ = {
122 | isa = PBXGroup;
123 | children = (
124 | D62FC87320E5E2D7003EF7A6 /* Sdift.h */,
125 | D62FC87420E5E2D7003EF7A6 /* Info-iOS.plist */,
126 | );
127 | path = Sdift;
128 | sourceTree = "";
129 | };
130 | D62FC87520E5E2D7003EF7A6 /* Sources */ = {
131 | isa = PBXGroup;
132 | children = (
133 | D62FC87620E5E2D7003EF7A6 /* Sdift */,
134 | );
135 | path = Sources;
136 | sourceTree = "";
137 | };
138 | D62FC87620E5E2D7003EF7A6 /* Sdift */ = {
139 | isa = PBXGroup;
140 | children = (
141 | D62FC87720E5E2D7003EF7A6 /* BackwardDirection.swift */,
142 | D62FC87820E5E2D7003EF7A6 /* Algorithm.swift */,
143 | D62FC87920E5E2D7003EF7A6 /* Slice.swift */,
144 | D62FC87A20E5E2D7003EF7A6 /* Difference.swift */,
145 | D62FC87B20E5E2D7003EF7A6 /* ProgressTable.swift */,
146 | D62FC87C20E5E2D7003EF7A6 /* ForwardDirection.swift */,
147 | );
148 | path = Sdift;
149 | sourceTree = "";
150 | };
151 | /* End PBXGroup section */
152 |
153 | /* Begin PBXHeadersBuildPhase section */
154 | D62FC83C20E5E1E2003EF7A6 /* Headers */ = {
155 | isa = PBXHeadersBuildPhase;
156 | buildActionMask = 2147483647;
157 | files = (
158 | D62FC88220E5E2D8003EF7A6 /* Sdift.h in Headers */,
159 | );
160 | runOnlyForDeploymentPostprocessing = 0;
161 | };
162 | /* End PBXHeadersBuildPhase section */
163 |
164 | /* Begin PBXNativeTarget section */
165 | D62FC84020E5E1E2003EF7A6 /* Sdift-iOS */ = {
166 | isa = PBXNativeTarget;
167 | buildConfigurationList = D62FC85520E5E1E2003EF7A6 /* Build configuration list for PBXNativeTarget "Sdift-iOS" */;
168 | buildPhases = (
169 | D62FC83C20E5E1E2003EF7A6 /* Headers */,
170 | D62FC83D20E5E1E2003EF7A6 /* Sources */,
171 | D62FC83E20E5E1E2003EF7A6 /* Frameworks */,
172 | D62FC83F20E5E1E2003EF7A6 /* Resources */,
173 | );
174 | buildRules = (
175 | );
176 | dependencies = (
177 | );
178 | name = "Sdift-iOS";
179 | productName = Sdift;
180 | productReference = D62FC84120E5E1E2003EF7A6 /* Sdift.framework */;
181 | productType = "com.apple.product-type.framework";
182 | };
183 | D62FC84920E5E1E2003EF7A6 /* SdiftTests-iOS */ = {
184 | isa = PBXNativeTarget;
185 | buildConfigurationList = D62FC85820E5E1E2003EF7A6 /* Build configuration list for PBXNativeTarget "SdiftTests-iOS" */;
186 | buildPhases = (
187 | D62FC84620E5E1E2003EF7A6 /* Sources */,
188 | D62FC84720E5E1E2003EF7A6 /* Frameworks */,
189 | D62FC84820E5E1E2003EF7A6 /* Resources */,
190 | );
191 | buildRules = (
192 | );
193 | dependencies = (
194 | D62FC84D20E5E1E2003EF7A6 /* PBXTargetDependency */,
195 | );
196 | name = "SdiftTests-iOS";
197 | productName = SdiftTests;
198 | productReference = D62FC84A20E5E1E2003EF7A6 /* SdiftTests.xctest */;
199 | productType = "com.apple.product-type.bundle.unit-test";
200 | };
201 | /* End PBXNativeTarget section */
202 |
203 | /* Begin PBXProject section */
204 | D62FC83820E5E1E2003EF7A6 /* Project object */ = {
205 | isa = PBXProject;
206 | attributes = {
207 | LastSwiftUpdateCheck = 1000;
208 | LastUpgradeCheck = 1000;
209 | ORGANIZATIONNAME = omochimetaru.com;
210 | TargetAttributes = {
211 | D62FC84020E5E1E2003EF7A6 = {
212 | CreatedOnToolsVersion = 10.0;
213 | };
214 | D62FC84920E5E1E2003EF7A6 = {
215 | CreatedOnToolsVersion = 10.0;
216 | };
217 | };
218 | };
219 | buildConfigurationList = D62FC83B20E5E1E2003EF7A6 /* Build configuration list for PBXProject "Sdift" */;
220 | compatibilityVersion = "Xcode 9.3";
221 | developmentRegion = en;
222 | hasScannedForEncodings = 0;
223 | knownRegions = (
224 | en,
225 | );
226 | mainGroup = D62FC83720E5E1E2003EF7A6;
227 | productRefGroup = D62FC84220E5E1E2003EF7A6 /* Products */;
228 | projectDirPath = "";
229 | projectRoot = "";
230 | targets = (
231 | D62FC84020E5E1E2003EF7A6 /* Sdift-iOS */,
232 | D62FC84920E5E1E2003EF7A6 /* SdiftTests-iOS */,
233 | );
234 | };
235 | /* End PBXProject section */
236 |
237 | /* Begin PBXResourcesBuildPhase section */
238 | D62FC83F20E5E1E2003EF7A6 /* Resources */ = {
239 | isa = PBXResourcesBuildPhase;
240 | buildActionMask = 2147483647;
241 | files = (
242 | );
243 | runOnlyForDeploymentPostprocessing = 0;
244 | };
245 | D62FC84820E5E1E2003EF7A6 /* Resources */ = {
246 | isa = PBXResourcesBuildPhase;
247 | buildActionMask = 2147483647;
248 | files = (
249 | );
250 | runOnlyForDeploymentPostprocessing = 0;
251 | };
252 | /* End PBXResourcesBuildPhase section */
253 |
254 | /* Begin PBXSourcesBuildPhase section */
255 | D62FC83D20E5E1E2003EF7A6 /* Sources */ = {
256 | isa = PBXSourcesBuildPhase;
257 | buildActionMask = 2147483647;
258 | files = (
259 | D62FC88520E5E2D8003EF7A6 /* Algorithm.swift in Sources */,
260 | D62FC88920E5E2D8003EF7A6 /* ForwardDirection.swift in Sources */,
261 | D62FC88620E5E2D8003EF7A6 /* Slice.swift in Sources */,
262 | D62FC88420E5E2D8003EF7A6 /* BackwardDirection.swift in Sources */,
263 | D62FC88820E5E2D8003EF7A6 /* ProgressTable.swift in Sources */,
264 | D62FC88720E5E2D8003EF7A6 /* Difference.swift in Sources */,
265 | );
266 | runOnlyForDeploymentPostprocessing = 0;
267 | };
268 | D62FC84620E5E1E2003EF7A6 /* Sources */ = {
269 | isa = PBXSourcesBuildPhase;
270 | buildActionMask = 2147483647;
271 | files = (
272 | D62FC88B20E5E2DF003EF7A6 /* SdiftTests.swift in Sources */,
273 | );
274 | runOnlyForDeploymentPostprocessing = 0;
275 | };
276 | /* End PBXSourcesBuildPhase section */
277 |
278 | /* Begin PBXTargetDependency section */
279 | D62FC84D20E5E1E2003EF7A6 /* PBXTargetDependency */ = {
280 | isa = PBXTargetDependency;
281 | target = D62FC84020E5E1E2003EF7A6 /* Sdift-iOS */;
282 | targetProxy = D62FC84C20E5E1E2003EF7A6 /* PBXContainerItemProxy */;
283 | };
284 | /* End PBXTargetDependency section */
285 |
286 | /* Begin XCBuildConfiguration section */
287 | D62FC85320E5E1E2003EF7A6 /* Debug */ = {
288 | isa = XCBuildConfiguration;
289 | buildSettings = {
290 | ALWAYS_SEARCH_USER_PATHS = NO;
291 | CLANG_ANALYZER_NONNULL = YES;
292 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
293 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
294 | CLANG_CXX_LIBRARY = "libc++";
295 | CLANG_ENABLE_MODULES = YES;
296 | CLANG_ENABLE_OBJC_ARC = YES;
297 | CLANG_ENABLE_OBJC_WEAK = YES;
298 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
299 | CLANG_WARN_BOOL_CONVERSION = YES;
300 | CLANG_WARN_COMMA = YES;
301 | CLANG_WARN_CONSTANT_CONVERSION = YES;
302 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
303 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
304 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
305 | CLANG_WARN_EMPTY_BODY = YES;
306 | CLANG_WARN_ENUM_CONVERSION = YES;
307 | CLANG_WARN_INFINITE_RECURSION = YES;
308 | CLANG_WARN_INT_CONVERSION = YES;
309 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
310 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
311 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
312 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
313 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
314 | CLANG_WARN_STRICT_PROTOTYPES = YES;
315 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
316 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
317 | CLANG_WARN_UNREACHABLE_CODE = YES;
318 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
319 | CODE_SIGN_IDENTITY = "iPhone Developer";
320 | COPY_PHASE_STRIP = NO;
321 | CURRENT_PROJECT_VERSION = 1;
322 | DEBUG_INFORMATION_FORMAT = dwarf;
323 | ENABLE_STRICT_OBJC_MSGSEND = YES;
324 | ENABLE_TESTABILITY = YES;
325 | GCC_C_LANGUAGE_STANDARD = gnu11;
326 | GCC_DYNAMIC_NO_PIC = NO;
327 | GCC_NO_COMMON_BLOCKS = YES;
328 | GCC_OPTIMIZATION_LEVEL = 0;
329 | GCC_PREPROCESSOR_DEFINITIONS = (
330 | "DEBUG=1",
331 | "$(inherited)",
332 | );
333 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
334 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
335 | GCC_WARN_UNDECLARED_SELECTOR = YES;
336 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
337 | GCC_WARN_UNUSED_FUNCTION = YES;
338 | GCC_WARN_UNUSED_VARIABLE = YES;
339 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
340 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
341 | ONLY_ACTIVE_ARCH = YES;
342 | SDKROOT = iphoneos;
343 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
344 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
345 | VERSIONING_SYSTEM = "apple-generic";
346 | VERSION_INFO_PREFIX = "";
347 | };
348 | name = Debug;
349 | };
350 | D62FC85420E5E1E2003EF7A6 /* Release */ = {
351 | isa = XCBuildConfiguration;
352 | buildSettings = {
353 | ALWAYS_SEARCH_USER_PATHS = NO;
354 | CLANG_ANALYZER_NONNULL = YES;
355 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
356 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
357 | CLANG_CXX_LIBRARY = "libc++";
358 | CLANG_ENABLE_MODULES = YES;
359 | CLANG_ENABLE_OBJC_ARC = YES;
360 | CLANG_ENABLE_OBJC_WEAK = YES;
361 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
362 | CLANG_WARN_BOOL_CONVERSION = YES;
363 | CLANG_WARN_COMMA = YES;
364 | CLANG_WARN_CONSTANT_CONVERSION = YES;
365 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
366 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
367 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
368 | CLANG_WARN_EMPTY_BODY = YES;
369 | CLANG_WARN_ENUM_CONVERSION = YES;
370 | CLANG_WARN_INFINITE_RECURSION = YES;
371 | CLANG_WARN_INT_CONVERSION = YES;
372 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
373 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
374 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
375 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
376 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
377 | CLANG_WARN_STRICT_PROTOTYPES = YES;
378 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
379 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
380 | CLANG_WARN_UNREACHABLE_CODE = YES;
381 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
382 | CODE_SIGN_IDENTITY = "iPhone Developer";
383 | COPY_PHASE_STRIP = NO;
384 | CURRENT_PROJECT_VERSION = 1;
385 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
386 | ENABLE_NS_ASSERTIONS = NO;
387 | ENABLE_STRICT_OBJC_MSGSEND = YES;
388 | GCC_C_LANGUAGE_STANDARD = gnu11;
389 | GCC_NO_COMMON_BLOCKS = YES;
390 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
391 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
392 | GCC_WARN_UNDECLARED_SELECTOR = YES;
393 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
394 | GCC_WARN_UNUSED_FUNCTION = YES;
395 | GCC_WARN_UNUSED_VARIABLE = YES;
396 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
397 | MTL_ENABLE_DEBUG_INFO = NO;
398 | SDKROOT = iphoneos;
399 | SWIFT_COMPILATION_MODE = wholemodule;
400 | SWIFT_OPTIMIZATION_LEVEL = "-O";
401 | VALIDATE_PRODUCT = YES;
402 | VERSIONING_SYSTEM = "apple-generic";
403 | VERSION_INFO_PREFIX = "";
404 | };
405 | name = Release;
406 | };
407 | D62FC85620E5E1E2003EF7A6 /* Debug */ = {
408 | isa = XCBuildConfiguration;
409 | buildSettings = {
410 | CODE_SIGN_IDENTITY = "";
411 | CODE_SIGN_STYLE = Automatic;
412 | DEFINES_MODULE = YES;
413 | DYLIB_COMPATIBILITY_VERSION = 1;
414 | DYLIB_CURRENT_VERSION = 1;
415 | DYLIB_INSTALL_NAME_BASE = "@rpath";
416 | INFOPLIST_FILE = "$(SRCROOT)/Resources/Sdift/Info-iOS.plist";
417 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
418 | LD_RUNPATH_SEARCH_PATHS = (
419 | "$(inherited)",
420 | "@executable_path/Frameworks",
421 | "@loader_path/Frameworks",
422 | );
423 | PRODUCT_BUNDLE_IDENTIFIER = com.omochimetaru.Sdift;
424 | PRODUCT_NAME = Sdift;
425 | SKIP_INSTALL = YES;
426 | SWIFT_VERSION = 4.2;
427 | TARGETED_DEVICE_FAMILY = "1,2";
428 | };
429 | name = Debug;
430 | };
431 | D62FC85720E5E1E2003EF7A6 /* Release */ = {
432 | isa = XCBuildConfiguration;
433 | buildSettings = {
434 | CODE_SIGN_IDENTITY = "";
435 | CODE_SIGN_STYLE = Automatic;
436 | DEFINES_MODULE = YES;
437 | DYLIB_COMPATIBILITY_VERSION = 1;
438 | DYLIB_CURRENT_VERSION = 1;
439 | DYLIB_INSTALL_NAME_BASE = "@rpath";
440 | INFOPLIST_FILE = "$(SRCROOT)/Resources/Sdift/Info-iOS.plist";
441 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
442 | LD_RUNPATH_SEARCH_PATHS = (
443 | "$(inherited)",
444 | "@executable_path/Frameworks",
445 | "@loader_path/Frameworks",
446 | );
447 | PRODUCT_BUNDLE_IDENTIFIER = com.omochimetaru.Sdift;
448 | PRODUCT_NAME = Sdift;
449 | SKIP_INSTALL = YES;
450 | SWIFT_VERSION = 4.2;
451 | TARGETED_DEVICE_FAMILY = "1,2";
452 | };
453 | name = Release;
454 | };
455 | D62FC85920E5E1E2003EF7A6 /* Debug */ = {
456 | isa = XCBuildConfiguration;
457 | buildSettings = {
458 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
459 | CODE_SIGN_STYLE = Automatic;
460 | INFOPLIST_FILE = "Resources/SdiftTests/Info-iOS.plist";
461 | LD_RUNPATH_SEARCH_PATHS = (
462 | "$(inherited)",
463 | "@executable_path/Frameworks",
464 | "@loader_path/Frameworks",
465 | );
466 | PRODUCT_BUNDLE_IDENTIFIER = com.omochimetaru.SdiftTests;
467 | PRODUCT_NAME = SdiftTests;
468 | SWIFT_VERSION = 4.2;
469 | TARGETED_DEVICE_FAMILY = "1,2";
470 | };
471 | name = Debug;
472 | };
473 | D62FC85A20E5E1E2003EF7A6 /* Release */ = {
474 | isa = XCBuildConfiguration;
475 | buildSettings = {
476 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
477 | CODE_SIGN_STYLE = Automatic;
478 | INFOPLIST_FILE = "Resources/SdiftTests/Info-iOS.plist";
479 | LD_RUNPATH_SEARCH_PATHS = (
480 | "$(inherited)",
481 | "@executable_path/Frameworks",
482 | "@loader_path/Frameworks",
483 | );
484 | PRODUCT_BUNDLE_IDENTIFIER = com.omochimetaru.SdiftTests;
485 | PRODUCT_NAME = SdiftTests;
486 | SWIFT_VERSION = 4.2;
487 | TARGETED_DEVICE_FAMILY = "1,2";
488 | };
489 | name = Release;
490 | };
491 | /* End XCBuildConfiguration section */
492 |
493 | /* Begin XCConfigurationList section */
494 | D62FC83B20E5E1E2003EF7A6 /* Build configuration list for PBXProject "Sdift" */ = {
495 | isa = XCConfigurationList;
496 | buildConfigurations = (
497 | D62FC85320E5E1E2003EF7A6 /* Debug */,
498 | D62FC85420E5E1E2003EF7A6 /* Release */,
499 | );
500 | defaultConfigurationIsVisible = 0;
501 | defaultConfigurationName = Release;
502 | };
503 | D62FC85520E5E1E2003EF7A6 /* Build configuration list for PBXNativeTarget "Sdift-iOS" */ = {
504 | isa = XCConfigurationList;
505 | buildConfigurations = (
506 | D62FC85620E5E1E2003EF7A6 /* Debug */,
507 | D62FC85720E5E1E2003EF7A6 /* Release */,
508 | );
509 | defaultConfigurationIsVisible = 0;
510 | defaultConfigurationName = Release;
511 | };
512 | D62FC85820E5E1E2003EF7A6 /* Build configuration list for PBXNativeTarget "SdiftTests-iOS" */ = {
513 | isa = XCConfigurationList;
514 | buildConfigurations = (
515 | D62FC85920E5E1E2003EF7A6 /* Debug */,
516 | D62FC85A20E5E1E2003EF7A6 /* Release */,
517 | );
518 | defaultConfigurationIsVisible = 0;
519 | defaultConfigurationName = Release;
520 | };
521 | /* End XCConfigurationList section */
522 | };
523 | rootObject = D62FC83820E5E1E2003EF7A6 /* Project object */;
524 | }
525 |
--------------------------------------------------------------------------------
/Sdift.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Sdift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Sdift.xcodeproj/xcshareddata/xcschemes/Sdift-iOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/Sources/Sdift/Algorithm.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public func difference
4 | (old: C, new: C) -> Difference
5 | where C.Element : Equatable
6 | {
7 | return difference(old: old,
8 | new: new,
9 | equals: { $0 == $1 })
10 | }
11 |
12 | private struct CacheKey : Hashable {
13 | var oldIndex: Int
14 | var newIndex: Int
15 | }
16 |
17 | public func difference(
18 | old: OC,
19 | new: NC,
20 | equals: @escaping (OC.Element, NC.Element) -> Bool) -> Difference
21 | {
22 | return difference(old: Array(old),
23 | new: Array(new),
24 | equals: equals)
25 | }
26 |
27 | public func difference(
28 | old: [O],
29 | new: [N],
30 | equals: @escaping (O, N) -> Bool) -> Difference
31 | {
32 | var solver = Solver(old: old, new: new, equals: equals)
33 | return solver.difference()
34 | }
35 |
36 | internal struct Solver {
37 | private let old: [O]
38 | private let new: [N]
39 | private let equalsImpl: (O, N) -> Bool
40 |
41 | public init(old: [O],
42 | new: [N],
43 | equals equalsImpl: @escaping (O, N) -> Bool)
44 | {
45 | self.old = old
46 | self.new = new
47 | self.equalsImpl = equalsImpl
48 | }
49 |
50 | private var equalCache: [CacheKey: Bool] = [:]
51 |
52 | private mutating func rawEquals(oldIndex: Int, newIndex: Int) -> Bool {
53 | let cacheKey = CacheKey(oldIndex: oldIndex, newIndex: newIndex)
54 | if let cache = equalCache[cacheKey] {
55 | return cache
56 | }
57 |
58 | let oldElement = old[oldIndex]
59 | let newElement = new[newIndex]
60 | let result = equalsImpl(oldElement, newElement)
61 | equalCache[cacheKey] = result
62 | return result
63 | }
64 |
65 | public mutating func difference() -> Difference {
66 | let oldSlice = Slice(elements: old,
67 | offset: 0,
68 | count: old.count)
69 | let newSlice = Slice(elements: new,
70 | offset: 0,
71 | count: new.count)
72 | let diffItems = self.difference(old: oldSlice, new: newSlice)
73 | return Difference(diffItems)
74 | }
75 |
76 | private mutating func difference(old: Slice, new: Slice) -> [Difference.Item] {
77 | func equals(oldIndex: Int, newIndex: Int) -> Bool {
78 | return rawEquals(oldIndex: old.offset + oldIndex,
79 | newIndex: new.offset + newIndex)
80 | }
81 |
82 | if new.count == 0 {
83 | return (0.. Int {
100 | return lengthDiff - k
101 | }
102 |
103 | let forwardTable = ProgressTable(size: tableSize)
104 | let backwardTable = ProgressTable(size: tableSize)
105 |
106 | let stepNum: Int = (maxDistance + 1) / 2 + 1
107 |
108 | for step in 0..= old.count
165 | if isCrossing {
166 | if snakeStartX == snakeEndX {
167 | if step == 0 {
168 | // maxDistanceのガードがあるからここには来ない
169 | assertionFailure()
170 | } else if step == 1 {
171 | assert(snakeEndX == old.count)
172 | assert(snakeEndY == new.count)
173 | assert(abs(lengthDiff) == 1)
174 | if new.count < old.count {
175 | return difference(old: old[new.count..= old.count
234 | if isCrossing {
235 | if snakeStartX == snakeEndX {
236 | if step == 0 {
237 | return []
238 | }
239 | }
240 |
241 | return difference(old: old[0..<(old.count - snakeEndX)],
242 | new: new[0..<(new.count - snakeEndY)]) +
243 | difference(old: old[(old.count - snakeStartX)..(new: NC,
24 | insert: (Int, NC.Element) -> Void,
25 | update: (Int, NC.Element) -> Void,
26 | remove: (Int) -> Void)
27 | {
28 | apply(new: Array(new),
29 | insert: insert,
30 | update: update,
31 | remove: remove)
32 | }
33 |
34 | public func apply(new: [N],
35 | insert: (Int, N) -> Void,
36 | update: (Int, N) -> Void,
37 | remove: (Int) -> Void)
38 | {
39 | var oldIndex = 0
40 | var oldIndexOffset = 0
41 | var newIndex = 0
42 | for item in items {
43 | while oldIndex < item.oldIndex {
44 | update(oldIndex + oldIndexOffset, new[newIndex])
45 | oldIndex += 1
46 | newIndex += 1
47 | }
48 | switch item {
49 | case .remove:
50 | remove(oldIndex + oldIndexOffset)
51 | oldIndex += 1
52 | oldIndexOffset -= 1
53 | case .insert(oldIndex: _, newIndex: _):
54 | insert(oldIndex + oldIndexOffset, new[newIndex])
55 | oldIndexOffset += 1
56 | newIndex += 1
57 | }
58 | }
59 | while newIndex < new.count {
60 | update(oldIndex + oldIndexOffset, new[newIndex])
61 | oldIndex += 1
62 | newIndex += 1
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Sources/Sdift/ForwardDirection.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | internal enum ForwardDirection {
4 | case down
5 | case right
6 | }
7 |
--------------------------------------------------------------------------------
/Sources/Sdift/ProgressTable.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | internal class ProgressTable {
4 | private var buffer: [Int]
5 |
6 | public init(size: Int) {
7 | self.buffer = Array(repeating: 0, count: size)
8 | }
9 |
10 | public var size: Int {
11 | return buffer.count
12 | }
13 |
14 | public subscript(k k: Int) -> Int {
15 | get {
16 | return buffer[wrap(k: k)]
17 | }
18 | set {
19 | buffer[wrap(k: k)] = newValue
20 | }
21 | }
22 |
23 | private func wrap(k: Int) -> Int {
24 | var k = k
25 | k %= size
26 | if k < 0 {
27 | k += size
28 | }
29 | return k
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/Sdift/Slice.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | internal class Slice {
4 | public let elements: [E]
5 | public let offset: Int
6 | public let count: Int
7 |
8 | public init(elements: [E],
9 | offset: Int,
10 | count: Int)
11 | {
12 | precondition(0 <= offset)
13 | precondition(0 <= count)
14 | precondition(offset + count <= elements.count)
15 |
16 | self.elements = elements
17 | self.offset = offset
18 | self.count = count
19 | }
20 |
21 | public subscript(range: Range) -> Slice {
22 | get {
23 | return Slice(elements: elements,
24 | offset: offset + range.lowerBound,
25 | count: range.count)
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import SdiftTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += SdiftTests.allTests()
7 | XCTMain(tests)
--------------------------------------------------------------------------------
/Tests/SdiftTests/SdiftTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import Sdift
3 |
4 | extension Difference {
5 | public func reconstruct(old: [E],
6 | new: [E],
7 | append: (E) -> Void)
8 | {
9 | var oldIndex = 0
10 | for item in items {
11 | while oldIndex < item.oldIndex {
12 | append(old[oldIndex])
13 | oldIndex += 1
14 | }
15 | switch item {
16 | case .remove:
17 | oldIndex += 1
18 | case .insert(oldIndex: _, newIndex: let newIndex):
19 | append(new[newIndex])
20 | }
21 | }
22 | while oldIndex < old.count {
23 | append(old[oldIndex])
24 | oldIndex += 1
25 | }
26 | }
27 | }
28 |
29 | final class SdiftTests: XCTestCase {
30 | func testDifference0() {
31 | let old = ""
32 | let new = ""
33 | let diff = difference(old: old, new: new)
34 | XCTAssertEqual(diff.items.count, 0)
35 | }
36 |
37 | func testDifference1() {
38 | let old = "a"
39 | let new = ""
40 | let diff = difference(old: old, new: new)
41 | XCTAssertEqual(diff.items.count, 1)
42 | XCTAssertEqual(diff.items[0], .remove(oldIndex: 0))
43 | }
44 |
45 | func testDifference2() {
46 | let old = "abc"
47 | let new = ""
48 | let diff = difference(old: old, new: new)
49 | XCTAssertEqual(diff.items.count, 3)
50 | XCTAssertEqual(diff.items[0], .remove(oldIndex: 0))
51 | XCTAssertEqual(diff.items[1], .remove(oldIndex: 1))
52 | XCTAssertEqual(diff.items[2], .remove(oldIndex: 2))
53 | }
54 |
55 | func testDifference3() {
56 | let old = ""
57 | let new = "a"
58 | let diff = difference(old: old, new: new)
59 | XCTAssertEqual(diff.items.count, 1)
60 | XCTAssertEqual(diff.items[0], .insert(oldIndex: 0, newIndex: 0))
61 | }
62 |
63 | func testDifference4() {
64 | let old = ""
65 | let new = "abc"
66 | let diff = difference(old: old, new: new)
67 | XCTAssertEqual(diff.items.count, 3)
68 | XCTAssertEqual(diff.items[0], .insert(oldIndex: 0, newIndex: 0))
69 | XCTAssertEqual(diff.items[1], .insert(oldIndex: 0, newIndex: 1))
70 | XCTAssertEqual(diff.items[2], .insert(oldIndex: 0, newIndex: 2))
71 | }
72 |
73 | func testDifference5() {
74 | let old = "abc"
75 | let new = "def"
76 | let diff = difference(old: old, new: new)
77 | XCTAssertEqual(diff.items.count, 6)
78 | XCTAssertEqual(diff.items[0], .remove(oldIndex: 0))
79 | XCTAssertEqual(diff.items[1], .remove(oldIndex: 1))
80 | XCTAssertEqual(diff.items[2], .remove(oldIndex: 2))
81 | XCTAssertEqual(diff.items[3], .insert(oldIndex: 3, newIndex: 0))
82 | XCTAssertEqual(diff.items[4], .insert(oldIndex: 3, newIndex: 1))
83 | XCTAssertEqual(diff.items[5], .insert(oldIndex: 3, newIndex: 2))
84 | }
85 |
86 | func testDifference6() {
87 | let old = "abcabba"
88 | let new = "cbabac"
89 | let diff = difference(old: old, new: new)
90 | XCTAssertEqual(diff.items.count, 5)
91 | XCTAssertEqual(diff.items[0], .remove(oldIndex: 0))
92 | XCTAssertEqual(diff.items[1], .insert(oldIndex: 1, newIndex: 0))
93 | XCTAssertEqual(diff.items[2], .remove(oldIndex: 2))
94 | XCTAssertEqual(diff.items[3], .remove(oldIndex: 5))
95 | XCTAssertEqual(diff.items[4], .insert(oldIndex: 7, newIndex: 5))
96 | }
97 |
98 | func testDifference7() {
99 | let old = "abgdef"
100 | let new = "gh"
101 | let diff = difference(old: old, new: new)
102 | XCTAssertEqual(diff.items.count, 6)
103 | XCTAssertEqual(diff.items[0], .remove(oldIndex: 0))
104 | XCTAssertEqual(diff.items[1], .remove(oldIndex: 1))
105 | XCTAssertEqual(diff.items[2], .remove(oldIndex: 3))
106 | XCTAssertEqual(diff.items[3], .remove(oldIndex: 4))
107 | XCTAssertEqual(diff.items[4], .insert(oldIndex: 5, newIndex: 1))
108 | XCTAssertEqual(diff.items[5], .remove(oldIndex: 5))
109 | }
110 |
111 | func assertReconstruct(old: String, new: String) {
112 | let diff = difference(old: old, new: new)
113 | var renew: String = ""
114 | diff.reconstruct(old: Array(old), new: Array(new)) { renew.append($0) }
115 | XCTAssertEqual(new, renew)
116 | }
117 |
118 | func testReconstruct() {
119 | // 0x0
120 | assertReconstruct(old: "", new: "")
121 | // 1x0
122 | assertReconstruct(old: "a", new: "")
123 | // 0x1
124 | assertReconstruct(old: "", new: "a")
125 | // 1x1
126 | assertReconstruct(old: "a", new: "a")
127 | assertReconstruct(old: "a", new: "b")
128 | // 2x0
129 | assertReconstruct(old: "ab", new: "")
130 | // 2x1
131 | assertReconstruct(old: "ab", new: "c")
132 | assertReconstruct(old: "ab", new: "a")
133 | assertReconstruct(old: "ab", new: "b")
134 | assertReconstruct(old: "aa", new: "a")
135 | // 0x2
136 | assertReconstruct(old: "", new: "ab")
137 | // 1x2
138 | assertReconstruct(old: "a", new: "bc")
139 | assertReconstruct(old: "a", new: "ab")
140 | assertReconstruct(old: "a", new: "ba")
141 | assertReconstruct(old: "a", new: "aa")
142 |
143 | // 2x2 (0)
144 | assertReconstruct(old: "ab", new: "cd")
145 | // 2x2 (1)
146 | assertReconstruct(old: "ab", new: "ad")
147 | assertReconstruct(old: "ab", new: "ca")
148 | assertReconstruct(old: "ab", new: "bd")
149 | assertReconstruct(old: "ab", new: "cb")
150 | // 2x2 (2)
151 | assertReconstruct(old: "aa", new: "ad")
152 | assertReconstruct(old: "ab", new: "ab")
153 | assertReconstruct(old: "ab", new: "aa")
154 |
155 | assertReconstruct(old: "ab", new: "bb")
156 | assertReconstruct(old: "ab", new: "ba")
157 |
158 | assertReconstruct(old: "aa", new: "ba")
159 | // 2x2 (3)
160 | assertReconstruct(old: "aa", new: "ab")
161 | assertReconstruct(old: "aa", new: "ba")
162 | assertReconstruct(old: "ab", new: "aa")
163 | assertReconstruct(old: "ba", new: "aa")
164 | // 2x2 (4)
165 | assertReconstruct(old: "aa", new: "aa")
166 |
167 | //
168 | assertReconstruct(old: "abcabba", new: "cbabac")
169 | assertReconstruct(old: "abgdef", new: "gh")
170 | }
171 |
172 | func assertApply(old: String, new: String) {
173 | var old = Array(old)
174 | let new = Array(new)
175 | let diff = difference(old: old, new: new)
176 | diff.apply(new: new,
177 | insert: { (index, item) in
178 | old.insert(item, at: index) },
179 | update: { (index, item) in
180 | XCTAssertEqual(old[index], item) },
181 | remove: { (index) in
182 | old.remove(at: index) })
183 | XCTAssertEqual(old, new)
184 | }
185 |
186 | func testApply() {
187 | assertApply(old: "a", new: "ab")
188 | assertApply(old: "a", new: "ba")
189 | assertApply(old: "abcabba", new: "cbabac")
190 | assertApply(old: "abgdef", new: "gh")
191 | }
192 |
193 | static var allTests = [
194 | ("testDifference0", testDifference0),
195 | ("testDifference1", testDifference1),
196 | ("testDifference2", testDifference2),
197 | ("testDifference3", testDifference3),
198 | ("testDifference4", testDifference4),
199 | ("testDifference5", testDifference5),
200 | ("testDifference6", testDifference6),
201 | ("testDifference7", testDifference7),
202 | ("testReconstruct", testReconstruct),
203 | ("testApply", testApply),
204 | ]
205 | }
206 |
--------------------------------------------------------------------------------
/Tests/SdiftTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | #if !os(macOS)
4 | public func allTests() -> [XCTestCaseEntry] {
5 | return [
6 | testCase(SdiftTests.allTests),
7 | ]
8 | }
9 | #endif
--------------------------------------------------------------------------------