/LanguageExt.Tests/PatchTests.cs

https://github.com/louthy/language-ext · C# · 588 lines · 428 code · 160 blank · 0 comment · 69 complexity · 502eacc1af230dcaaa4cf63c32ac862f MD5 · raw file

  1. using LanguageExt;
  2. using static LanguageExt.Prelude;
  3. using static LanguageExt.Patch;
  4. using LanguageExt.ClassInstances;
  5. using Xunit;
  6. namespace LanguageExt.Tests
  7. {
  8. public class PatchTests
  9. {
  10. [Fact]
  11. public void PatchAppendEmptyIsPatch()
  12. {
  13. var docA = List("Hello", "World");
  14. var docB = List("Hello", "World", "Again");
  15. var patchA = diff<EqString, string>(docA, docB);
  16. var patchB = append(patchA, Patch<EqString, string>.Empty);
  17. Assert.True(patchA == patchB);
  18. }
  19. [Fact]
  20. public void EmptyPatchAppendPatchIsPatch()
  21. {
  22. var docA = List("Hello", "World");
  23. var docB = List("Hello", "World", "Again");
  24. var patchA = diff<EqString, string>(docA, docB);
  25. var patchB = append(Patch<EqString, string>.Empty, patchA);
  26. Assert.True(patchA == patchB);
  27. }
  28. [Fact]
  29. public void PatchCommutes()
  30. {
  31. var docA = List("Hello", "World");
  32. var docB = List("Hello", "World", "Again");
  33. var docC = List("World");
  34. var docD = List("World", "War");
  35. var patchAB = diff<EqString, string>(docA, docB);
  36. var patchBC = diff<EqString, string>(docB, docC);
  37. var patchCD = diff<EqString, string>(docC, docD);
  38. var patchA_BC = append(patchAB, append(patchBC, patchCD));
  39. var patchAB_C = append(append(patchAB, patchBC), patchCD);
  40. Assert.True(patchA_BC == patchAB_C);
  41. }
  42. [Fact]
  43. public void InsertAtEndDiff()
  44. {
  45. var docA = List("Hello", "World");
  46. var docB = List("Hello", "World", "Again");
  47. var patch = diff<EqString, string>(docA, docB);
  48. Assert.True(patch.Edits.Count == 1);
  49. Assert.True(patch.Edits.Head == Edit<EqString, string>.Insert.New(2, "Again"));
  50. }
  51. [Fact]
  52. public void InsertAtBeginningDiff()
  53. {
  54. var docA = List("Hello", "World");
  55. var docB = List("Again", "Hello", "World");
  56. var patch = diff<EqString, string>(docA, docB);
  57. Assert.True(patch.Edits.Count == 1);
  58. Assert.True(patch.Edits.Head == Edit<EqString, string>.Insert.New(0, "Again"));
  59. }
  60. [Fact]
  61. public void InsertAtMidDiff()
  62. {
  63. var docA = List("Hello", "World");
  64. var docB = List("Hello", "Again", "World");
  65. var patch = diff<EqString, string>(docA, docB);
  66. Assert.True(patch.Edits.Count == 1);
  67. Assert.True(patch.Edits.Head == Edit<EqString, string>.Insert.New(1, "Again"));
  68. }
  69. [Fact]
  70. public void InsertMultiDiff()
  71. {
  72. var docA = List("Hello", "World");
  73. var docB = List("It's", "Hello", "Again", "World", "Cheers");
  74. var patch = diff<EqString, string>(docA, docB);
  75. Assert.True(patch.Edits.Count == 3);
  76. Assert.True(patch.Edits.Head == Edit<EqString, string>.Insert.New(0, "It's"));
  77. Assert.True(patch.Edits.Tail.Head == Edit<EqString, string>.Insert.New(1, "Again"));
  78. Assert.True(patch.Edits.Tail.Tail.Head == Edit<EqString, string>.Insert.New(2, "Cheers"));
  79. }
  80. [Fact]
  81. public void DeleteAtEndDiff()
  82. {
  83. var docA = List("Hello", "World", "Again");
  84. var docB = List("Hello", "World");
  85. var patch = diff<EqString, string>(docA, docB);
  86. Assert.True(patch.Edits.Count == 1);
  87. Assert.True(patch.Edits.Head == Edit<EqString, string>.Delete.New(2, "Again"));
  88. }
  89. [Fact]
  90. public void DeleteAtBeginningDiff()
  91. {
  92. var docA = List("Again", "Hello", "World");
  93. var docB = List("Hello", "World");
  94. var patch = diff<EqString, string>(docA, docB);
  95. Assert.True(patch.Edits.Count == 1);
  96. Assert.True(patch.Edits.Head == Edit<EqString, string>.Delete.New(0, "Again"));
  97. }
  98. [Fact]
  99. public void DeleteAtMidDiff()
  100. {
  101. var docA = List("Hello", "Again", "World");
  102. var docB = List("Hello", "World");
  103. var patch = diff<EqString, string>(docA, docB);
  104. Assert.True(patch.Edits.Count == 1);
  105. Assert.True(patch.Edits.Head == Edit<EqString, string>.Delete.New(1, "Again"));
  106. }
  107. [Fact]
  108. public void DeleteMultiDiff()
  109. {
  110. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  111. var docB = List("Hello", "World");
  112. var patch = diff<EqString, string>(docA, docB);
  113. Assert.True(patch.Edits.Count == 3);
  114. Assert.True(patch.Edits.Head == Edit<EqString, string>.Delete.New(0, "It's"));
  115. Assert.True(patch.Edits.Tail.Head == Edit<EqString, string>.Delete.New(2, "Again"));
  116. Assert.True(patch.Edits.Tail.Tail.Head == Edit<EqString, string>.Delete.New(4, "Cheers"));
  117. }
  118. [Fact]
  119. public void ReplaceAtEndDiff()
  120. {
  121. var docA = List("Hello", "World", "Again");
  122. var docB = List("Hello", "World", "Once More");
  123. var patch = diff<EqString, string>(docA, docB);
  124. Assert.True(patch.Edits.Count == 1);
  125. Assert.True(patch.Edits.Head == Edit<EqString, string>.Replace.New(2, "Again", "Once More"));
  126. }
  127. [Fact]
  128. public void ReplaceAtBeginningDiff()
  129. {
  130. var docA = List("Again", "Hello", "World");
  131. var docB = List("Once More", "Hello", "World");
  132. var patch = diff<EqString, string>(docA, docB);
  133. Assert.True(patch.Edits.Count == 1);
  134. Assert.True(patch.Edits.Head == Edit<EqString, string>.Replace.New(0, "Again", "Once More"));
  135. }
  136. [Fact]
  137. public void ReplaceAtMidDiff()
  138. {
  139. var docA = List("Hello", "Again", "World");
  140. var docB = List("Hello", "Once More", "World");
  141. var patch = diff<EqString, string>(docA, docB);
  142. Assert.True(patch.Edits.Count == 1);
  143. Assert.True(patch.Edits.Head == Edit<EqString, string>.Replace.New(1, "Again", "Once More"));
  144. }
  145. [Fact]
  146. public void ReplaceMultiDiff()
  147. {
  148. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  149. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  150. var patch = diff<EqString, string>(docA, docB);
  151. Assert.True(patch.Edits.Count == 3);
  152. Assert.True(patch.Edits.Head == Edit<EqString, string>.Replace.New(0, "It's", "Yes"));
  153. Assert.True(patch.Edits.Tail.Head == Edit<EqString, string>.Replace.New(2, "Again", "My"));
  154. Assert.True(patch.Edits.Tail.Tail.Head == Edit<EqString, string>.Replace.New(4, "Cheers", "Of Joy"));
  155. }
  156. [Fact]
  157. public void ApplyInsertAtEndDiff()
  158. {
  159. var docA = List("Hello", "World");
  160. var docB = List("Hello", "World", "Again");
  161. var patch = diff<EqString, string>(docA, docB);
  162. var docC = apply(patch, docA);
  163. Assert.True(docB == docC);
  164. }
  165. [Fact]
  166. public void ApplyInsertAtBeginningDiff()
  167. {
  168. var docA = List("Hello", "World");
  169. var docB = List("Again", "Hello", "World");
  170. var patch = diff<EqString, string>(docA, docB);
  171. var docC = apply(patch, docA);
  172. Assert.True(docB == docC);
  173. }
  174. [Fact]
  175. public void ApplyInsertAtMidDiff()
  176. {
  177. var docA = List("Hello", "World");
  178. var docB = List("Hello", "Again", "World");
  179. var patch = diff<EqString, string>(docA, docB);
  180. var docC = apply(patch, docA);
  181. Assert.True(docB == docC);
  182. }
  183. [Fact]
  184. public void ApplyInsertMultiDiff()
  185. {
  186. var docA = List("Hello", "World");
  187. var docB = List("It's", "Hello", "Again", "World", "Cheers");
  188. var patch = diff<EqString, string>(docA, docB);
  189. var docC = apply(patch, docA);
  190. Assert.True(docB == docC);
  191. }
  192. [Fact]
  193. public void ApplyDeleteAtEndDiff()
  194. {
  195. var docA = List("Hello", "World", "Again");
  196. var docB = List("Hello", "World");
  197. var patch = diff<EqString, string>(docA, docB);
  198. var docC = apply(patch, docA);
  199. Assert.True(docB == docC);
  200. }
  201. [Fact]
  202. public void ApplyDeleteAtBeginningDiff()
  203. {
  204. var docA = List("Again", "Hello", "World");
  205. var docB = List("Hello", "World");
  206. var patch = diff<EqString, string>(docA, docB);
  207. var docC = apply(patch, docA);
  208. Assert.True(docB == docC);
  209. }
  210. [Fact]
  211. public void ApplyDeleteAtMidDiff()
  212. {
  213. var docA = List("Hello", "Again", "World");
  214. var docB = List("Hello", "World");
  215. var patch = diff<EqString, string>(docA, docB);
  216. var docC = apply(patch, docA);
  217. Assert.True(docB == docC);
  218. }
  219. [Fact]
  220. public void ApplyDeleteMultiDiff()
  221. {
  222. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  223. var docB = List("Hello", "World");
  224. var patch = diff<EqString, string>(docA, docB);
  225. var docC = apply(patch, docA);
  226. Assert.True(docB == docC);
  227. }
  228. [Fact]
  229. public void ApplyReplaceAtEndDiff()
  230. {
  231. var docA = List("Hello", "World", "Again");
  232. var docB = List("Hello", "World", "Once More");
  233. var patch = diff<EqString, string>(docA, docB);
  234. var docC = apply(patch, docA);
  235. Assert.True(docB == docC);
  236. }
  237. [Fact]
  238. public void ApplyReplaceAtBeginningDiff()
  239. {
  240. var docA = List("Again", "Hello", "World");
  241. var docB = List("Once More", "Hello", "World");
  242. var patch = diff<EqString, string>(docA, docB);
  243. var docC = apply(patch, docA);
  244. Assert.True(docB == docC);
  245. }
  246. [Fact]
  247. public void ApplyReplaceAtMidDiff()
  248. {
  249. var docA = List("Hello", "Again", "World");
  250. var docB = List("Hello", "Once More", "World");
  251. var patch = diff<EqString, string>(docA, docB);
  252. var docC = apply(patch, docA);
  253. Assert.True(docB == docC);
  254. }
  255. [Fact]
  256. public void ApplyReplaceMultiDiff()
  257. {
  258. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  259. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  260. var patch = diff<EqString, string>(docA, docB);
  261. var docC = apply(patch, docA);
  262. Assert.True(docB == docC);
  263. }
  264. [Fact]
  265. public void PatchAppendInversePatchIsEmpty()
  266. {
  267. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  268. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  269. var mp = default(MPatch<EqString, string>);
  270. var patch = diff<EqString, string>(docA, docB);
  271. var inverseP = inverse(patch);
  272. var patch1 = mp.Append(patch, inverseP);
  273. var empty = mp.Empty();
  274. Assert.True(patch1 == empty);
  275. }
  276. [Fact]
  277. public void InversePatchAppendPatchIsEmpty()
  278. {
  279. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  280. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  281. var mp = default(MPatch<EqString, string>);
  282. var patch = diff<EqString, string>(docA, docB);
  283. var inverseP = inverse(patch);
  284. var patch1 = mp.Append(inverseP, patch);
  285. var empty = mp.Empty();
  286. Assert.True(patch1 == empty);
  287. }
  288. [Fact]
  289. public void InverseInversePatchIsPatch()
  290. {
  291. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  292. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  293. var patch = diff<EqString, string>(docA, docB);
  294. var inverseP = inverse(patch);
  295. var inverseInverse = inverse(inverseP);
  296. Assert.True(patch == inverseInverse);
  297. }
  298. [Fact]
  299. public void PatchAppend()
  300. {
  301. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  302. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  303. var docC = List("Yes", "My", "Of Joy");
  304. var patchP = diff<EqString, string>(docA, docB);
  305. var patchQ = diff<EqString, string>(docB, docC);
  306. var mp = default(MPatch<EqString, string>);
  307. var patchPQ = mp.Append(patchP, patchQ);
  308. var docD = apply(patchPQ, docA);
  309. var docD1 = apply(patchP, docA);
  310. var docD2 = apply(patchQ, docD1);
  311. Assert.True(docC == docD);
  312. var edits = patchPQ.Edits.ToArr();
  313. Assert.True(edits[0] == Edit<EqString, string>.Replace.New(0, "It's", "Yes"));
  314. Assert.True(edits[1] == Edit<EqString, string>.Delete.New(1, "Hello"));
  315. Assert.True(edits[2] == Edit<EqString, string>.Replace.New(2, "Again", "My"));
  316. Assert.True(edits[3] == Edit<EqString, string>.Delete.New(3, "World"));
  317. Assert.True(edits[4] == Edit<EqString, string>.Replace.New(4, "Cheers", "Of Joy"));
  318. }
  319. [Fact]
  320. public void InverseOfPatchPAppendPatchQIsInversePatchQAppendInversePatchP()
  321. {
  322. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  323. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  324. var docC = List("Yes", "Hello", "My", "World", "Of Joy", "And More");
  325. var patchP = diff<EqString, string>(docA, docB);
  326. var patchQ = diff<EqString, string>(docB, docC);
  327. var mp = default(MPatch<EqString, string>);
  328. var invPatchP = inverse(patchP);
  329. var invPatchQ = inverse(patchQ);
  330. Assert.True(inverse(invPatchP) == patchP);
  331. Assert.True(inverse(invPatchQ) == patchQ);
  332. var patchPQ = mp.Append(patchP, patchQ);
  333. var invPatchPQ = inverse(patchPQ);
  334. Assert.True(inverse(invPatchPQ) == patchPQ);
  335. var invPatchQinvPatchP = mp.Append(invPatchQ, invPatchP);
  336. Assert.True(inverse(invPatchPQ) == inverse(invPatchQinvPatchP));
  337. Assert.True(invPatchPQ == invPatchQinvPatchP);
  338. }
  339. [Fact]
  340. public void InverseEmptyIsEmpty()
  341. {
  342. var empty = Patch<EqString, string>.Empty;
  343. Assert.True(empty == inverse(empty));
  344. }
  345. [Fact]
  346. public void ComposableWithInverse()
  347. {
  348. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  349. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  350. var patch = diff<EqString, string>(docA, docB);
  351. var isComposable = composable(patch, inverse(patch));
  352. Assert.True(isComposable);
  353. }
  354. [Fact]
  355. public void InverseComposableWith()
  356. {
  357. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  358. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  359. var patch = diff<EqString, string>(docA, docB);
  360. var isComposable = composable(inverse(patch), patch);
  361. Assert.True(isComposable);
  362. }
  363. [Fact]
  364. public void InverseApplicableToAnyAppliedPatchOfP()
  365. {
  366. var docA = List("It's", "Hello", "Again", "World", "Cheers");
  367. var docB = List("Yes", "Hello", "My", "World", "Of Joy");
  368. var docC = List("Yes", "Hello", "My", "World", "Of Joy", "And More");
  369. var patch = diff<EqString, string>(docA, docB);
  370. var invPatch = inverse(patch);
  371. var isApplicable = applicable(invPatch, apply(patch, docC));
  372. Assert.True(isApplicable);
  373. }
  374. [Fact]
  375. public void ApplyDiffResultsInTargetDocument()
  376. {
  377. var d = List("It's", "Hello", "Again", "World", "Cheers");
  378. var e = List("Yes", "Hello", "My", "World", "Of Joy");
  379. Assert.True(apply(diff<EqString, string>(d, e), d) == e);
  380. }
  381. [Fact]
  382. public void DiffTheSameDocumentProducesEmptyPatch()
  383. {
  384. var d = List("It's", "Hello", "Again", "World", "Cheers");
  385. Assert.True(diff<EqString, string>(d, d) == empty<EqString, string>());
  386. }
  387. [Fact]
  388. public void DiffsBetweenThreePatchesAreEqualToDiffsBetweenFirstAndLastPatch()
  389. {
  390. var a = List("It's", "Hello", "Again", "World", "Cheers");
  391. var b = List("Yes", "Hello", "My", "World", "Of Joy");
  392. var c = List("Yes", "Hello", "My", "World", "Of Joy", "And More");
  393. Assert.True(
  394. apply(append(diff<EqString, string>(a, b), diff<EqString, string>(b, c)), a) == apply(diff<EqString, string>(a, c), a)
  395. );
  396. }
  397. [Fact]
  398. public void DiffWithConflictTakeOurs()
  399. {
  400. var a = List("Hello", "World");
  401. var b = List("World", "Hello");
  402. var c = List("Worldy", "Hello");
  403. var ab = diff<EqString, string>(a, b);
  404. var ac = diff<EqString, string>(a, c);
  405. var (pa, pb) = transformWith(ours, ab, ac);
  406. var newa = apply(pa, apply(ab, a));
  407. var newb = apply(pb, apply(ac, a));
  408. Assert.True(newa == newb);
  409. Assert.True(newa == b);
  410. Assert.True(newb == b);
  411. }
  412. [Fact]
  413. public void DiffWithConflictTakeTheirs()
  414. {
  415. var a = List("Hello", "World");
  416. var b = List("World", "Hello");
  417. var c = List("Worldy", "Hello");
  418. var ab = diff<EqString, string>(a, b);
  419. var ac = diff<EqString, string>(a, c);
  420. var (pa, pb) = transformWith(theirs, ab, ac);
  421. var newa = apply(pa, apply(ab, a));
  422. var newb = apply(pb, apply(ac, a));
  423. Assert.True(newa == newb);
  424. Assert.True(newa == c);
  425. Assert.True(newb == c);
  426. }
  427. }
  428. }