Skip to content

Commit

Permalink
Merge pull request #43 from nexxbiz/feature/bugfix-copy-move-internal…
Browse files Browse the repository at this point in the history
…_array

Bug fix for issue #41
  • Loading branch information
cristinamudura authored Jan 17, 2022
2 parents 61c0a94 + 9566635 commit 940ab21
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 6 deletions.
49 changes: 44 additions & 5 deletions JLio.Commands/Logic/CopyMove.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,54 @@ internal JLioExecutionResult Execute(JToken dataContext, IExecutionContext conte
var sourceItems = context.ItemsFetcher.SelectTokens(FromPath, data);
if (ToPath == executionContext.ItemsFetcher.RootPathIndicator)
return HandleRootObject(dataContext, sourceItems);
var innerArrayIndex = GetInnerArrayIndex();
if (innerArrayIndex != -1)
HandleActionPerSource(action, sourceItems, innerArrayIndex);
else
HandleActionForEachToAll(action, sourceItems);
return new JLioExecutionResult(true, dataContext);
}

private int GetInnerArrayIndex()
{
var fromPath = JsonPathMethods.SplitPath(FromPath);
var toPath = JsonPathMethods.SplitPath(ToPath);
if (!fromPath.HasArrayIndication || !toPath.HasArrayIndication) return -1;
var index = fromPath.GetSameElementsIndex(toPath);
if (!HasArrayNotationAfterIndex(fromPath, index) && !HasArrayNotationAfterIndex(toPath, index))
return index;

return -1;
}

private static bool HasArrayNotationAfterIndex(JsonSplittedPath path, int index)
{
return path.Elements.Skip(index).Any(e => e.HasArrayIndicator);
}

private void HandleActionPerSource(EAction action, SelectedTokens sourceItems, int innerArrayIndex)
{
var targetPath = JsonPathMethods.SplitPath(ToPath).Elements.Skip(innerArrayIndex);
sourceItems.ForEach(i =>
{
AddToTargets(i);
var selectionTargetPath =
new JsonSplittedPath(JsonPathMethods.SplitPath(i.Path).Elements.Take(innerArrayIndex - 1));
selectionTargetPath.Elements.AddRange(targetPath);
AddToTargets(i, selectionTargetPath);
if (action == EAction.Move)
RemoveItemFromSource(i);
});
}

return new JLioExecutionResult(true, dataContext);
private void HandleActionForEachToAll(EAction action, SelectedTokens sourceItems)
{
var toPath = JsonPathMethods.SplitPath(ToPath);
sourceItems.ForEach(i =>
{
AddToTargets(i, toPath);
if (action == EAction.Move)
RemoveItemFromSource(i);
});
}

private JLioExecutionResult HandleRootObject(JToken dataContext, SelectedTokens sourceItems)
Expand Down Expand Up @@ -83,10 +122,10 @@ private void RemoveValuesFromArray(JArray array, JToken selectedValue)
array.RemoveAt(index);
}

private void AddToTargets(JToken value)
private void AddToTargets(JToken value, JsonSplittedPath toPath)
{
var toPath = JsonPathMethods.SplitPath(ToPath);
JsonMethods.CheckOrCreateParentPath(data, toPath, executionContext.ItemsFetcher, executionContext.Logger);
JsonMethods.CheckOrCreateParentPath(data, toPath, executionContext.ItemsFetcher,
executionContext.Logger);
var targetItems = executionContext.ItemsFetcher.SelectTokens(toPath.ParentElements.ToPathString(), data);
targetItems.ForEach(t => AddToTarget(toPath.LastName, t, value));
}
Expand Down
25 changes: 24 additions & 1 deletion JLio.Core/Extensions/JsonSplittedPath.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using JLio.Core.Models.Path;

Expand Down Expand Up @@ -32,8 +33,15 @@ public JsonSplittedPath(string path)
if (element.Any()) Elements.Add(new PathElement(element));
}

public JsonSplittedPath(IEnumerable<PathElement> elements)
{
Elements.AddRange(elements);
}

public IEnumerable<PathElement> ConstructionPath => Elements.Skip(GetSelectionPathIndex() + 1);

public bool HasArrayIndication => Elements.Any(e => e.HasArrayIndicator);

public bool IsSearchingForObjectsByName =>
Elements.Count > 1 && Elements[Elements.Count - 2].RecursiveDescentIndicator;

Expand All @@ -58,5 +66,20 @@ private int GetSelectionPathIndex()

return 0;
}

public int GetSameElementsIndex(JsonSplittedPath secondPath)
{
var result = 0;
while (result < Elements.Count && result < secondPath.Elements.Count)
{
if (string.Compare(Elements[result].PathElementFullText,
secondPath.Elements[result].PathElementFullText, StringComparison.InvariantCultureIgnoreCase) != 0)
return result;

result++;
}

return result;
}
}
}
26 changes: 26 additions & 0 deletions JLio.UnitTests/CommandsTests/CopyMoveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,32 @@ public void PropertyMoveTests(string from, string to, string expectedValueToPath
Assert.IsTrue(from == to || data.SelectToken(from) == null);
}

[Test]
public void CanCopyMovePropertiesInAnLayeredArray()
{
var startObject =
"{\"myData\":[{\"demo\":[{\"demo2\":3}]},{\"demo\":[{\"demo2\":4}]},{\"demo\":[{\"demo2\":5}]}]}";
var result =
new Move("$.myData[*].demo[*].demo2", "$.myData[*].demo[*].new").Execute(
JToken.Parse(startObject), executeOptions);
Assert.IsTrue(JToken.DeepEquals(result.Data,
JToken.Parse(
"{\"myData\":[{\"demo\":[{\"new\":3}]},{\"demo\":[{\"new\":4}]},{\"demo\":[{\"new\":5}]}]}")));
}

[Test]
public void CanCopyMovePropertiesInAnArray()
{
var startObject =
"{\"myData\":[{\"demo\":[{\"old\":3}]},{\"demo\":[{\"old\":4}]},{\"demo\":[{\"old\":5}]}]}";
var result =
new Move("$.myData[*].demo", "$.myData[*].new").Execute(
JToken.Parse(startObject), executeOptions);
Assert.IsTrue(JToken.DeepEquals(result.Data,
JToken.Parse(
"{\"myData\":[{\"new\":[{\"old\":3}]},{\"new\":[{\"old\":4}]},{\"new\":[{\"old\":5}]}]}")));
}

[Test]
public void CanUseFluentApi()
{
Expand Down

0 comments on commit 940ab21

Please sign in to comment.