Saturday, July 14, 2007

Pex can analyze regular expressions*** and generate strings that matches them automatically!

What does it mean? Well, maybe, somewhere deep in your code your are validating some string with a regex (for example a url). In order to test the validation code, one needs to craft inputs that does not match (easy) and matches (harder) the regex.

Let Pex do it:

So what if Pex could be smart enough to understand a regex and craft inputs accordingly? In the example below, it would be very hard for a random generate to generate a string that matches the regex.

[PexTest]
public void Url([PexAssumeIsNotNull]string s)
{
    if (Regex.IsMatch(s, "(?<Protocol>\w+):\/\/(?<Domain>[\w@][\w.:@]+)\/?[\w\.?=%&=\-@/$,]*"))
        throw new PexCoverThisException(); // random won't find this
}

"" would be a failing match and foo://foo.com a good match. (To generate the correct match, my brain simulated the regex automaton and estimated one possible path). Interestingly, Pex generates....

Ā://Āā

Pretty ugly... but correct! This reminds us that while regex are used to validate input, what they'll let through is sometimes scary.

Compiled Regex + Pex = Love

The great part about supporting the regular expressions is that it comes for free (almost) since Regex can be compiled to IL in .Net. When the BCL generates the regex IL code, it effectily builds the automaton... which can be analyzed by Pex!!!

Refresher: Pex works analyzing the MSIL being executed.

Hey but not all Regex are compiled!

That's true. Compiling the regex is optional so Pex needs to do a little bit of 'plumbing' to make sure all regular expressions are compiled. This is simply done by substituting the real .ctor of the Regex class with a customized version that compiles the regex. I'll talk about substitutions deeper in the future.

*** Of course, the bigger the regex is, the harder it is going to be for Pex to craft a successful match.

posted on Sunday, July 15, 2007 4:49:53 AM UTC  #    Comments [1]
 Sunday, July 08, 2007

I finally posted a project that I had been developing last year in my daily commutes: Toad (www.codeplex.com/toad).

Toad is an (experimental) compiler infrastructure to build languages top of .Net, without knowing much about IL. Mostly it was a way for me to learn first hand all the little subtleties of writing multiple language on top of .Net.

What does Toad give you?

  • A dynamic console that supports multiple languages,
  • An Expression/Statement tree that can be translated back to IL,
  • Built-in debugging capabilities,
  • A set of Visitors on top this AST that implement various optimization and language constructs (this is the fun part),
  • There's a lot of stuff, I used to take the bus twice a day. :)
  • Toad does not use the DLR maybe in the future.

What is it good for?

  • Toy around with IL and try to build your micro language.
  • Don't use it for anything serious.

Good For Nothing Language

 The 'Good for nothing' language is a toy language that Joel Pobar used to illustrate managed IL compilers. With Gfn, you can write simple program such as:

var i = 123;
print i;
for j = i to 10 do print i+j; end;

The parsing stuff

I took Joel's example and wrote a grammar for the Gold parser. It looks like something like this that is then compiled by Gold:

<Program> ::= <BlockStatement>

<BlockStatement> ::= <BlockStatement> <Statement> ';'
            | <Statement> ';'

<Statement> ::= 'var' Identifier '=' <Expression>
    | Identifier '=' <Expression>
    | 'for' Identifier '=' <Expression> 'to' <Expression> 'do' <BlockStatement> 'end'
    | 'read_int' Identifier
    | 'print' <Expression>
    | 'return' <Expression>

At the end of the process, you get a visitor for the code AST. This is the boiler plate code to start using Toad to build the compiler:

// <Statement> ::= for Identifier '=' <Expression> to <Expression> do <BlockStatement> end
protected virtual object VisitRuleStatementforIdentifierEqtodoend(SyntaxNode node)
{
     throw new NotSupportedException("RuleStatementforIdentifierEqtodoend");
}

Implementing the 'for' loop

Let's take a look at the implementation of the for loop. We need to:

  • extract the from, to expressions,
  • declare a variable for the index,
  • build the predicate i < to etc...,
  • emit symbols for debugging,

The code below shows the full implementation of that statement:

// <Statement> ::= for Identifier '=' <Expression> to <Expression> do <BlockStatement> end
protected override object VisitRuleStatementforIdentifierEqtodoend(SyntaxNode node)
{
    // from, to
    Expression from = (Expression)this.VisitNode(node[3]);
    Expression to = (Expression)this.VisitNode(node[5]);

    // x = from
    VariableDeclarationStatement init = Stm.Var(node[1].Data, from);

    // body
    this.Context.PushScope();
    this.Context.PushVariable(init.Variable);

    Unit body = (Unit)this.VisitNode(node[7]);

    // i < to;
    Expression ilto = Expr.LessThanOrEqual(Expr.Var(init), to);
    ilto.Symbol = FromNode(node[1]);
    // ++i
    Statement inc = Stm.Expr(Expr.PrePlusPlus(Expr.Var(init)));

    this.Context.PopScope();

    ForStatement forstm = Stm.For(init, ilto, inc);
    forstm.Body = Stm.FromUnit(body);

    return forstm;
}

Hooking up the visitor in Toad

The last step is to package our visitor as a 'language' and return the generated statements or expression to Toad. We can spin up the interactive console, load Gfn and try it out:

image

Nothing really mind blowing here. Let's turn on live IL debugging to see what happening under the hood. This mode emits the IL source of the method, adds a bunch of 'nop' instructions to force the debugger to step on each IL instruction:

image

You can see in the generated code how the expressions got translated into IL instructions. 

posted on Monday, July 09, 2007 5:23:32 AM UTC  #    Comments [0]
 Thursday, July 05, 2007

Pex has a couple samples that get bundled in our installer. We have them in our main solution so that we get the benefits of Refactoring (that they still compiled :)). This approach has one little problem: the sample projects are referencing the Pex projects... which are not shipped! If packaged as is, they'll never compile on the user's machine.

ProjectReference -> Reference

We solved this problem by implementing an MSBuild task that 'patches' .csproj project files by replacing ProjectReference nodes with Reference:

<ProjectReference Include="..\..\..\Pex\Framework\Microsoft.Pex.Framework.csproj">
  ...
</ProjectReference>

becomes

<Reference Include="Microsoft.Pex.Framework">...</Reference>

There's a bit of coding involved to it (resolving the assembly name, selecting the appropriate projects, etc...) but that's basically it :)

posted on Thursday, July 05, 2007 11:02:38 PM UTC  #    Comments [0]
 Wednesday, July 04, 2007

One of the problem with Pex is that.... it's yet another dependency in your test project. Pex has it's own attributes which makes it very difficult to 'strip it out' of the test source. Many teams won't allow to check-in assemblies, they won't install external components on the build machine and just forget about touching the source code!

So how do you strip Pex?

In "Condition" lies the answer

An elegant solution uses a bit of Reflection, CodeDom and the MSBuild Condition attribute: generate Attribute stubs (shadows) and bind them to the project.

Pex modifies the project file and uses MSBuild conditions to conditionally include files and assembly references in the generated test project.

  • A boolean property PexShadows to controls the shadowing state: true if shadowed, false or missing otherwize.
<Project DefaultTargets="Build" ...>
  <PropertyGroup>
    ...
    <PexShadows>true</PexShadows>
  </PropertyGroup>
  • a conditional reference to Microsoft.Pex.Framework:
    <Reference 
        Include="Microsoft.Pex.Framework" 
        Condition="$(PexShadows) != 'true'" />

when the property PexShadows evalutes to true, the Microsoft.Pex.Framework assembly is not referenced anymore.

  • a file containing all the custom attributes 'stubs' (for all attributes in the Microsoft.Pex.Framework) is generated (automatically of course :)). Pex also dumps the source of several other helper classes. Each generated file is added to the test project conditionally:
    <Compile Include="Properties\PexAttributes.cs" Condition="$(PexShadows) == 'true'">
      <AutoGen>True</AutoGen>
      <DependentUpon>AssemblyInfo.cs</DependentUpon>
    </Compile>

That's it! Flip the value of PexShadows to bind/unbing your test project from Pex.

So what does Visual Studio says ?

Visual Studio is totally fooled by the maneuver. It shows the conditional files and references as if nothing happened. Add a menu item in the project context menu to switch it on and off and we are good to go :)

posted on Wednesday, July 04, 2007 12:28:12 PM UTC  #    Comments [0]
 Saturday, June 30, 2007

In Pex, we added the possibility to specify the type under test of a given fixture:

public class Account {...}


[TestFixture, PexClass(typeof(Account))]
public class AccountTest {...}  

That's nice but why would it be useful... Beyond the fact that it clearly expresses the 'target' of the fixture, this kind of information can be leverage by tools like Pex.

For example, since we know that Account is the type under test, we can tune Pex to prioritize the exploration of the Account type.

Another interesting side effect is the targeted code coverage data. Instead of getting coverage information over the entire assembly, we can directly provide coverage over the type under test: the AccountTest covered xx% of Account.

Still toying around the concept, one can add a special filtering mode to the command line to execute all tests that target 'Account':

pex.exe /type-under-test:Account Bank.Tests.dll
posted on Saturday, June 30, 2007 2:23:24 PM UTC  #    Comments [0]
 Sunday, June 03, 2007

A nice side effect of the Pex infrastructure is that it computes coverage data while exploring a parameterized test. What does this mean to the user? Well, what about this specifying that a parameterized test should reach 100% coverage**:

[PexTest]
[PexExpectedCoverage(100)] // expect 100% coverage
public void UberTest(int i)
{ ... }
** What kind of coverage are we talking about?

Pex internally tracks implicit branch coverage (which can never be covered :)). So we usually refer to basic block coverage. By default, the coverage is reported for the code that was run by the parameterized test. This is a very important difference with usual coverage tools, which give numbers for the entire assembly.

posted on Sunday, June 03, 2007 12:24:56 PM UTC  #    Comments [0]
 Saturday, June 02, 2007

This post gives a little introduction on the integrated mock support in Pex (it should also make clear why we couldn't reuse existing (and excellent) mock framework).

As other frameworks, Pex support mocking interfaces or virtual methods in non sealed classes.

Choose and replay

Pex Mocks have 2 modes of execution that are quite different:

  • when Pex is looking for new input, they act as a source of parameter choices, (this will be clearer in the example below).
  • when executing the generated unit tests, they act as stubs.
Micro example

Let us illustrate this by mocking a simple interface that returns the name of an instance:

interface INamed
{
    string GetName();
}
Writing the mock

The mock for this interface looks as follows:

[PexMock] // specifies to pex that this type is a mock
public class MNamed : INamed
{
    public string GetName()
    {
        IPexMethodCallOracle call = PexOracle.MethodCall(this);
        // let's ask Pex for a name    
        return call.ChooseResult<string>(); 
    }
}

So what did we do really: The mock implementation of GetName fetches a value oracle,  an interface from which new values can be queried:

IPexMethodCallOracle call = PexOracle.MethodCall(this); 

Then, this oracle can be used to choose new values. It's like adding parameters to the test, but not through the test signature. In this case, we ask Pex to get a new result value. Pex will choose that value as if it was a parameter of the test:

return call.ChooseResult<string>();
Let's try it!

The following test takes a INamed instance (which we assumed to be non-null) and displays a message on the console if the name is equal to'Marc':

[PexTest]
public void GetName(INamed name)
{
    if (name.GetName() == "Marc")
        Console.WriteLine("hello marc");
}
Generated tests

Pex generates 2 unit tests that fully covers the code of method: Pex tracked the data returned by ChooseResult and computed that this value had to be equal to "Marc" to hit a different path in the execution.

The first test has GetName return a default value. The second generated test is more interresting as it shows how Pex sets up the behavior of the replay stub:

// test 2
MockTest.MNamed mn0 = new MockTest.MNamed();
IPexOracleRecorder oracle = PexOracle.NewTest();
oracle.OnCall(0, typeof(MockTest.MNamed), "GetName")
      .Returns("Marc");
this.GetName(mn0);

The oracle instance is used to set up the result value on the first call to GetName:

// on the call '0' to the method GetName of MockType.MNamed,
oracle.OnCall(0, typeof(MockTest.MNamed), "GetName")
      // return "Marc"
      .Returns("Marc");
Adding behavior

Behavior can simply be added to mock as code since Pex will explore the mock code as well. For example, let's refine the MNamed implementation to always return the same name:

[PexMock] // specifies to pex that this type is a mock
public class MNamed : INamed
{
    private string name;
    public string GetName()
    {
        if(this.name == null)
            this.name = PexOracle.MethodCall(this)
                              .ChooseNotNull<string>("name");
        return this.name;
    }
}
Wrapping Up

In this post, we've given a brief glimpse at the pex oracles. These are a special breed of mocks specific to Pex.

posted on Saturday, June 02, 2007 2:00:50 PM UTC  #    Comments [0]
 Sunday, May 27, 2007

.Net 2.0 has been out for a while and it seems that 'generics' have not made it into unit test frameworks (that I know of). When I write unit tests for generics, I don't want to have to instantiate them!

For example, if I have an generic interface,

interface IFoo<T> {...}

then I'd really like to write this kind of test and let the test framework figure out an interresting instantiation (i.e. choice of T):

[Test]
public void Test<T>(IFoo<T> foo) { ... }

In the example above, System.Object can be trivially used to instantiate IFoo<T>. Of course, things get more interresting when mixing type argument, method argument and constraints :)

interface IFoo<T>
{
    R Bar<R>(T t)
     where R : IEnumerable<T>
}

In Pex, we've started to look at this problem... stay tuned.

posted on Sunday, May 27, 2007 1:09:00 PM UTC  #    Comments [3]
 Friday, May 25, 2007

MbUnit 2.4 is out, check it out at

http://weblogs.asp.net/astopford/archive/2007/05/24/mbunit-2-4-rtm.aspx

If you are using MbUnit parameterized tests (i.e. RowTest, CombinatorialTest) then migrating to Pex should be a piece of cake :)

posted on Friday, May 25, 2007 10:25:02 PM UTC  #    Comments [2]
 Sunday, April 22, 2007

3 years after being released on CodeProject, it was about time to dust off QuickGraph and give it generics support.

posted on Sunday, April 22, 2007 3:49:21 PM UTC  #    Comments [2]
 Friday, April 20, 2007

With parameterized unit tests, it is not uncommon to generate a large number of exceptions. An basic exception log usually looks like this: a small message and the stack trace.

Whith this kind of output, a lot of work is still left to the user since he has, *for each frame*,  to manually open the source file and move to the line refered by the trace.

Give me the source context!

In the Pex reports we added a couple lines of code to read the source for each frame and display it in the reports (no rocket science). The cool thing is that you now can get a pretty good idea of what happened without leaving the test report. Multiply that by dozens of exceptions and you've won a loooot of time.

Here are some screenshots to illustrate this: an exception was thrown in some arcane method. The error message is not really useful (as usual).

If we expand the source and actually see the code, things become much clearer...

posted on Friday, April 20, 2007 7:12:40 AM UTC  #    Comments [0]
 Wednesday, April 11, 2007

MbUnit supports different flavors of parameterized unit tests: RowTest, CombinatorialTest, etc... If you are already using those features, it would be very easy for you to 'pexify' them:

namespace MyTest
{
     using MbUnit.Framework;
     using Microsoft.Pex.Framework;

     [TestFixture, PexClass]
     public partial class MyTestFixture
{
[RowTest]
[Row("a", "b")]
[PexTest]

public void Test(string a, string b)
{
...
}


}
}

Isn't this nice? :)

Some little notes:

  • 'partial' is helpfull to emit the generated unit test in the same class... but not the same file. Pex also support another mode where partial is not required.
  • the Pex attributes do not 'interfere' with the MbUnit ones. Your unit tests will still run exactly the same with MbUnit.
posted on Wednesday, April 11, 2007 11:47:27 AM UTC  #    Comments [2]
 Sunday, April 08, 2007

The bank sample is a small example that serves as a quickstart for NUnit. In this post, we will revisit the sample and see how existing unit tests can be refactored into Pex parameterized tests.

The original unit test:

Let's start with the initial implementation of the Account class, and the first unit test case from the sample:

namespace bank
{
  public class Account
  {
    private float balance;
    public void Deposit(float amount)
    {
      balance+=amount;
    }

    public void Withdraw(float amount)
    {
      balance-=amount;
    }

    public void TransferFunds(Account destination, float amount)
    {}

    public float Balance
    {
      get{ return balance;}
    }
  }
}
namespace bank
{
  using NUnit.Framework;

  [TestFixture]
  public class AccountTest
  {
    [Test]
    public void TransferFunds()
    {
      Account source = new Account();
      source.Deposit(200.00F);
      Account destination = new Account();
      destination.Deposit(150.00F);

      source.TransferFunds(destination, 100.00F);
      Assert.AreEqual(250.00F, destination.Balance);
      Assert.AreEqual(100.00F, source.Balance);
	
    }
  }
}

Refactoring the unit test and hooking Pex

An easy oportunity to refactor a unit test into parameterized unit tests is to extract constants as parameters, namely 200F as sourceDeposit, 150F as destinationDeposit, etc... We also add the PexClass and PexTest custom attributes to tell Pex that there are some parameterized tests: 

    using Microsoft.Pex.Framework;
    [TestFixture, PexClass]
    public partial class AccountTest
    {
        [PexTest]
        public void TransferFunds(
            float sourceDeposit,
            float destinationDeposit,
            float transfer)
        {
            Account source = new Account();
            source.Deposit(sourceDeposit);
            Account destination = new Account();
            destination.Deposit(destinationDeposit);
            source.TransferFunds(destination, transfer);
            Assert.AreEqual(destinationDeposit + transfer, destination.Balance);
            Assert.AreEqual(sourceDeposit - transfer, source.Balance);
        }
    }

Iteration 1: amount should not be negative,

The first (and unique) test case that Pex generates uses float.MinValue for all values, which leads to some interresting floating point issues.

this.TransferFunds(float.MinValue, float.MinValue, float.MinValue);

...

expected: <-Infinity>

but was: <-3.40282347E+38>

at Assert.AreEqual(destinationDeposit + transfer, destination.Balance);

This little test reminds us that floats can have some weird values (infinity, minvalue, etc...).

Iteration 2: amount should not be too big,

It's time to add parameter checking to prevent negative transfer amounts. The ValidateAmount method is added in each transaction method:

        private void ValidateAmount(float amount)
        {
            if (amount < 0)
                throw new ArgumentOutOfRangeException("amount");
        }

Pex now generates 4 test cases. 3 of them pass negative values as amount to cover the argument validation code:

        [Test()]
        [ExpectedException(typeof(System.ArgumentOutOfRangeException)), ...]
        public void TransferFunds_Single_Single_Single_70408_082415_0_01()
        {
            this.TransferFunds(float.MinValue, float.MinValue, float.MinValue);
}
...
            this.TransferFunds(float.MaxValue, float.MinValue, float.MinValue);
            this.TransferFunds(float.MaxValue, float.MaxValue, float.MinValue);

The 4-th test finds another overflow by passing all float.MaxValue.

Iteration 3: NaN handling

We add a MaximumAmount field to bound the amount of money that can be transfered.


private float maximumAmount = 1000.00F;
public float MaximumAmount
{
 get{ return maximumAmount;}
}

private void ValidateAmount(float amount)
{
if (amount <= 0)
     throw new ArgumentOutOfRangeException("amount");
    if (amount > this.MaximumAmount)
      throw new ArgumentOutOfRangeException("amount");
}

We run Pex. The test still does not fail and to our surprise it generates the following passing test: 

      this.TransferFunds(float.NaN, float.NaN, float.NaN);

Oops, NaN is a very special number. Did you know that (float.NaN == float.Nan) == false? In our case, float.NaN passes the parameter validation and assertions!

Iteration 4: The test fails!

Again, we beef up the 'amount' validation to rule out NaN:

        private void ValidateAmount(float amount)
        {
            if (float.IsNaN(amount))
                throw new ArgumentOutOfRangeException("amount");
            if (amount <= 0)
                throw new ArgumentOutOfRangeException("amount");
            if (amount > this.MaximumAmount)
                throw new ArgumentOutOfRangeException("amount");
        }

We run Pex again and, at last, we find an input to fail the test:

            this.TransferFunds(float.Epsilon, float.Epsilon, float.Epsilon);
        ...
        [test] TransferFunds_Single_Single_Single_70408_113456_0_05, AssertionException:
 expected: <2.80259693E-45>
  but was: <1.40129846E-45>

Iteration 5: Implementing TransferFunds

Now that we found an input that fails the test, we can actually add some code to TransferFunds (as in the QuickStart):

        public void TransferFunds(Account destination, float amount)
        {
            this.ValidateAmount(amount);
            destination.Deposit(amount);
            Withdraw(amount);
        }

So we run Pex again and all the tests passes. Next time, we'll take look at the implementation of the 'MinimumDeposit' feature.

posted on Sunday, April 08, 2007 2:09:48 PM UTC  #    Comments [2]
 Sunday, April 01, 2007

This is the first post about Pex and how to use it. Since Pex is a fairly large project, I'll probably stretch the content of a large number of entries. Stay tunned...

Pex gives you Parameterized Unit Tests

Data-driven tests are not something new. They exist under different forms such as MbUnit's RowTest or CombinatorialTest, VSTS's DataSource, etc... So what's so special about Pex? The major difference is that Pex finds the parameter inputs for you (and generates a unit test out of it).

Whereas the user had to (smartly) guess a set of input for the data-driven tests, Pex tries to compute the relevant inputs to those tests automatically (and may also suggest fixes).

Note: The way Pex finds the input will be covered in more details later. In a couple words, Pex performs a systematic white box analysis of the program behavior. It tries to generate a minimal test suite with maximum coverage.

Parameterized Unit Tests, what does it feel like?

Parameterized unit tests are methods with parameters. There's nothing magic about that. Pex provides a set of custom attributes so that you can author them side-by-side with classic unit tests:

[TestClass, PexClass] // VSTS fixture containing parameterized tests
public class AccountTest
{
    // parameterized unit test
    // account money should never be negative, for any 'money', 'withdraw'
    [PexTest]
    public void TransferFunds(int money, int withdraw) {...}
}

When Pex finds interresting data to feed the parameterized unit test, it generates a unit test method that calls the parameterized unit test. This also means that once the unit test has been generated, you do not need Pex anymore to run the repro.

[TestClass, PexClass] // VSTS fixture containing parameterized tests
public class AccountTest
{
    [PexTest]
    public void TransferFunds(int money, int withdraw) {...}
    ...
    [TestMethod, GeneratedBy("Pex", "1.0.0.0")]
    public void TransferFunds_12345() { this.TransferFunds(12, 13); }

}

Why do I need parameterized unit tests anyway?

A parameterized unit tests generally captures more program behaviors than a single unit test which is like a micro-scenario. This will become more apparent when we start looking at some examples. 

If you were already using [RowTest] or [DataSource] as part of your testing, then you will definitely like Pex.

posted on Monday, April 02, 2007 5:52:37 AM UTC  #    Comments [2]
 Monday, March 19, 2007

Reflector.CodeMetrics swallowed the treemap coolaid ...

posted on Monday, March 19, 2007 11:01:41 AM UTC  #    Comments [0]
 Tuesday, March 13, 2007

The Pex screencast was a bit mysterious without sound and comments. I've added a 'storyboard' to help you understand it:

   http://research.microsoft.com/pex/screencast.aspx


 

posted on Tuesday, March 13, 2007 7:31:29 AM UTC  #    Comments [1]
 Thursday, March 08, 2007

Pex

I'm thrilled to present the project I joined last October: 'Pex' (for Program EXploration). Pex is a powerfull plugin for unit test frameworks that let the user write parameterized unit tests**. Pex does the hard work of computing the relevant values for those parameters, and serializing them as classic unit tests.

Here's a short screencast where we test and implement a string chunker. In the screencast, we use a parameterized unit test to express that for *any* string input and *any* chunk length, the concatenation of the chunks should be equal to the original sting.

http://research.microsoft.com/pex/screencast.aspx

More info on Pex is available at http://research.microsoft.com/pex/.

** It's actually much more than that... but let's keep that for later :)

posted on Friday, March 09, 2007 1:58:36 AM UTC  #    Comments [5]
 Saturday, February 24, 2007
 Tuesday, February 20, 2007

All my Reflector addins have a new home:

http://www.codeplex.com/reflectoraddins

Please use the codeplex issue tracking to log bugs.

 

posted on Tuesday, February 20, 2007 12:04:29 PM UTC  #    Comments [2]
 Sunday, November 19, 2006

Getting this dusty blog back to life....

posted on Sunday, November 19, 2006 10:08:28 AM UTC  #    Comments [0]
 Tuesday, September 12, 2006

GLEE, a graph layout engine developed in Microsoft Research. It is now available for downloading at http://research.microsoft.com/research/downloads/download.aspx?FUID=c927728f-8872-4826-80ee-ecb842d10371.

 

posted on Tuesday, September 12, 2006 7:13:07 AM UTC  #    Comments [1]
 Saturday, September 09, 2006

After 2 years in the CLR, I'm moving job (and building) to Microsoft Research. I will be working on Parametrized Unit Testing.

 

posted on Sunday, September 10, 2006 1:21:39 AM UTC  #    Comments [3]
 Sunday, March 12, 2006

I've refreshed the Reflector Addins and fixed a couple bugs:

  • CodeMetrics: fixed data serialization problem. Now dumping xml.
  • IL graph: back to life
  • IronPython: upgrade to beta4

Download the latest binaries as usual at http://projectdistributor.net/Projects/Project.aspx?projectId=43 

posted on Sunday, March 12, 2006 10:18:03 AM UTC  #    Comments [1]
 Wednesday, February 01, 2006

 Looks like there are some big changes ahead for me... Elliott, born sunday, loves milk and keeping his parents awake all night.  

posted on Thursday, February 02, 2006 3:14:40 AM UTC  #    Comments [0]
 Thursday, January 26, 2006

Update for Reflector 4.2.0.0

   Download at http://www.projectdistributor.net/Releases/Release.aspx?releaseId=304

.net 1.1 addins:

  • Reflector.CodeMetrics.dll (CodeMetrics)
  • Reflector.Rules.dll (Rules)
  • Reflector.ComViewer.dll (COM viewer)
  • Reflector.DesignViewer.dll (PropertyGrid, Control, XmlSerializer)
  • Reflector.TreeMap.dll (Type Tree Map)
  • Reflector.Graph.dll (Assembly Graph, IL Graph, Statement Graph)

.net 2.0 addins:

  • Reflector.IronPython.dll (IronPython console. Requires IronPython assemblies in path!)
  • Reflector.Coverage.dll (Coverage visualization)

 

posted on Thursday, January 26, 2006 3:25:12 PM UTC  #    Comments [0]
 Monday, November 21, 2005

I have updated my Reflector Addins (download available at http://projectdistributor.net/Releases/Release.aspx?releaseId=274 ).

  1. The big change is that I have splitted the addins into many assemblies which let you load more selectively which one you want.
  2. The second change is that most of the addins are now compiled against .Net 1.1. All the 1.1 addins are in the root directory, while the ones requiring 2.0 are in the 2.0 folder (which also contains a config file)!

.net 1.1 addins:

  • Reflector.CodeMetrics.dll (CodeMetrics)
  • Reflector.Rules.dll (Rules)
  • Reflector.ComViewer.dll (COM viewer)
  • Reflector.DesignViewer.dll (PropertyGrid, Control, XmlSerializer)
  • Reflector.TreeMap.dll (Type Tree Map)

.net 2.0 addins:

  • Reflector.Graph.dll (Assembly Graph, IL Graph, Statement Graph)
  • Reflector.CodeGeneration.dll (Code Generators)
  • Reflector.IronPython.dll (IronPython console. Requires IronPython assemblies in path!)
  • Reflector.Languages.dll (Reflection.Emit language)
  • Reflector.Coverage.dll (Coverage visualization)

Enjoy.

posted on Monday, November 21, 2005 11:24:45 AM UTC  #    Comments [3]
 Tuesday, November 01, 2005

There's a new addin in Reflector.Framework that let's you load COM typelib in Reflector (i.e. it generates the assembly and loads it for your).

posted on Tuesday, November 01, 2005 10:37:10 PM UTC  #    Comments [0]

There are 3 different builds for my addins, depending on the kind of depencies they require. *This is list depicts the features of the next drop 4.1.85.2*. All projects can be found on projectdistributor.net.

Each flavor is mutually exclusive! Pick your flavor depending on the dependencies and features that your are looking for!

Dependencies:

  • Common requirements:
    • Reflector 4.1.85.0 (or higher)
    • .Net 2.0 Redist

 

  • Reflector.CodeMetrics:
    • Nothing else
  • Reflector.Graph:
    • Dependency on NGraphviz (unmanaged assembly)
    • SVG viewer
  • Reflector.Framework:
    • Dependency on NGraphviz (unmanaged assembly)
    • SVG viewer

Features:

  • Reflector.CodeMetrics
    • CodeMetrics
    • Coverage datagrid
  • Reflector.Graph
    • Assembly Graph
    • IL graph (not bullet proof)
    • Statement Graph (not bullet proof)
    • Class diagram (alpha)
    • Method invocation graph (alpha)
    • Typed Dataset (alpha)
  • Reflector.Framework
    • All the addins from Reflector.CodeMetrics + Reflector.Graph
    • XmlSerializer viewer (see your object as if it was "XmlSerialized") *locks the assembly*
    • Control viewer (see your winforms control) *locks the assembly*
    • PropertyGrid viewer (see your object as if it was in a PropertyGrid control) *locks the assembly*
    • COM loader (compiles assembly for COM type libraries)  *New*
    • Reflector.Emit language
    • Type TreeMap (supports coverage)
    • IronPython console

 

 

 

posted on Tuesday, November 01, 2005 2:03:14 PM UTC  #    Comments [1]

Ever wondered what would it take to generate your code on the fly using Reflector.Emit....
The meaning of the following screenshot is left as a quiz...

posted on Tuesday, November 01, 2005 11:11:27 AM UTC  #    Comments [2]
 Saturday, October 29, 2005

I've update Reflector.Framework, Reflector.CodeMetrics and Reflector.Graph against the latest version of Reflector.

  • They all require .Net 2.0
  • Compiled against Reflector 4.1.85.0
  • Reflector.Framework requires IronPython assemblies!!!!
posted on Sunday, October 30, 2005 4:03:37 AM UTC  #    Comments [0]

It's alive!

posted on Sunday, October 30, 2005 4:00:01 AM UTC  #    Comments [0]
 Wednesday, October 26, 2005

A while ago I hooked up Haibo's ILReader to make a rustic Debugger Visualizer for DynamicMethod (Lightweight Code Generation). Haibo did the hard work and made it very interresting tool for debugging those strange .net citizens.

I'm a big fan of custom debugger visualizers. Not only they are very useful but they also very well documented and easily testable! There are already many implementations of those for datasets, xml, etc... but usually it worth investing a little time to build your own customized visualizers.

For example, if your data organized as a tree, you might be continuously drilling down this tree. You could consider a visializer that would render the tree to a certain depth. This will save you a *lot* of "expand node" time.

 

posted on Wednesday, October 26, 2005 2:00:48 PM UTC  #    Comments [0]
 Sunday, September 04, 2005

I have uploaded a updated build of the Reflector addins for Reflector. 4.1.80.0.

This build is done against Whidbey (.Net 2.0) Beta2!

posted on Monday, September 05, 2005 5:01:46 AM UTC  #    Comments [3]