private static IDiff[] makediffs (string original, string [] changed, IComparer comparer) { IDiff[] diffs = new IDiff[changed.Length]; for (int i = 0; i < changed.Length; i++) diffs [i] = new TextDiff (original, changed [i], comparer); return diffs; }
public override void SetUp() { base.SetUp(); scmData = MockRepository.GenerateStub<IScmData>(); logStub = MockRepository.GenerateStub<ILog>(); diffStub = MockRepository.GenerateStub<IDiff>(); }
public Changestep(TData data, CrudOperation operation, IDiff diff, DateTime timestamp) { Data = data; Operation = operation; Diff = diff; Timestamp = timestamp; }
public TType Apply(TType source, IDiff <TType> patch) { // ReSharper disable once PossibleInvalidCastExceptionInForeachLoop foreach (var item in patch.Cast <IDiffValue>()) { switch (item) { case IDiffItemReplaced <TType> itemReplaced: return(itemReplaced.NewValue); case IDiffItemChanged itemChanged: Type sourceType = source.GetType(); IDiff diff = itemChanged.ValueDiff; IApplyPatchAlgorithm algorithm; if (!this.aTypes.TryGetValue(sourceType, out algorithm)) { algorithm = this.aMergerImplementation.Partial.Algorithms.GetApplyPatchAlgorithm(sourceType, this.aRules); } return((TType)algorithm.Apply(source, diff)); default: throw new InvalidOperationException(); } } return(source); }
private static IDiff[] makediffs (IList original, IList [] changed, IComparer comparer, IHashCodeProvider hashcoder) { IDiff[] diffs = new IDiff[changed.Length]; for (int i = 0; i < changed.Length; i++) diffs [i] = new Diff (original, changed [i], comparer, hashcoder); return diffs; }
/// <summary> /// Verifies that the <paramref name="actualChange"/> diff is a change to the value of the specific attribute (<paramref name="expectedAttrName"/>). /// </summary> /// <param name="actualChange">The actual change that has happened.</param> /// <param name="expectedAttrName">The expected name of the changed attribute.</param> /// <param name="expectedAttrValue">The expected value of the changed attribute.</param> /// <param name="userMessage">A custom user message to show when the verification fails.</param> public static void ShouldBeAttributeChange(this IDiff actualChange, string expectedAttrName, string expectedAttrValue, string?userMessage = null) { if (actualChange is null) { throw new ArgumentNullException(nameof(actualChange)); } if (expectedAttrName is null) { throw new ArgumentNullException(nameof(expectedAttrName)); } if (expectedAttrValue is null) { throw new ArgumentNullException(nameof(expectedAttrValue)); } var actual = Assert.IsType <AttrDiff>(actualChange); if (!expectedAttrName.Equals(actual.Test.Attribute.Name, StringComparison.Ordinal)) { throw new AssertActualExpectedException( expectedAttrName, actual.Test.Attribute.Name, userMessage ?? "The name of the changed attribute does not match the expected name.", "Expected attribute name", "Actual attribute name"); } if (!expectedAttrValue.Equals(actual.Test.Attribute.Value, StringComparison.Ordinal)) { throw new AssertActualExpectedException( expectedAttrValue, actual.Test.Attribute.Value, userMessage ?? "The value of the changed attribute does not match the expected value.", "Expected attribute value", "Actual attribute value"); } }
public void Process(IDiff diff, IKoreFolderInfo source, IKoreFolderInfo destination) { IsNotNull(diff); if (diff.Relation == DiffRelation.Identical) { return; } if (diff.Relation == DiffRelation.DestinationOrphan) { diff.Destination.Delete(); return; } IsNotNull(source); IsNotNull(destination); var sourceFileInfo = diff.Source; var destinationFileInfo = diff.Destination; if (diff.Relation == DiffRelation.SourceNew) { var sourceInnerFullPath = BuildRelativePath(diff.Source, source); destinationFileInfo = new KoreFileInfo(Path.Combine(destination.FullName, sourceInnerFullPath)); } else if (diff.Relation == DiffRelation.SourceOlder) { sourceFileInfo = destinationFileInfo; destinationFileInfo = diff.Source; } _fileCopier.Copy(sourceFileInfo, destinationFileInfo); }
private TType ApplyInternal(IEnumerable <TItemType> source, IDiff <TType> patch) { HashSet <TItemType> ret = new HashSet <TItemType>(source, this.aItemComparer); foreach (var item in patch.Cast <IDiffUnorderedCollectionItem>()) { switch (item) { case IDiffItemAdded <TItemType> itemAdded: ret.Add(itemAdded.NewValue); break; case IDiffItemRemoved <TItemType> itemRemoved: ret.Remove(itemRemoved.OldValue); break; case IDiffItemReplaced <TItemType> itemReplaced: ret.Remove(itemReplaced.OldValue); ret.Add(itemReplaced.NewValue); break; default: throw new InvalidOperationException(); } } return(this.aConvertor(ret)); }
public IDiff <TType> MergeDiffs(IDiff <TType> left, IDiff <TType> right, IConflictContainer conflicts) { if (this.aMergeItemsDiffs == null) { this.aMergeItemsDiffs = this.aMergerImplementation.Partial.Algorithms.GetMergeDiffsAlgorithm <TItemType>(); } List <IDiffItem> ret = new List <IDiffItem>(); foreach (var(leftItems, rightItems) in new MergeJoin(new Chunker(left.Cast <IDiffOrderedCollectionItem>()), new Chunker(right.Cast <IDiffOrderedCollectionItem>()))) { if (leftItems == null) { ret.AddRange(rightItems); } else if (rightItems == null) { ret.AddRange(leftItems); } else { this.ProcessConflicts(ret, leftItems, rightItems, conflicts); } } return(new Diff <TType>(ret)); }
public override void SetUp() { base.SetUp(); scmData = MockRepository.GenerateStub <IScmData>(); logStub = MockRepository.GenerateStub <ILog>(); diffStub = MockRepository.GenerateStub <IDiff>(); }
/// <summary> /// Verifies that the <paramref name="actualChange"/> diff is a change to the value of the specific attribute (<paramref name="expectedAttrName"/>). /// </summary> /// <param name="actualChange">The actual change that has happened.</param> /// <param name="expectedAttrName">The expected name of the changed attribute.</param> /// <param name="expectedAttrValue">The expected value of the changed attribute.</param> /// <param name="userMessage">A custom user message to show when the verification fails.</param> public static void ShouldBeAttributeChange(this IDiff actualChange, string expectedAttrName, string expectedAttrValue, string?userMessage = null) { if (actualChange is null) { throw new ArgumentNullException(nameof(actualChange)); } if (expectedAttrName is null) { throw new ArgumentNullException(nameof(expectedAttrName)); } if (expectedAttrValue is null) { throw new ArgumentNullException(nameof(expectedAttrValue)); } var actual = actualChange as AttrDiff ?? throw new DiffChangeAssertException(actualChange.Result, DiffResult.Different, "The change was not a attribute change."); if (!expectedAttrName.Equals(actual.Test.Attribute.Name, StringComparison.Ordinal)) { throw new ActualExpectedAssertException( actual.Test.Attribute.Name, expectedAttrName, "Actual attribute name", "Expected attribute name", userMessage ?? "The name of the changed attribute does not match the expected name."); } if (!expectedAttrValue.Equals(actual.Test.Attribute.Value, StringComparison.Ordinal)) { throw new ActualExpectedAssertException( actual.Test.Attribute.Value, expectedAttrValue, "Actual attribute value", "Expected attribute value", userMessage ?? "The value of the changed attribute does not match the expected value."); } }
public DynamicDiff(IDiff <TType> original, Dictionary <IDiffItemConflicted, ResolveAction> resolveActions) { this.aOriginal = original; this.aResolveActions = resolveActions; this.aDynamicDiffItemChangedFactory = new DynamicDiffItemChangedFactory(this.aResolveActions, false); this.aFinishDiffItemChangedFactory = new DynamicDiffItemChangedFactory(this.aResolveActions, true); }
public IConflictResolver <TType> GetConflictResolver <TType>(IDiff <TType> conflicted) { var conflicts = new ConflictContainer(); conflicts.RegisterAll(conflicted); return(new ConflictResolver <TType>(conflicted, conflicts)); }
public ConflictResolver(IDiff <TType> original, ConflictContainer conflicts) { this.aOriginal = original; this.aConflicts = conflicts.GetConflicts().ToList(); this.aResolveActions = new Dictionary <IDiffItemConflicted, ResolveAction>(this.aConflicts.Count, aConflictComparer); this.aResolved = new DynamicDiff <TType>(this.aOriginal, this.aResolveActions); this.aFinished = false; }
/// <summary> /// Verifies that a diff is a change to a text node. /// </summary> /// <param name="actualChange">The diff to verify.</param> /// <param name="expectedChange">The rendered fragment containing the expected text change.</param> /// <param name="userMessage">A custom error message to show if the verification fails.</param> public static void ShouldBeTextChange(this IDiff actualChange, IRenderedFragment expectedChange, string?userMessage = null) { if (expectedChange is null) { throw new ArgumentNullException(nameof(expectedChange)); } ShouldBeTextChange(actualChange, expectedChange.Nodes, userMessage); }
public void Test003() { var input = new IDiff[] { Mock.Of <IDiff>() }; var output = input.ShouldHaveSingleChange(); output.ShouldBe(input[0]); }
private static IDiff[] makediffs(IList original, IList[] changed, IComparer comparer, IEqualityComparer hashcoder) { IDiff[] diffs = new IDiff[changed.Length]; for (int i = 0; i < changed.Length; i++) { diffs[i] = new Diff(original, changed[i], comparer, hashcoder); } return(diffs); }
private static IDiff[] makediffs(string original, string[] changed, IComparer comparer) { IDiff[] diffs = new IDiff[changed.Length]; for (int i = 0; i < changed.Length; i++) { diffs[i] = new TextDiff(original, changed[i], comparer); } return(diffs); }
public TType Apply(TType source, IDiff <TType> patch) { if (this.aItemComparer == null) { this.aItemComparer = EqualityComparer <TItemType> .Default; this.aConvertor = this.CompileConvertor(); } return(this.ApplyInternal((IEnumerable <TItemType>)source, patch)); }
public TType Apply(TType source, IDiff <TType> patch) { if (this.aConvertor == null) { this.aConvertor = this.CompileConvertor(); this.aApplyItemDiff = this.aMergerImplementation.Partial.Algorithms.GetApplyPatchAlgorithm <TItemType>(); } return(this.ApplyInternal((IEnumerable <KeyValuePair <TKeyType, TItemType> >)source, patch)); }
private TType ApplyInternal(IEnumerable <TItemType> source, IDiff <TType> patch) { List <TItemType> ret = new List <TItemType>(); using (IEnumerator <TItemType> enumerator = source.GetEnumerator()) { bool lastMoveNext = enumerator.MoveNext(); int currentIndex = 0; foreach (var item in patch.Cast <IDiffOrderedCollectionItem>()) { while (currentIndex < item.ItemIndex) { ret.Add(enumerator.Current); lastMoveNext = enumerator.MoveNext(); currentIndex++; } switch (item) { case IDiffItemAdded <TItemType> itemAdded: ret.Add(itemAdded.NewValue); break; case IDiffItemChanged <TItemType> itemChanged: ret.Add(this.aApplyItemDiff.Apply(enumerator.Current, itemChanged.ValueDiff)); lastMoveNext = enumerator.MoveNext(); currentIndex++; break; case IDiffItemRemoved <TItemType> _: lastMoveNext = enumerator.MoveNext(); currentIndex++; break; case IDiffItemReplaced <TItemType> itemReplaced: lastMoveNext = enumerator.MoveNext(); ret.Add(itemReplaced.NewValue); currentIndex++; break; default: throw new InvalidOperationException(); } } while (lastMoveNext) { ret.Add(enumerator.Current); lastMoveNext = enumerator.MoveNext(); } } return(this.aConvertor(ret)); }
public TType Apply(TType source, IDiff <TType> patch) { if (this.aCompiled == null) { var compiled = this.Compile(); this.aCompiled = compiled.Compile(); } return(this.aCompiled(source, patch)); }
public static byte[] Write(IDiff diff) { var stream = new MemoryStream(); var writer = new BinaryWriter(stream); WriteHeader(diff, writer); Write(diff, writer, diff.HasZ()); writer.Flush(); stream.Flush(); return(stream.ToArray()); }
public TType Apply(TType source, IDiff <TType> patch) { if (this.aIdAccessor == null) { this.aIdAccessor = IdHelpers.CreateIdAccessor <TItemType, TIdType>(this.aIdProperty); this.aApplyItemDiff = this.aMergerImplementation.Partial.Algorithms.GetApplyPatchAlgorithm <TItemType>(); this.aConvertor = this.CompileConvertor(); } return(this.ApplyInternal((IEnumerable <TItemType>)source, patch)); }
public IDiff <TType> MergeDiffs(IDiff <TType> left, IDiff <TType> right, IConflictContainer conflicts) { if (this.aIdAccessor == null) { if (this.aIdProperty == null) { ParameterExpression obj = Expression.Parameter(typeof(TItemType), "obj"); Expression <Func <TItemType, TIdType> > identityFunction = Expression.Lambda <Func <TItemType, TIdType> >( obj, obj ); this.aIdAccessor = identityFunction.Compile(); } else { this.aIdAccessor = IdHelpers.CreateIdAccessor <TItemType, TIdType>(this.aIdProperty); } this.aMergeItemsDiffs = this.aMergerImplementation.Partial.Algorithms.GetMergeDiffsAlgorithm <TItemType>(); } Dictionary <TIdType, IDiffUnorderedCollectionItem> rightIndex = new Dictionary <TIdType, IDiffUnorderedCollectionItem>(right.Count); foreach (IDiffItem item in right) { rightIndex[this.GetID(item)] = (IDiffUnorderedCollectionItem)item; } List <IDiffItem> ret = new List <IDiffItem>(left.Count + right.Count); foreach (var leftItem in left.Cast <IDiffUnorderedCollectionItem>()) { IDiffUnorderedCollectionItem rightItem; TIdType id = this.GetID(leftItem); if (rightIndex.TryGetValue(id, out rightItem)) { rightIndex.Remove(id); this.ProcessConflict(id, leftItem, rightItem, ret, conflicts); } else { ret.Add(leftItem); } } ret.AddRange(rightIndex.Values); return(new Diff <TType>(ret)); }
public IDiff <TType> MergeDiffs(IDiff <TType> left, IDiff <TType> right, IConflictContainer conflicts) { if (this.aCompiled == null) { var compiled = this.Compile(); this.aCompiled = compiled.Compile(); } var ret = this.aCompiled(left, right, conflicts); return(new Diff <TType>(ret)); }
public void RegisterAll(IDiff diff) { foreach (IDiffItem item in diff) { switch (item) { case IDiffItemConflicted itemConflicted: this.RegisterConflict(itemConflicted); break; case IDiffItemChanged itemChanged: this.RegisterAll(itemChanged.ValueDiff); break; } } }
void RunOnBuilders(IActivityMonitor m, IDiff diff) { bool accepted = false; foreach (var builder in _diffRootResultBuilders) { if (diff.SendToBuilder(m, builder)) { accepted = true; } } if (!accepted) { diff.SendToBuilder(m, _others); } }
private IDiff <TType> ComputeInternal(IEnumerable <TItemType> @base, IEnumerable <TItemType> changed) { Dictionary <TIdType, TItemType> changedSet = changed.ToDictionary(this.aIdAccessor); List <IDiffItem> ret = new List <IDiffItem>(20); // 20 seems to be a good value :) foreach (TItemType baseItem in @base) { TIdType id = this.aIdAccessor(baseItem); TItemType changedItem; if (changedSet.TryGetValue(id, out changedItem)) { changedSet.Remove(id); if (this.aItemDiff.IsDirect) { if (!this.aItemComparer.Equals(baseItem, changedItem)) { ret.Add(new DiffUnorderedCollectionReplaced <TItemType>(baseItem, changedItem)); } } else { IDiff <TItemType> itemDiff = this.aItemDiff.Compute(baseItem, changedItem); if (itemDiff.HasChanges) { ret.Add(new DiffUnorderedCollectionChanged <TIdType, TItemType>(id, itemDiff)); } } } else { ret.Add(new DiffUnorderedCollectionRemoved <TItemType>(baseItem)); } } foreach (KeyValuePair <TIdType, TItemType> item in changedSet) { ret.Add(new DiffUnorderedCollectionAdded <TItemType>(item.Value)); } return(new Diff <TType>(ret)); }
/// <summary> /// Verifies that a diff is a change to a text node. /// </summary> /// <param name="actualChange">The diff to verify.</param> /// <param name="expectedChange">The expected text change.</param> /// <param name="userMessage">A custom error message to show if the verification fails.</param> public static void ShouldBeTextChange(this IDiff actualChange, string expectedChange, string?userMessage = null) { if (actualChange is null) { throw new ArgumentNullException(nameof(actualChange)); } if (expectedChange is null) { throw new ArgumentNullException(nameof(expectedChange)); } var actual = Assert.IsType <NodeDiff>(actualChange); var parser = actual.Control.Node.Owner.Context.GetService <TestHtmlParser>(); var expected = parser.Parse(expectedChange); ShouldBeTextChange(actualChange, expected, userMessage); }
static bool ExcludeDiff(IDiff diff) { // Handle aria-describedby being out of order // e.g. 'bar foo' instead of 'foo bar' if (diff is AttrDiff attrDiff && attrDiff.Test.Attribute.Name == "aria-describedby") { var controlValueParts = attrDiff.Control.Attribute.Value .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var testValueParts = attrDiff.Test.Attribute.Value .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); return(controlValueParts.OrderBy(v => v, StringComparer.OrdinalIgnoreCase) .SequenceEqual(testValueParts.OrderBy(v => v, StringComparer.OrdinalIgnoreCase))); } return(false); }
/// <summary> /// Verifies that the <paramref name="actualChange"/> <see cref="IDiff"/> is an removal, /// i.e. that one or more nodes have been removed, and verifies that the removed nodes are equal /// to the markup specified in the <paramref name="expectedChange"/> input. /// </summary> /// <param name="actualChange">The change to verify</param> /// <param name="expectedChange">The expected removal to verify against</param> /// <param name="userMessage">A custom user message to display in case the verification fails.</param> public static void ShouldBeRemoval(this IDiff actualChange, string expectedChange, string?userMessage = null) { if (actualChange is null) { throw new ArgumentNullException(nameof(actualChange)); } if (expectedChange is null) { throw new ArgumentNullException(nameof(expectedChange)); } var actual = Assert.IsType <MissingNodeDiff>(actualChange); INodeList expected; if (actual.Control.Node.GetHtmlParser() is { } parser) { expected = parser.Parse(expectedChange); }
/// <summary> /// Verifies that a diff is a change to a text node. /// </summary> /// <param name="actualChange">The diff to verify.</param> /// <param name="expectedChange">The expected text change.</param> /// <param name="userMessage">A custom error message to show if the verification fails.</param> public static void ShouldBeTextChange(this IDiff actualChange, string expectedChange, string?userMessage = null) { if (actualChange is null) { throw new ArgumentNullException(nameof(actualChange)); } if (expectedChange is null) { throw new ArgumentNullException(nameof(expectedChange)); } var actual = actualChange as NodeDiff ?? throw new DiffChangeAssertException(actualChange.Result, DiffResult.Different, "The change was not a text change."); var parser = actual.Control.Node.Owner.Context.GetService <HtmlParser>(); var expected = parser.Parse(expectedChange); ShouldBeTextChange(actualChange, expected, userMessage); }
public Merge(IDiff[] diffs) { this.diffs = diffs; // initialize data structures IEnumerator[] enumerators = new IEnumerator[diffs.Length]; ArrayList[] hunks = new ArrayList[diffs.Length]; for (int i = 0; i < hunks.Length; i++) { enumerators[i] = ((IEnumerable)diffs[i]).GetEnumerator(); hunks[i] = new ArrayList(); } int startline = 0; while (true) { int endline = -1; bool hasmore = false; // Get the next hunk for each diff, and find the longest // hunk for which there are changes. for (int i = 0; i < hunks.Length; i++) { if (hunks[i].Count > 0) continue; if (!enumerators[i].MoveNext()) return; hasmore = true; Diff.Hunk hunk = (Diff.Hunk)enumerators[i].Current; hunks[i].Add(hunk); if (!hunk.Same && hunk.Left.End > endline) endline = hunk.Left.End; } if (!hasmore) return; if (endline == -1) { // All of the hunks represented no change. Find the shortest hunk, // create a hunk from the current start line to the end of the // shortest hunk, and retain all of the hunks that overlap into that // hunk's next region. (Clear the rest.) int start = int.MaxValue; for (int i = 0; i < hunks.Length; i++) { Diff.Hunk h = (Diff.Hunk)hunks[i][0]; if (h.Left.End < start) start = h.Left.End; } // Crop all of the hunks to the shortest region. Diff.Hunk[][] h2 = new Diff.Hunk[hunks.Length][]; for (int i = 0; i < hunks.Length; i++) { h2[i] = new Diff.Hunk[1]; h2[i][0] = (Diff.Hunk)hunks[i][0]; h2[i][0] = h2[i][0].Crop(startline - h2[i][0].Left.Start, h2[i][0].Left.End - start); } this.hunks.Add( new Hunk(this, h2, startline, start - startline + 1, true) ); for (int i = 0; i < hunks.Length; i++) { Diff.Hunk h = (Diff.Hunk)hunks[i][0]; if (h.Left.End == start) hunks[i].Clear(); } startline = start+1; continue; } // For each diff, add in all of the non-same hunks that fall // at least partially within the largest hunk region. If // a hunk crosses the edge, push the edge further and then // add more hunks again. bool moreToAdd = true; while (moreToAdd) { moreToAdd = false; for (int i = 0; i < hunks.Length; i++) { Diff.Hunk last = (Diff.Hunk)hunks[i][hunks[i].Count-1]; while (last.Left.End < endline) { if (!enumerators[i].MoveNext()) continue; last = (Diff.Hunk)enumerators[i].Current; hunks[i].Add(last); if (last.Same) continue; if (last.Left.End > endline) { endline = last.Left.End; moreToAdd = true; } } } } Diff.Hunk[][] hunks2 = new Diff.Hunk[hunks.Length][]; for (int i = 0; i < hunks.Length; i++) { // any same hunks that overlap the start or end need to be replaced ArrayList hunks3 = new ArrayList(); foreach (Diff.Hunk h in hunks[i]) { Diff.Hunk h2 = h; int shiftstart = 0, shiftend = 0; if (h2.Same && h2.Left.Start < startline) shiftstart = startline - h2.Left.Start; if (h2.Same && h2.Left.End > endline) shiftend = h2.Left.End - endline; if (shiftstart != 0 || shiftend != 0) h2 = h2.Crop(shiftstart, shiftend); hunks3.Add(h2); } hunks2[i] = (Diff.Hunk[])hunks3.ToArray(typeof(Diff.Hunk)); } this.hunks.Add( new Hunk(this, hunks2, startline, endline - startline + 1, false) ); // In each hunk list, retain only the last hunk if it // overlaps into the next region. startline = endline+1; for (int i = 0; i < hunks.Length; i++) { if (hunks[i].Count == 0) continue; Diff.Hunk h = (Diff.Hunk)hunks[i][hunks[i].Count-1]; hunks[i].Clear(); if (h.Left.End >= startline) hunks[i].Add(h); } } }