Skip to content

Commit 92dc8b5

Browse files
Fix for incorrect reporting of a type mismatch when object mapping fails and a Vector type is involved. (#871)
* Fix for incorrect reporting of a type mismatch when object mapping fails and a Vector type is involved. Before the fix the error reported when trying to map from, for example, a Vector<float> to a Vector<double> was: System.InvalidOperationException: The expected value `Neo4j.Driver.Vector`1[System.Single]` is different from the actual value `System.Collections.Generic.List`1[System.Single]` This was occurring because the ValueExtensions As method did not contain a clause for IVector, this caused the logic to fall through to the IEnumerable clause (which a vector implements) which converted the vector into a list, and then failed the type conversion on that list. Now that a clause for IVector is added you get the correct error. e.g. For the Vector<float> -> Vector<double> example: System.InvalidOperationException: The expected value `Neo4j.Driver.Vector`1[System.Single]` is different from the actual value `Neo4j.Driver.Vector`1[System.Double]` * Added tests to check on vector conversions in the valueExtensions class. Vectors should not be able to be converted to any other type, or between mismatched vectors.
1 parent b39720b commit 92dc8b5

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

Neo4j.Driver/Neo4j.Driver.Tests/ValueExtensionsTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,30 @@ public void ShouldThrowExceptionWhenCastFromListToInt()
236236
var ex = Record.Exception(() => value.As<int>());
237237
ex.Should().BeOfType<InvalidCastException>();
238238
}
239+
240+
[Fact]
241+
public void ShouldThrowExceptionWhenCastFromVectorToNonVector()
242+
{
243+
object value = new Vector<float>(new[] { 1.0f, 2.0f, 3.0f, 4.0f });
244+
var ex = Record.Exception(() => value.As<int>());
245+
ex.Should().BeOfType<InvalidCastException>();
246+
}
247+
248+
[Fact]
249+
public void ShouldThrowExceptionWhenCastFromNonVectorToVector()
250+
{
251+
object value = (int)10;
252+
var ex = Record.Exception(() => value.As<Vector<int>>());
253+
ex.Should().BeOfType<InvalidCastException>();
254+
}
255+
256+
[Fact]
257+
public void ShouldThrowExceptionWhenCastingBetweenMismatchedVectors()
258+
{
259+
object value = new Vector<float>(new[] { 1.0f, 2.0f, 3.0f, 4.0f });
260+
var ex = Record.Exception(() => value.As<Vector<double>>());
261+
ex.Should().BeOfType<InvalidCastException>();
262+
}
239263
}
240264

241265
public class AsCollectionTypeMethod

Neo4j.Driver/Neo4j.Driver/Public/Extensions/ValueExtensions.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@ public static T As<T>(this object value)
149149
{
150150
return Convert.ChangeType(value, targetType).AsItIs<T>();
151151
}
152+
153+
//If the source type (value) is a vector then it can not be cast to anything else. We also want to
154+
//make sure that it is not attempting to cast into a vector of another type.
155+
if (value is IVector)
156+
{
157+
return AsVector<T>(value);
158+
}
152159

153160
// force to cast to a dict or list
154161
var typeInfo = targetType.GetTypeInfo();
@@ -197,6 +204,17 @@ private static T AsList<T>(this IEnumerable value, TypeInfo typeInfo)
197204
return list.AsItIs<T>();
198205
}
199206

207+
private static T AsVector<T>(this object value)
208+
{
209+
if (value is T result)
210+
{
211+
return result;
212+
}
213+
214+
throw new InvalidCastException($"Cannot cast differing vector types. Attempting from `" +
215+
$" { typeof(T) }` to `{value.GetType()}");
216+
}
217+
200218
#region Helper Methods
201219

202220
private static object InvokeStatic(this MethodInfo method, params object[] parameters)

0 commit comments

Comments
 (0)