Merge branch 'rel/1.1.1' into dev
Conflicts: NuGet.config src/Microsoft.AspNetCore.JsonPatch/project.json test/Microsoft.AspNetCore.JsonPatch.Test/project.json
This commit is contained in:
commit
b240929cf4
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
PositionInfo positionInfo;
|
PositionInfo positionInfo;
|
||||||
if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage))
|
if (!TryGetPositionInfo(list, segment, OperationType.Add, out positionInfo, out errorMessage))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
PositionInfo positionInfo;
|
PositionInfo positionInfo;
|
||||||
if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage))
|
if (!TryGetPositionInfo(list, segment, OperationType.Get, out positionInfo, out errorMessage))
|
||||||
{
|
{
|
||||||
value = null;
|
value = null;
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
PositionInfo positionInfo;
|
PositionInfo positionInfo;
|
||||||
if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage))
|
if (!TryGetPositionInfo(list, segment, OperationType.Remove, out positionInfo, out errorMessage))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
PositionInfo positionInfo;
|
PositionInfo positionInfo;
|
||||||
if (!TryGetPositionInfo(list, segment, out positionInfo, out errorMessage))
|
if (!TryGetPositionInfo(list, segment, OperationType.Replace, out positionInfo, out errorMessage))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -243,7 +243,12 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryGetPositionInfo(IList list, string segment, out PositionInfo positionInfo, out string errorMessage)
|
private bool TryGetPositionInfo(
|
||||||
|
IList list,
|
||||||
|
string segment,
|
||||||
|
OperationType operationType,
|
||||||
|
out PositionInfo positionInfo,
|
||||||
|
out string errorMessage)
|
||||||
{
|
{
|
||||||
if (segment == "-")
|
if (segment == "-")
|
||||||
{
|
{
|
||||||
|
|
@ -261,16 +266,24 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// As per JSON Patch spec, for Add operation the index value representing the number of elements is valid,
|
||||||
|
// where as for other operations like Remove, Replace, Move and Copy the target index MUST exist.
|
||||||
|
else if (position == list.Count && operationType == OperationType.Add)
|
||||||
|
{
|
||||||
|
positionInfo = new PositionInfo(PositionType.EndOfList, -1);
|
||||||
|
errorMessage = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
positionInfo = default(PositionInfo);
|
positionInfo = new PositionInfo(PositionType.OutOfBounds, position);
|
||||||
errorMessage = Resources.FormatIndexOutOfBounds(segment);
|
errorMessage = Resources.FormatIndexOutOfBounds(segment);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
positionInfo = default(PositionInfo);
|
positionInfo = new PositionInfo(PositionType.Invalid, -1);
|
||||||
errorMessage = Resources.FormatInvalidIndexValue(segment);
|
errorMessage = Resources.FormatInvalidIndexValue(segment);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -295,5 +308,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
||||||
Invalid, // Ex: not an integer
|
Invalid, // Ex: not an integer
|
||||||
OutOfBounds
|
OutOfBounds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum OperationType
|
||||||
|
{
|
||||||
|
Add,
|
||||||
|
Remove,
|
||||||
|
Get,
|
||||||
|
Replace
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,31 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
||||||
message);
|
message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Add_WithIndexSameAsNumberOfElements_Works()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
|
||||||
|
var targetObject = new List<string>() { "James", "Mike" };
|
||||||
|
var listAdapter = new ListAdapter();
|
||||||
|
string message = null;
|
||||||
|
var position = targetObject.Count.ToString();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var addStatus = listAdapter.TryAdd(targetObject, position, resolver.Object, "Rob", out message);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Null(message);
|
||||||
|
Assert.True(addStatus);
|
||||||
|
Assert.Equal(3, targetObject.Count);
|
||||||
|
Assert.Equal(new List<string>() { "James", "Mike", "Rob" }, targetObject);
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("-1")]
|
[InlineData("-1")]
|
||||||
[InlineData("-2")]
|
[InlineData("-2")]
|
||||||
[InlineData("2")]
|
|
||||||
[InlineData("3")]
|
[InlineData("3")]
|
||||||
public void Patch_WithOutOfBoundsIndex_Fails(string position)
|
public void Add_WithOutOfBoundsIndex_Fails(string position)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
|
var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
|
||||||
|
|
@ -225,6 +244,93 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal
|
||||||
Assert.Equal(expected, targetObject);
|
Assert.Equal(expected, targetObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new int[] { }, "0")]
|
||||||
|
[InlineData(new[] { 10, 20 }, "-1")]
|
||||||
|
[InlineData(new[] { 10, 20 }, "2")]
|
||||||
|
public void Get_IndexOutOfBounds(int[] input, string position)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
|
||||||
|
var targetObject = new List<int>(input);
|
||||||
|
var listAdapter = new ListAdapter();
|
||||||
|
string message = null;
|
||||||
|
object value = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var getStatus = listAdapter.TryGet(targetObject, position, resolver.Object, out value, out message);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(getStatus);
|
||||||
|
Assert.Equal(
|
||||||
|
string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position),
|
||||||
|
message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new[] { 10, 20 }, "0", 10)]
|
||||||
|
[InlineData(new[] { 10, 20 }, "1", 20)]
|
||||||
|
[InlineData(new[] { 10 }, "0", 10)]
|
||||||
|
public void Get(int[] input, string position, object expected)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
|
||||||
|
var targetObject = new List<int>(input);
|
||||||
|
var listAdapter = new ListAdapter();
|
||||||
|
string message = null;
|
||||||
|
object value = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var getStatus = listAdapter.TryGet(targetObject, position, resolver.Object, out value, out message);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(getStatus);
|
||||||
|
Assert.Equal(expected, value);
|
||||||
|
Assert.Equal(new List<int>(input), targetObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new int[] { }, "0")]
|
||||||
|
[InlineData(new[] { 10, 20 }, "-1")]
|
||||||
|
[InlineData(new[] { 10, 20 }, "2")]
|
||||||
|
public void Remove_IndexOutOfBounds(int[] input, string position)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
|
||||||
|
var targetObject = new List<int>(input);
|
||||||
|
var listAdapter = new ListAdapter();
|
||||||
|
string message = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out message);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(removeStatus);
|
||||||
|
Assert.Equal(
|
||||||
|
string.Format("The index value provided by path segment '{0}' is out of bounds of the array size.", position),
|
||||||
|
message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(new[] { 10, 20 }, "0", new[] { 20 })]
|
||||||
|
[InlineData(new[] { 10, 20 }, "1", new[] { 10 })]
|
||||||
|
[InlineData(new[] { 10 }, "0", new int[] { })]
|
||||||
|
public void Remove(int[] input, string position, int[] expected)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var resolver = new Mock<IContractResolver>(MockBehavior.Strict);
|
||||||
|
var targetObject = new List<int>(input);
|
||||||
|
var listAdapter = new ListAdapter();
|
||||||
|
string message = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var removeStatus = listAdapter.TryRemove(targetObject, position, resolver.Object, out message);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(removeStatus);
|
||||||
|
Assert.Equal(new List<int>(expected), targetObject);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Replace_NonCompatibleType_Fails()
|
public void Replace_NonCompatibleType_Fails()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue