Giter Site home page Giter Site logo

mockeverything's People

Contributors

arseni-mourzenko avatar

Stargazers

 avatar  avatar

Watchers

 avatar

mockeverything's Issues

The indexer overloads aren't handled correctly

When dealing with classes containing indexer overloads, an exception is thrown by MockEverything.Inspection.MonoCecil.Type.FindPropertyByName(string) : PropertyDefinition because Single is applied to a sequence containing multiple elements.

A way to reproduce this issue it to call Type.FindMethods() on a class containing several indexers, such as:

public class Demo
{
    public string this[int i] { get { return string.Empty; } }
    public string this[string i] { get { return string.Empty; } }
}

Arguments mismatch between static proxies and the corresponding instance methods

In C#, the arguments of instance methods start by the instance itself. In other words, for an instance method which takes a string as a parameter, in the corresponding IL code, ldarg.0 refers to this, and ldarg.1 refers to the actual string. On the other hand, if the same method is static, ldarg.0 refers directly to the string.

For example, in the following code:

public class DemoInstance
{
    public void SayHello(string name)
    {
        Console.WriteLine("Hello, {0}!", name);
    }
}

public static class DemoStatic
{
    public static void SayHello(string name)
    {
        Console.WriteLine("Hello, {0}!", name);
    }
}

the instance method is translated into:

IL_0000: nop
IL_0001: ldstr "Hello, {0}!"
IL_0006: ldarg.1
IL_0007: call void [mscorlib]System.Console::WriteLine(string, object)
IL_000c: nop
IL_000d: ret

while the static method becomes:

IL_0000: nop
IL_0001: ldstr "Hello, {0}!"
IL_0006: ldarg.0
IL_0007: call void [mscorlib]System.Console::WriteLine(string, object)
IL_000c: nop
IL_000d: ret

Since all proxies are static, this leads to a bug which can be reproduced by using the arguments passed to a method (for example by throwing an exception containing in its message all the arguments). The bug is very weird: either it leads to a crash, or the values of the arguments are totally creepy.

When proxy methods correspond to an instance method in the tampered assembly, arguments should be shifted.

A proxy method containing four or more arguments cannot be used

Following #6, if a proxy method contains and uses more than three arguments, the following exception is thrown:

Error   3   opcode   at Mono.Cecil.Cil.Instruction.Create(OpCode opcode, Int32 value)
   at MockEverything.Inspection.MonoCecil.Method.ShiftArguments(Instruction instruction) in C:\Git\mockeverything\MockEverything\Source\Inspection\MonoCecil\Method.cs:line 225
   at MockEverything.Inspection.MonoCecil.Method.ReplaceCollectionContents[TElement](IEnumerable`1 source, Collection`1 destination, Func`2 transform) in C:\Git\mockeverything\MockEverything\Source\Inspection\MonoCecil\Method.cs:line 260
   at MockEverything.Inspection.MonoCecil.Method.ReplaceBody(MethodDefinition definition) in C:\Git\mockeverything\MockEverything\Source\Inspection\MonoCecil\Method.cs:line 195
   at MockEverything.Inspection.MonoCecil.Method.ReplaceBody(IMethod other) in C:\Git\mockeverything\MockEverything\Source\Inspection\MonoCecil\Method.cs:line 177
   at MockEverything.Engine.Tampering.Tampering.Rewrite(Assembly assembly) in C:\Git\mockeverything\MockEverything\Source\Engine\Tampering\Tampering.cs:line 161
   at MockEverything.Engine.Tampering.Tampering.Tamper(String[] dependenciesLocations) in C:\Git\mockeverything\MockEverything\Source\Engine\Tampering\Tampering.cs:line 77
   at MockEverything.BuildTask.TamperingTask.ProcessProxy(Tampering tampering) in C:\Git\mockeverything\MockEverything\Source\BuildTask\TamperingTask.cs:line 100
   at MockEverything.BuildTask.TamperingTask.Execute() in C:\Git\mockeverything\MockEverything\Source\BuildTask\TamperingTask.cs:line 60 [...]

Document better the custom build task

Consider explaining in documentation a way to see in Visual Studio the logs produced by the custom build task, as well as the way to quickly run just the task, separately from Visual Studio.

A match of a method which uses params cannot be found

When the proxy has a method which uses params, the following exception is thrown:

Error   3   Sequence contains no matching element   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
   at MockEverything.Inspection.MonoCecil.Type.FindPropertyByName(String name, IEnumerable`1 parameters) in C:\Git\mockeverything\MockEverything\Source\Inspection\MonoCecil\Type.cs:line 334
   at MockEverything.Inspection.MonoCecil.Type.FindAttributesOfGetterOrSetter(MethodDefinition methodDefinition) in C:\Git\mockeverything\MockEverything\Source\Inspection\MonoCecil\Type.cs:line 319
   at MockEverything.Inspection.MonoCecil.Type.FindAttributesOfMethod(MethodDefinition methodDefinition) in C:\Git\mockeverything\MockEverything\Source\Inspection\MonoCecil\Type.cs:line 299
   at MockEverything.Inspection.MonoCecil.Type.MatchAttributesFilter(MethodDefinition methodDefinition, ICollection`1 attributes) in C:\Git\mockeverything\MockEverything\Source\Inspection\MonoCecil\Type.cs:line 282
   at MockEverything.Inspection.MonoCecil.Type.<>c__DisplayClass10_0.<FindMethods>b__1(MethodDefinition definition) in C:\Git\mockeverything\MockEverything\Source\Inspection\MonoCecil\Type.cs:line 123
   at System.Linq.Enumerable.<>c__DisplayClassf`1.<CombinePredicates>b__e(TSource x)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at MockEverything.Engine.Browsers.MethodMatching.FindMatch(IMethod proxy, IType targetType) in C:\Git\mockeverything\MockEverything\Source\Engine\Matching\MethodMatching.cs:line 33
   at MockEverything.Engine.Browsers.Browser`2.CreateMatch(TElement proxyType) in C:\Git\mockeverything\MockEverything\Source\Engine\Browsers\Browser{TElement,TContainer}.cs:line 92
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext()
   at MockEverything.Engine.Tampering.Tampering.Rewrite(Assembly assembly) in C:\Git\mockeverything\MockEverything\Source\Engine\Tampering\Tampering.cs:line 158
   at MockEverything.Engine.Tampering.Tampering.Tamper(String[] dependenciesLocations) in C:\Git\mockeverything\MockEverything\Source\Engine\Tampering\Tampering.cs:line 77
   at MockEverything.BuildTask.TamperingTask.ProcessProxy(Tampering tampering) in C:\Git\mockeverything\MockEverything\Source\BuildTask\TamperingTask.cs:line 100
   at MockEverything.BuildTask.TamperingTask.Execute() in C:\Git\mockeverything\MockEverything\Source\BuildTask\TamperingTask.cs:line 60
   ...

Implement logging collector

Console.WriteLine() and Trace.WriteLine() cannot be used within the proxies, since the messages never appear in the actual console or trace.

Implement an exchanger which is able to collect logs (preferably transparently by subscribing to console and trace messages) and send it to the caller.

mscorlib is not supported

The current (documented) limitation is that the product cannot be used to tamper mscorlib. This is unfortunate, given the amount of legacy code which relies on “basic” .NET Framework classes such as System.IO.File, preventing it from being tested.

According to the documentation, this limitation comes from a problem within ILRepack. A fork of ILRepack should be done in order to make it possible to tamper mscorlib.

Poor performance when dealing with large assemblies

When dealing with large assemblies such as Microsoft.SharePoint, the time it takes to tamper it is terrible (up to one minute on an average machine).

The solution could be to create a stripped version of ILRepack which, eventually, merges proxy assembly to target one, instead of creating an empty assembly.

Another solution, which seems too scary, is to inject proxy code directly inside the assembly. This was attempted in the early prototypes, and appeared to be overly complicated.

Crash when the property is prefixed with interface name

The actual #4 appeared to be an issue related to the properties when their names are prefixed with an interface name. In this case, the inspection attempts to find a property based on the name of the getter, and fails, leading to the exception in #4.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.