Moq Overloaded Property in VB.Net - vb.net

I have a legacy class something along the lines of this:
Public Class MyOverloadExample
Public Overridable ReadOnly Property SomeDescription() As String
Get
Return "No Parameter"
End Get
End Property
Public ReadOnly Property SomeDescription(ByVal p1 As Integer) As String
Get
Return "Used Parameter"
End Get
End Property
End Class
I want to SetupGet on the first SomeDescription Property with no parameters. I tried this:
Dim mock = New Mock(Of MyOverloadExample)
mock.SetupGet(Function(i) i.SomeDescription()).Returns("Mocked the No Parameter Property")
But it fails with this exception:
threw exception:
System.Reflection.AmbiguousMatchException: Ambiguous match found.
at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetProperty(String name, BindingFlags bindingAttr)
at Moq.ExpressionExtensions.ToPropertyInfo(LambdaExpression expression) in C:\projects\moq4\src\Moq\ExpressionExtensions.cs:line 47
at Moq.Mock.SetupGetPexProtected[T,TProperty](Mock`1 mock, Expression`1 expression, Condition condition) in C:\projects\moq4\src\Moq\Mock.cs:line 511
at Moq.PexProtector.Invoke[T1,T2,T3,TResult](Func`4 function, T1 arg1, T2 arg2, T3 arg3) in C:\projects\moq4\src\Moq\PexProtector.cs:line 38
at Moq.Mock.SetupGet[T,TProperty](Mock`1 mock, Expression`1 expression, Condition condition) in C:\projects\moq4\src\Moq\Mock.cs:line 496
at Moq.Mock`1.SetupGet[TProperty](Expression`1 expression) in C:\projects\moq4\src\Moq\Mock.Generic.cs:line 332
I tried without the empty () but get the same exception:
mock.SetupGet(Function(i) i.SomeDescription).Returns("Mocked the No Parameter Property")
Is there some lambda/moq magic I'm missing or is this just not possible with Moq?

Related

Stack too deep, try using less variables on creating contract

I am trying to create a contract from a contract factory using the following function:
function createContract(string _var1, string _var2,
uint32 _var3, string _var4, string _var5,
string _var6, uint32 _var7, uint32 _var8, uint32 _var9,
uint32 _var10, uint32 _var11)
public returns (address contractAddress) {
return new Contract(_var1, random1, random2, _var2,
_var3, _var4, _var5, _var6, _var7, _var8,
_var9, _var10, _var11);
}
N.B. random1 and random2 are fields in the contract factory.
This function throws Stack too deep, try using less variables. I have read that I should split up the function etc. to get around this, but obviously, that is not an option here. Is there a way to get this working?
So, initially I tried grouping the variables by type into this:
function createContract(string[] _var1, uint32[] _var2)
public returns (address contractAddress) {
return new Contract(_var1, random1, random2, _var2);
}
However, nested dynamic arrays are not supported at this time. As string is represented as byte[] in EVM, a string[] is in fact passed as a byte[][].
I ended up grouping the uint32 and leaving the strings:
function createContract(string _var1, string _var2, uint32[] _var3,
string _var4, string _var5, string _var6)
public returns (address contractAddress) {
return new Contract(_var1, random1, random2, _var2,
_var3, _var4, _var5, _var6);
}
EDIT: Even though this method works, it is badly designed. See my other answer for a better workaround for this.
I went one step further with this as having an array of unit32 is ambiguous and confusing in terms of the position of a specific argument.
My final attempt utilized the struct type to provide a less ambiguous implementation. This struct is in a library in a separate file Library.sol:
struct ContractArgs {
uint32 var1;
string var2;
uint32 var3;
....
}
The factory method looks like this:
function createContract(Library.ContractArgs _contractArgs)
public returns (address contractAddress) {
return new Contract(_contractArgs, random1, random2);
}
And my constructor looks like this:
function Contract(Library.ContructorArgs _contractorArgs,
uint32 _supplierId, string _supplierName) {
contractArgs = _contractArgs;
random1 = _random1;
random2 = _random2;
}

Need help defining a machine integer

I'm using the mach.int library in a specification (see also this question), and I'm trying to define a constant that is of type int32:
let constant_out1: int32 = 1 in
…
However, when analyzing this, why3 returns the message:
This term has type int, but is expected to have type int32
I noticed that Bounded_int (which Int32 instantiates with type int32) has the following in it:
val of_int (n:int) : t
requires { "expl:integer overflow" in_bounds n }
ensures { to_int result = n }
However, I do not seem to be able to use this to cast 1 to int32. For example, if I use:
let constant_out1: int32 = Int32.of_int(1) in
…
I get the message unbound symbol 'Int32.of_int'. I've tried many permutations of this, all without any success. Can anyone provided guidance for how to tell why3 that I want 1 to be of type int32?

Sitecore Crawler : AddRecursive DoItemAdd failed

Our crawler log is filled with the following Index Out of Bounds Exception. Has anyone seen this error? Or have any ideas on how to resolve?
4548 00:37:31 WARN Crawler : AddRecursive DoItemAdd failed - {DDAFF741-80D0-4650-8E73-02A88EB2C8DC}
Exception: System.IndexOutOfRangeException
Message: Index was outside the bounds of the array.
Source: Sitecore.Kernel
at Sitecore.Caching.ItemPathsCache.UpdateKeyIndex(List`1 list, String value)
at System.Collections.Concurrent.ConcurrentDictionary`2.AddOrUpdate(TKey key, TValue addValue, Func`3 updateValueFactory)
at Sitecore.Caching.ItemPathsCache.AddMapping(Item item, ItemPathType itemPathType, String path)
at Sitecore.Data.ItemPath.DoGetPath(Item currentItem, String separator, ItemPathType type, Item root, Int32 level)
at Sitecore.Data.ItemPath.DoGetPath(Item currentItem, String separator, ItemPathType type, Item root, Int32 level)
at Sitecore.Data.ItemPath.DoGetPath(Item currentItem, String separator, ItemPathType type, Item root, Int32 level)
at Sitecore.Data.ItemPath.DoGetPath(Item currentItem, String separator, ItemPathType type, Item root, Int32 level)
at Sitecore.Data.ItemPath.DoGetPath(Item currentItem, String separator, ItemPathType type)
at Sitecore.Data.ItemPath.DoGetPath(Item currentItem, String from, String separator, ItemPathType type)
at Sitecore.Data.ItemPath.GetPath(Item currentItem, String from, String separator, ItemPathType type)
at Sitecore.Data.ItemPath.get_ContentPath()
at Sitecore.ContentSearch.SitecoreItemCrawler.DoAdd(IProviderUpdateContext context, SitecoreIndexableItem indexable)
at Sitecore.ContentSearch.HierarchicalDataCrawler`1.CrawlItem(T indexable, IProviderUpdateContext context, CrawlState`1 state)

Marshaling structure with reference-type and value-type members inside a union

bellow code is the marshling of a native win32 code.
but i get an error message
type load exception, can not load from assembly because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field
there is a structure S1 with both value-type member and reference-type.. this structure is a member of union which has to have fieldOffset, but all S1 members can not start from fieldOffset 0 they are a mixture of reference and value type...how can I handle that??
[StructLayout(LayoutKind.Sequential)]
public struct S1
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Const.FieldSizeMsgid + 1)]//Reference Type
public String MsgId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Const.FieldSizeTime + 1)]//Reference Type
public String SendTime;
public UInt32 SubsSeq;//Value Type
public UInt32 ServTime;//Value Type
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = Const.FieldSizeFillerA1 + 1)]//Reference Type
public String Filler;
}
[StructLayout(LayoutKind.Explicit)]
public struct AdminData
{
[FieldOffset(0)] public S1 S11;// get an error because the S1 has both reference type member and value type member
[FieldOffset(0)] public S2 S22;
[FieldOffset(0)] public S3 S33;
}
I know I have to break the S1 into 2 structures, one with value-type members and the other for reference-type members..but I do not know how to do it and how to reference them in AdminData which is a union.
EDIT:
here is the c++ code
typedef struct S1
{
char MsgId [Const.FieldSizeMsgid + 1];//Reference Type
char SendTime[Const.FieldSizeTime + 1];//Reference Type
int SubsSeq;//Value Type
int ServTime;//Value Type
char Filler[Const.FieldSizeFillerA1 + 1];//Reference Type
}
union AdminData
{
S1 S11;//has both value type member and reference type member
S2 S22;//has both value type member and reference type member
S3 S33;//has both value type member and reference type member
}
typedef struct MMTPMsg
{
int Length;
short Type;
AdminData Data; //the union
long long TimeStamp;
}
As you have discovered you cannot overlay reference types on top of value types. So to implement your union, you need to use either one or the other. Your structures must contain value types and so we conclude that you must use value types exclusively.
So, how do you implement your character arrays as value types? By using a fixed size buffer.
unsafe public struct S1
{
fixed byte MsgId[Const.FieldSizeTime + 1];
....
}

Best way to convert object to integer

I wish to safely convert an object from an external cache to an Integer type.
The only way I can seem to do this is inside a try catch block like so:
Try
Return Convert.ToInt32(obj)
Catch
'do nothing
End Try
I hate writing catch statements like this.
Is there a better way?
I have tried:
TryCast(Object, Int32)
Doesn't work (must be reference type)
Int32.TryParse(Object, result)
Doesn't work (must be a string type)
UPDATE
I like the comment posted by Jodrell - this would make my code look like this:
Dim cacheObject As Object = GlobalCache.Item(key)
If Not IsNothing(cacheObject) Then
If TypeOf cacheObject Is Int32 Then
Return Convert.ToInt32(cacheObject)
End If
End If
'Otherwise get fresh data from DB:
Return GetDataFromDB
Clarification: the question was originally tagged c# vb.net; the following applies to C# only (although may be translated into VB.NET):
If it is a boxed int, then:
object o = 1, s = "not an int";
int? i = o as int?; // 1, as a Nullable<int>
int? j = s as int?; // null
so generalising:
object o = ...
int? i = o as int?;
if(i == null) {
// logic for not-an-int
} else {
// logic for is-an-int, via i.Value
}
Unesscessary conversion to String should be avoided.
You could use Is to check the type beforehand
Dim value As Integer
If TypeOf obj Is Integer Then
value = DirectCast(obj, Integer)
Else
' You have a problem
End If
or,
You could implement a variation on TryCast like this,
Function BetterTryCast(Of T)(ByVal o As Object, ByRef result As T) As Boolean
Try
result = DirectCast(o, T)
Return True
Catch
result = Nothing
Return False
End Try
End Function
Which you could use like this
Dim value As Integer
If BetterTryCast(obj, value) Then
// It worked, the value is in value.
End If
The simplest one is
Int32.TryParse(anObject.ToString, result)
Every Object has a ToString method and calling Int32.TryParse will avoid a costly (in terms of perfomance) exception if you Object is not a numeric integer. Also the value for result, if the object is not a string will be zero.
EDIT. The answer from Marc Gravell raised my curiosity. Its answer seems complex for a simple conversion, but it is better? So I have tried to look at the IL code produced by its answer
object o = 1, s = "not an int";
int? i = o as int?; // 1, as a Nullable<int>
int? j = s as int?; // null
IL CODE
IL_0000: ldc.i4.1
IL_0001: box System.Int32
IL_0006: stloc.0 // o
IL_0007: ldstr "not an int"
IL_000C: stloc.1 // s
while the IL CODE produced by my answer is the following
IL_0000: ldc.i4.1
IL_0001: box System.Int32
IL_0006: stloc.0 // anObject
IL_0007: ldloc.0 // anObject
IL_0008: callvirt System.Object.ToString
IL_000D: ldloca.s 01 // result
IL_000F: call System.Int32.TryParse
Definitively the answer from Marc is the best approach. Thanks Marc to let me discover something new.
this works:
Int32.TryParse(a.ToString(), out b);