Wednesday, July 14, 2004

An installation tutorial "for Dummies" is available at http://www.dotnetwiki.org/Default.aspx?tabid=55

posted on Thursday, July 15, 2004 3:09:00 AM UTC  #    Comments [0]

With all those addins poping out on the blog, maintaining the files was becoming quite messy. In order to simplify a lot of things, I have upgraded my old www.dotnetwiki.org web site to DotNetNuke 2.1.2 with the following components:

  • Issue tracker for the Reflector Addins, please use it instead of sending the bugs to Lutz,
  • Forums, what thread can be watched by emails and news feed,
  • Download section, where the files are stored and link remain permanent

See you seen on www.dotnetwiki.org .

posted on Thursday, July 15, 2004 2:30:00 AM UTC  #    Comments [2]

After this afternoon crash of the blog, it is time to get back to some fun activities...and today code coverage is the program. I will be using NCover (gotdotnet) but other tools could apply also.

There is one thing that strikes me with code coverage: there is almost no efficient tool to visualize coverage (I'm leaving aside Team System for now). Usually the framework that compute the coverage already have a big job to do with computing it, and the visualization is somehow "left to the user". It seems to me that this part of the job is not trivial also because of the quantity of information that has to be processed: an assembly can have hundreds of types, thousands of methods. This motivates the introduction of some new...  Reflector Addins for code coverage visualization.

Coverage in a TreeMap

A natural way of visualizing coverage is to use the TreeMap that I was previously using for the Type TreeMap addin.With some minor modifications, we have the following result: the figure shows the test coverage of NCollection project (green is fullly covered, red is not covered).

NCover and Reflector

The most difficult/annoying part of this work was to create the bridge between NCover and Reflector, because of slight difference in the way name, assembly and modules are named.

posted on Wednesday, July 14, 2004 11:02:00 AM UTC  #    Comments [10]
 Tuesday, July 13, 2004

Following the PropertyGrid and the XmlSerialization addin, this addin displays the control classes inside Reflector.

The addin is desesperately simple: if the selected class inherits from System.Windows.Forms, the addin instanciate it and adds it to the window.

posted on Wednesday, July 14, 2004 3:39:00 AM UTC  #    Comments [0]

This is a preview of a new Reflector addin to well let you search for Program Patterns in your assemblies. The addin is mainly an adaptation to .Net of the article from Santany Paul and Atul Prakash, "A Framework for Source Code Search using Program Patterns".

What are Program Patterns ?

In their article, the authors use a pattern language to specify high-level patterns for making queries on the source code. It smells like regular expression but it operates on statements and expression instead of strings. The basic pieces of the pattern languages are:

  • # describes any expression,
  • @ describes any statement,
  • more to come here...

More specific patterns, like if, while, throw,  are also defined. In fact, for each interface of the Reflector.CodeModel namespace, a corresponding pattern class is needed. Let's illustrate this with a simple example of query: Find all occurence of a if followed by a throw statement.
In the original paper notation, the pattern is defined as follows:

if (#) throw #;

Of course this will have to change a bit for C#.

C# implementation

In my implementaiton, the IPattern interface defines a Program Pattern:

public interface IPattern
{
    bool Match(Object target);
}

The interface is intentionaly simple to enable great extensibility. This interface is then specialized for IStatement, IExpression, IBlockStatement, etc.. For example, the pattern to match a throw statement will be implemented as follows:

public class ThrowExceptionStatementPattern : StatementPattern
{
    // pattern for the expression that is throwed. Pats is a helper class
    private ExpressionPattern expression = Pats.AnyExpression;
    ...

    public override bool Match(IStatement statement)
    {
        // trying to cast statement to IThrowExceptionStatement
        IThrowExceptionStatement th = statement as IThrowExceptionStatement;
        // did not cast, no match
        if (th==null)
            return false;
        // expression did not match, no match
        if (!this.Expression.Match(th.Expression))
            return false;
        // we have a match!
        return true;
    }
}

To ease up things, a helper class containing static methods (Pats) takes care of creating those objects.

Implementing the example

Implementing the example is now just a matter of putting the pieces together. We need a pattern for the if, one for the throw and a pattern that will recurse in all the statements:

// provided by Reflector
IMethodDeclaration visitedMethod = ...
// if pattern
ConditionStatementPattern ifthen = Pats.If();
// setting the Then pattern
// StatementInBlock says the pattern should be in the IBlockStatement
// Pats.Throw() returns a ThrowExceptionStatementPattern 
ifthen.Then = Pats.StatementInBlock(Pats.Throw());
// a pattern that will recurse all the statements
RecursiveStatementPattern rec = Pats.Recursive(ifthen);

// launching the seach
rec.Match(visitedMethod.Body);

Testing the example

The above pattern has been applied to the following class where 2 methods match the pattern, and 2 do not match it:

public class CodeMatchingTest
{
    public void If(bool arg)
    {
        Console.WriteLine("This method has a if");
        if (arg)
            Console.WriteLine("arg is true");
        else
            Console.WriteLine("arg is false");
    }
    public void Throw()
    {
        throw new Exception();
    }
    public void IfThrow(bool arg)
    {
        if (arg)
            throw new Exception();
    }
    public void IfThrowHiddenInsideWhileLoop(bool arg)
    {
        int i = 0;
        while(i<10)
        {
            if (i>5)
                throw new Exception();
            Console.WriteLine(i.ToString());
        }
    }
}

And the result in Reflector is displayed below. As expected, IfThrow and IfThrowHiddenInsideWhileLoop have matched the pattern.

posted on Wednesday, July 14, 2004 3:38:00 AM UTC  #    Comments [3]

Jamie Cansdale (NUnitAddin) has recently started to use the SSCLI tests to verify the output of Reflector.

"The Shared Source Common Language Infrastructure 1.0  is a compressed archive of the source code to a working implementation of the ECMA CLI and the ECMA C# language specification. This implementation builds and runs on Windows XP, the FreeBSD operating system, and Mac OS X 10.2." says the description. If you download this file, you will see that it ships with tons of tests that are used to test the CLI implementation. Each one of the test classes is to be compiled into a console application that returns 0 if successful, 1 otherwise.... Could we harness those test using a test framework ?

First try: all tests in one assembly

Since each fixture is designed to be compiled as a console, we just need to look for classes with a static Main method, load them and execute the main method. This is rather optimistic because it assumes that you can compile all the tests into a single assembly and then load, which is not true because a lot of classes are duplicated and clashes. Anyway, I managed to load some of them "just for fun":

Second try: dynamic compliation

Jamie was ahead of me and had already the solution. He designed a bunch of helper classes that dynamically load the files, compile, and execute them. This combined to a CodeSmith template that would generate a huge fixture (one case per file), he had this harnessed for NUnit. Jamie is kind of "shy" (sorry Jamie) and does not want to write about the amazing stuff he is doing with testing. So if you want to know how he managed to wrap up SSCLI tests in NUnit in a record time, give him a shout ! 

That's all for today, I'll have to modify MbUnit to integrate Jamies work... 

posted on Wednesday, July 14, 2004 3:37:00 AM UTC  #    Comments [0]

How do you handle the inclusion of examples into your C# documentation ? If you've been asking yourself this question, here's a quick tip for automatic example inclusion.

Let's start with an example. Consider the following dummy class MyClass:

public class MyClass
{
 ...
}

We hapilly write anexample for the MyClass class in a separate xml file (say Doc.xml):

<doc>
  <examples>
    <example name="example1">
       public class MyLibrary
       {
           public static Main(string[] args)
           {
               MyClass mc = new MyClass();
           }
       }
    </example>
  </examples>
</doc>

Now the way Visual Studio suggests uses to include the example is to use the include tag with a XPath expression similar to this:

//< include file='Doc.xml' path='example[@name="example1"]' />

This is fine but it can break easily.Moreover, assuming that you have a lots of examples, you may miss some example that could be integrated into the documentation.

A much better solution is to use the power of XPath. In fact, what we want to include is all the examples that involve the MyClass class, which in XPath translates to: contains(descendant-or-self::*,'MyClass'):

/// <include 
///     file='MyLibrary.Doc.xml' 
///     path='//example[contains(descendant-or-self::*,"MyClass")]'
/// />

That's it. Instead of using name=... you stop worrying and let XPath find the proper examples for you.

posted on Wednesday, July 14, 2004 3:36:00 AM UTC  #    Comments [0]

I was waiting for this moment for a long time: we have matrix algebra package for .NET!

dnAnalytics home page: http://www.dnanalytics.net/

posted on Wednesday, July 14, 2004 3:36:00 AM UTC  #    Comments [2]

From Benjamin blog;

BOF001: James Newkirk on Integrating Unit Testing into the Software Development Lifecycle.

James Newkirk leading the Unit Testing BoFJames Newkirk lead a Birds of a Feather session on Test Driven Development.  The room was packed to the rafters, showing that Unit Testing is starting to reach a critical mass.  Here are my notes on the discussion from the session which covered how to write tests, how to use tests against legacy systems, how to test against the database and many other topics.

Should we write test code against interfaces or something more abstract than the implementation?
James mentioned that MbUnit is a tool that allows you to test against an interface.  The question was whether you should create interfaces that enable tests to be written against them in case further implementations were created in future.  James' attitude was that this might result in wasted work ('you aint gonna need it') since you may not need it, or may not need it now.  Instead, abstract things out when you need them - don't create an interface just to test it.

James also said that an interface is not a good example of the contract of what is being done - it is the name of the method with input and outputs, but does not reflect how the method reacts to the input. James writes tests that show the real interaction between someone that calls the code and what it produces.

I must say I'm disapointed to have missed TechEd Amsterdam and this session (It's only a couple hour from Brussels). Aaaaargghhh!

posted on Wednesday, July 14, 2004 3:35:00 AM UTC  #    Comments [0]

TestFu is a collection of framework that can help the tester to build data generator, state machines, grammars, etc... TestFu v0.1 contains:

I have decided to separate the Production Grammar Framework and the Database Populator Framework from MbUnit so that any user (not only MbUnit users) benefit from those two frameworks.

Download TestFu

posted on Wednesday, July 14, 2004 3:35:00 AM UTC  #    Comments [2]

Download addins

The following post gives a list and a quick description of the Reflector addins I have written. The addins are organized by assemblies.

Configuration Reflector for the addins

All addins are targeted for .Net v1.0.5 and Reflector is compiled agains 1.0.3. This means that you must add/modify the Reflector.exe.config file accordingly to the one contained in the zip file. Please do not send bug reports to Lutz but directly to me or through the MbUnit issue tracking system.

Reflector.Graph.dll
Addins

Comments
This addin uses QuickGraph and Refly in the background.

Reflector.Graph.Drawing.dll
Addins

Comments
Might still be a little buggy. Intensive on system resources.

Reflector.Goodies.dll
Addins

Comments
Be aware that this addins actually loads the assembly with Reflector and it will lock those assemblies.

Reflector.TreeMap.dll
Addins

Comments
This addin depends on the TreeMap control from Microsoft Research. Make sure you put TreeMapControl.dll and TreeMapGenerator.dll (from Microsoft TreeMap) in the directory of Reflector.

Reflector.Rules.dll (experimental)
Addins

Comments
Does not do much, still under experimentation.

posted on Wednesday, July 14, 2004 3:34:00 AM UTC  #    Comments [18]

Download addins

The following post gives a list and a quick description of the Reflector addins I have written. The addins are organized by assemblies.

Configuration Reflector for the addins

All addins are targeted for .Net v1.0.5 and Reflector is compiled agains 1.0.3. This means that you must add/modify the Reflector.exe.config file accordingly to the one contained in the zip file. Please do not send bug reports to Lutz but directly to me or through the MbUnit issue tracking system.

Reflector.Graph.dll
Addins

Comments
This addin uses QuickGraph and Refly in the background.

Reflector.Graph.Drawing.dll
Addins

Comments
Might still be a little buggy. Intensive on system resources.

Reflector.Goodies.dll
Addins

Comments
Be aware that this addins actually loads the assembly with Reflector and it will lock those assemblies.

Reflector.TreeMap.dll
Addins

Comments
This addin depends on the TreeMap control from Microsoft Research. Make sure you put TreeMapControl.dll and TreeMapGenerator.dll (from Microsoft TreeMap) in the directory of Reflector.

Reflector.Rules.dll (experimental)
Addins

Comments
Does not do much, still under experimentation.

posted on Wednesday, July 14, 2004 3:34:00 AM UTC  #    Comments [18]

I have added abunch of classes for database testing  in the TestFu project (Download Now ):

 

·         SqlAdministrator: backup, restore, create or drop  databases, and also some methods on tables, constraints,etc...

·         SqlExplorer: extracts the schema of database to a DataSet

·         SqlFixture: a mini data abstraction layer "TestFixture" oriented

 

Let's see them in action...

 

SqlAdministrator

 

·         Backup  database to a file:

·         Restore a database from a file:

·         Drop a database:

·         Drop a table:

·         Drop a constraint:

·         etc...

 

using System;
using TestFu.Data;

public class Demo
{
    public static void Main(string[] args)
    {
        DbAdministrator admin = new SqlAdministrator("...");    
        
        // backup Northwind
        admin.Backup("Northwind",SqlBackupDevice.Disk,@"c:\Backups\Northwind.bkp");
        
        // drop Northwind
        admin.Drop("Northwind");
        
        // restore Northwind
        admin.Restore("Northwind",SqlBackupDevice.Disk,@"c:\Backups\Northwind.bkp");
    }
}

SqlFixture

The DbFixture (SqlFixture for MsSQL server) can be used as a base class for the fixtures involving database testing:

[TestFixture]
public class DatabaseTest : SqlFixture
{
    public DatabaseTest()
    :base("Data Source=testserver;...","MyTestDatabase")
    {}
    
    [SetUp]
    public void SetUp()
    {
        this.Open();
        this.BeginTransaction();
    }
    
    [Test]
    public void Selec()
    {
        IDbCollection cmd = this.Connection.CreateCommand("select * from anytable",this.Transaction);
        ...
    }
    
    [TearDown]
    public void TearDown()
    {
        this.Close();
    }
}
posted on Wednesday, July 14, 2004 3:34:00 AM UTC  #    Comments [3]

I have added abunch of classes for database testing  in the TestFu project (Download Now ):

 

·         SqlAdministrator: backup, restore, create or drop  databases, and also some methods on tables, constraints,etc...

·         SqlExplorer: extracts the schema of database to a DataSet

·         SqlFixture: a mini data abstraction layer "TestFixture" oriented

 

Let's see them in action...

 

SqlAdministrator

 

·         Backup  database to a file:

·         Restore a database from a file:

·         Drop a database:

·         Drop a table:

·         Drop a constraint:

·         etc...

 

using System;
using TestFu.Data;

public class Demo
{
    public static void Main(string[] args)
    {
        DbAdministrator admin = new SqlAdministrator("...");    
        
        // backup Northwind
        admin.Backup("Northwind",SqlBackupDevice.Disk,@"c:\Backups\Northwind.bkp");
        
        // drop Northwind
        admin.Drop("Northwind");
        
        // restore Northwind
        admin.Restore("Northwind",SqlBackupDevice.Disk,@"c:\Backups\Northwind.bkp");
    }
}

SqlFixture

The DbFixture (SqlFixture for MsSQL server) can be used as a base class for the fixtures involving database testing:

[TestFixture]
public class DatabaseTest : SqlFixture
{
    public DatabaseTest()
    :base("Data Source=testserver;...","MyTestDatabase")
    {}
    
    [SetUp]
    public void SetUp()
    {
        this.Open();
        this.BeginTransaction();
    }
    
    [Test]
    public void Selec()
    {
        IDbCollection cmd = this.Connection.CreateCommand("select * from anytable",this.Transaction);
        ...
    }
    
    [TearDown]
    public void TearDown()
    {
        this.Close();
    }
}
posted on Wednesday, July 14, 2004 3:34:00 AM UTC  #    Comments [4]

Roy Osherove's (ISerializable) has come up with a new RollBackAttribute to automatically rollback transaction for each test case. This is pretty neat because you can write things like:

[TestFixture]
public class Test
{
   [Test,RollBack]
   public void SomeTestWithDatabase()
   {
       // all what we do here
       // is automatically rolled back
   }
}

MbUnit implementation

Roy was kind enough to send me the source code of this attribute so I integrated it into MbUnit. Roy plans to make an article about the details of the implementations so I will not discuss it further. The interresting point is that the integration was done in less than 5 minutes, thanks to the extensibility of MbUnit.

Here is a part of the implementation of the attribute (I have stripped out the Service related code):

[AttributeUsage(AttributeTargets.Method,AllowMultiple=false,Inherited=true)] 
public sealed class RollBackAttribute : DecoratorPatternAttribute
{
    public override IRunInvoker GetInvoker(IRunInvoker invoker)
    {
        return new RollbackRunInvoker(invoker);
    }

    private class RollbackRunInvoker : DecoratorRunInvoker
    {
        public RollbackRunInvoker(IRunInvoker invoker)
        :base(invoker){}


        public override object Execute(object o, System.Collections.IList args)
        {
            EnterServicedDomain();
            try
            {
                Object result = this.Invoker.Execute(o,args);
                return result;
            }
            finally
            {
                AbortRunningTransaction();
                LeaveServicedDomain();
            }
        }
    
        #region Service stuff
        private void AbortRunningTransaction()
        {...}

        private void LeaveServicedDomain()
        {...}

        private void EnterServicedDomain()
        {...}
        #endregion
    }
}

There are a few things to say in the above implementation:

  • DecoratorPatternAttribute is an abstract attribute for test case decorators, such as ExpectedException, Ignore, etc... The purpose of the attribute is to return a IRunInvoker implementation that acts as a wrapper around another IRunInvoker,
  • This filter effect can be seen in the RollbackRunInvoker.Execute method, where the actual Test case method is called inside a Try/Catch statement. This guard is used to roll back transactions.
posted on Wednesday, July 14, 2004 3:33:00 AM UTC  #    Comments [0]

While working on my DotNetNuke upgrade, I screwed up my blog database. I've recovered a backup from June 24, there I will find in Google cache I hope...

posted on Wednesday, July 14, 2004 3:32:00 AM UTC  #    Comments [0]
 Thursday, June 24, 2004

Little intro

Reflector is a (great) decompiler. The most obvious use of it is to load an assembly and recreate source code out of the IL it contains. The assembly itself was built from source code, so we have a mini "cycle of life". In a perfect world, the decompiled code and the orginal source code would be exactly the same (at least in the same language). So we can represent this cycle by the figure below.

Now,  let's introduce a new actor in this ecosystem. We want the decompiler to producec CodeDom source code that can be used to generate the original source code as shown in the figure below: we want to produce a CodeDom template that will generate that type.

Sample example

Let's illustrate all this with an example. Consider the following User class:

public class User
{
    private string name = "Marc";

    public String Name
    {
        get
        {
            return this.name;
        }
        set
        {
            this.name=value;
        }
    } 
    public override string ToString()
    {
        return this.name;
    }
}

We compile User and now, we want Reflector to generate a class that uses CodeDom (indeed Refly) to generate back the User class. This is the tricky part. I need to use Refly to generate code that uses Refly, so that would be building a code generator generator. The template for the User class will look like this:

public class UserTemplate 
{
    private Refly.CodeDom.ClassDeclaration _type;
    private Refly.CodeDom.FieldDeclaration _nameField;
    private Refly.CodeDom.PropertyDeclaration _nameProperty;
    private Refly.CodeDom.MethodDeclaration _toStringMethod;

    public UserTemplate(Refly.CodeDom.NamespaceDeclaration ns) 
    {
        // add User class to generator
        this._type = ns.AddClass("User");
        this.Declare();
    }

    public virtual void Declare() 
    {
        this.DeclareFields();
        this.DeclareMethods();
        this.DeclareProperties();
        this.DeclareEvents();
        this.DeclareInnerClasses();
    }

    public virtual void DeclareFields() 
    {
        // adding name field
        this._nameField = this._type.AddField(typeof(String), "name");
    }

    public virtual void DeclareMethods() 
    {
        this._toStringMethod = this._type.AddMethod("ToString");
        this.PopulateToStringMethod(this._toStringMethod);
    }

    public virtual void DeclareProperties() 
    {
        this._nameProperty = this._type.AddProperty(typeof(String), "Name");
        this.PopulateNameProperty(this._nameProperty);
    }
    ...
}

(The above template is still missing a big part: the generation of the statements and the expression) Now that we have a Refly ClassDeclaration, we can feed it to the CodeGenerator class:

NamespaceDeclaration ns = new NamespaceDeclaration("RoundRobin");
UserTemplate template = new UserTemplate(ns);
CodeGenerator gen =new CodeGenerator();
gen.GenerateCode("./Output",ns);

And the result of the execution of this program will be this piece of code:

namespace RoundRobin 
{
    using System;
    public class User 
    {
        private string _name;
        public virtual string Name 
        {
        }
        public virtual void ToString() 
        {
        }
    }
}

Not so bad for a start, we have gotten our User class back but there are still some big "holes" in it....

posted on Thursday, June 24, 2004 10:40:00 PM UTC  #    Comments [0]

Following the idea of displaying a class in a PropertyGrid, we can also take a look at how it serializes using the XmlSerializer (see if it serializes at all!). The task looks trivial at first sight:

  1. create an instance of the object,
  2. create a XmlSerializer that can serialize it,
  3. write the object to a XmlRichTextWriter to get colors :)

Of course, there's a gotcha here. You will likely get empty xml files all of the time because usually, the default constructor creates "empty" object. So what we want is to dress the object before serializing them. This is done in a variety of ways depending on the property type:

  • the property/field is a string, int, etc... you can set easily a value to it,
  • the property/field is tagged with XmlArrayAttribute,
    • the property/field is an array: get all the XmlArrayItem attribute, create an array and fill it with instance of those items,
    • the property/field is a collection: get the "Add(Object)" method, add instances of the items.

Of course, this is rather simplistic and may fail on forgotten situations.

Screenshot: ReportAssembly contains collection properties (namespaces, fixtures),  which would appear empty if not "dressed".

posted on Thursday, June 24, 2004 9:23:00 PM UTC  #    Comments [2]

In this blog, I'll show how you can a implement a control to colorizes XML in a simple and effective way. I needed to display XML in a control, however, displaying it in "black and white" made it very depressing.  I have 3 objectives: simplicity, simplicity and simplicity.You can think of this as a traditional Microsoft interview enigma. So let's enumerate what we need and what we want (and what we want to avoid). 

What we want: colors!
What we don't want: manipulate the XML Dom, in other words: let's be lazy.
What we have: it's time to dig into the FCL classes and see what we could use 

  • RichTextBox: this control seems to be the perfect match for our "coloring" purposes,
  • XmlTextWriter: this class is a forward only, non-cached Xml writer. This class provides a rich set of method that output elements, attributes, etc...

Implementation

At this point, you must have an idea of the way we are going to acheive colors... the tools are here, we just need to inject the color at the right spot (like in a toothpaste, the color lines come right at the end). In fact, we have 3 tasks to acheive:

1) RichTextBoxWriter:

A TextWriter-derived class that writes to a RichTextBox. The writer keeps a current Color and Font that is apply to each chunk of string appended. This task is pretty straightforward, basically you need to overload 3 Write methods.

public class RichTextBoxWriter : TextWriter
{
    private RichTextBox textBox;
    private Color currentColor=Color.Black;
    private Font currentFont = new Font("Tahoma",8.25f);

    ...

    public override void Write(char value)
    {
        this.TextBox.SelectedText = value.ToString(this.FormatProvider);
    }
    public override void Write(char[] buffer)
    {
        if (buffer!=null)
        {
            this.TextBox.SelectedText = new String(buffer).ToString(this.FormatProvider);
            // if buffer = '\n\r', font and color is reseted
            this.TextBox.SelectionColor=this.CurrentColor;
            this.TextBox.SelectionFont=this.CurrentFont;
        }
    }
    public override void Write(string value)
    {
        this.TextBox.SelectedText = value.ToString(this.FormatProvider);
    }
}

Wow, that was short. Now to point 2.

2) XmlRichTextWriter:

This class, which inherits from XmlTextWriter, injects color on some "startegic" methods. In order to store the colors, we create XmlRichTextBox, which inherits from RichTextBox and contains a rich set of customizable colors and fonts for the Xml rendering. This class will be used by the XmlRichTextBoxWriter:

public class XmlRichTextBoxWriter : XmlTextWriter
{
    private XmlRichTextBox theme; // contains all the colors and fonts

    public XmlRichTextBoxWriter(XmlRichTextBox tb)
    :base(tb.Writer)
    {
        this.theme=tb;
    }

    public override void WriteStartDocument()
    {
        // setting color of the selected text
        this.theme.Writer.CurrentColor = this.theme.StartColor;
        this.theme.Writer.CurrentFont = this.theme.StartFont;
        // output data
        base.WriteStartDocument();
    }
    ...
}

4) XmlRichTextBox:

Now, that we have our writer, we just need to wire them up in the XmlRichTextBox and we are done.

And finally, the result: on the left, a XmlRichTextBox, on the left, how it looks like in the PropertyGrid. We have colooors!

Download it now....

posted on Thursday, June 24, 2004 11:08:00 AM UTC  #    Comments [6]
 Wednesday, June 23, 2004

Joel Pobar speaks about the new features of Reflection.

ReflectionOnly seems to be very interresting...

posted on Wednesday, June 23, 2004 11:14:00 PM UTC  #    Comments [1]
 Tuesday, June 22, 2004

Ever wondered how you classes you look like in a PropertyGrid control, now it is possible directly from Reflector with my upcoming Reflector Addin:

Ps: As always, a big thanks to Jamie Cansdale (NUnitAddIn) for his help on this one.

posted on Wednesday, June 23, 2004 6:19:00 AM UTC  #    Comments [5]

XsdTidy is a refactoring tool to overcomes some silly limitations of the exceptional Xsd.exe  tool provided with the .NET framework. More specifically, XsdTidy addresses the following problems:

  • Name normalization: if your XSD schema is using lower case names or more generally non ".NET" normalized names, you will end up with types that will make the FxCop spit out hundreds of infractions,
  • Fields not properties: xsd.exe creates fields and does not "hide" them in properties which is bad OO design.
  • Fixed Array Sizes: xsd.exe handles multiple elements by creating an array. There is no problem when you are loading the data, but unfortunately this is not convenient if you want to populate a document since arrays do not support Add or Remove. XsdTidy provides strongly-typed collection that support Add, Remove, etc...
  • Default Constructor: Xsd.exe does not care about providing a default constructor that initializes the fields with the proper values. If the object structure is getting big, it becomes very difficult to properly initializes fields,
  • Serializable: Xsd.exe does not tag classes with serializable

Note that XsdTidy uses Refly for building the source code and is also maintained by Marcus Mac Innes.

What does XsdTidy fix ?

Name conversion

The .NET standards define specific naming convention for all types of data: arguments should be camel case, function names capitalized, etc... This is really helpful to keep the framework consistent. Tools like FxCop help us stay on the "normalized" side.

This problem is tackled the dumb way: given a dictionary of "common" words, the class NameConformer tries to split a name in separate words, after that it renders it to the needed convention. Of couse, this feature can be disabled.

FixedArraySize and "Multi" Strongly-Typed Collections

Arrays are replaced by inner strongly-type collections which are much more flexible to use. Moreover, array fields are created by default using their default constructor. This is to economize you the hassle of creating a collection before using it. If an array can support multiple object type, the generate collection will be "multi" strongly typed:

public class TestClass
{
    [XmlArray("values")]
    [XmlArrayItem("car",typeof(Car));
    [XmlArrayItem("car",typeof(Bike));
    public Object[] values;
}

becomes

public class TestClass
{
    private ValueCollection values = new ValueCollection();

    [XmlArray("values")]
    [XmlArrayItem("car",typeof(Car));
    [XmlArrayItem("car",typeof(Bike));
    public ValueCollection Values
    {
        get { return this.values;}
    }

    public class ValueCollection : CollectionBase
    {
        public void AddCar(Car car)
        {
            this.List.Add(car);
        }
        public void AddBike(Bike bike)
        {
            this.List.Add(bike);
        }
        ... // the implementation of the collection
    }
}

Properties

Fields are hidden in properties, which is more convenient to use. Moreover, collection fields do not have set property according to FxCop rule.

public class testclass
{
    [XmlAttribute("values")]
    public String values;
}

becomes:

public class TestClass
{
    private String values;

    [XmlAttribute("values")]
    public String Values
    {
        get
        {
            return this.values;
        }
        set
        {
            this.values = value;
        }
    }
}

Serializable

The output classes are tagged with the Serializable attribute to make them usable using Remoting.

XsdTidy history

I have first started to build XsdTidy using System.Reflection.Emit. It was a titanic job and very error prone. The difficulty of using Emit pushed me to use CodeDom which was also heavy to use. So finally, Refly was designed and XsdTidy became much easier to impement.

Download:

Download XsdTidy and Refly at http://blog.dotnetwiki.org/downloads/Refly.zip

Screenshot

posted on Tuesday, June 22, 2004 11:33:00 PM UTC  #    Comments [6]
 Monday, June 21, 2004

Reflector.Graph was becoming messy because of external dependencies so I decided to remove some parts of it (TypeGraph, TreeMap) in order to keep funcitonal.

Reflector version: tested for 4.0.6.0 and 4.0.7.0

Installation procedure:

  • Download the Reflector.Graph Binaries  and unzip it in the Reflector directory (it may be unzipped in a Release directory, copy the file aside to Reflector)
  • In Reflector, Tools -> Addin... -> Add -> Reflector.Graph.dll
  • That's it!

In this release, you do not need to create a Reflector.exe.config.

What's in Reflector.Graph:

  • MethodRank (Assembly),
  • TypeRank (Assembly),
  • Unit Test Generator (Type),
  • Mock Geneator (Type),
  • IL Graph (Method),
  • AssemblyGraph (Tools)

What's not in Reflector.Graph:

  • TypeGraph will be release separately because it needs to be compiled agains .Net v1.1
  • TypeTreeMap will be released separately because it has a dependency on the Microsoft TreeMap

Bugs and suggestions:

 

posted on Monday, June 21, 2004 10:56:00 PM UTC  #    Comments [2]

The Database Populator Framework  follows the same idea of DbMonster (or at least, was partially inspired from it). The purpose of the framework is to provide a flexible (and smart) set of random data generators to populate your database.

Why ?

If you plan to do database testing, the solution are not much: use transaction, create/kill database after each unit test, clean up after each test or use the new technique using Enterprise Services.

The objective of DPF is not to test the database but provide "food" for your unit test. By generating data randomly (satisfying the constraint), you do not need to clean up and you will avoid test clashing on each other. Moreover, you can also use the DPF to test your database under load.

Random but no dumb

In order to generate data for testing database, you need to take into accounts the constraints on the columns and between the tables. By providing a DataSet representing you database, the framework analyses it and create a set of generators. The data generated satisfies all the constraint. Of course, each row generator can be customized for your own needs, but in general, the information contained in the dataset is enough.

The ideas

The idea are rather simple:

  • Each DataColumn has its corresponding IDataGenerator instance,
  • Each DataTable has its corresponding ITablePopulator instance,
  • Each UniqueConstraint has its corresponding IUniqueValidator instance which takes care of ensuring the all unique constraint are validated,
  • Each ForeignKeyConstraint has its corresponding IForeignKeyConstraint instance which will fetch valid foreign key values

The generation of a new row is made inside a ITablePopulator as follows:

  1. Create a row,
  2. Call each IDataGenerator and fill the row,
  3. For each foreign key, get relevant values,
  4. Verify unique constraints, if violated go to 1,
  5. return row

The first bits

The first bits of the framework is located in the MbUnit.Framework.Data namespace. Althout the framework still needs work, the first example is running and is quite promising.

I have built a simple database containing User - Order - Product - OrderProduct:

this.dataSet=new DataSet();

DataTable users=dataSet.Tables.Add("Users");
DataColumn userID = users.Columns.Add("UserID",typeof(int));
DataColumn userName=Users.Columns.Add("UserName",typeof(string));
DataColumn userName.AllowDBNull=false;

DataTable orders=dataSet.Tables.Add("Orders");
DataColumn orderID=orders.Columns.Add("OrderID",typeof(int));
DataColumn orderDate = orders.Columns.Add("OrderDate",typeof(DateTime));
DataColumn oUserID = orders.Columns.Add("UserID",typeof(int));

DataTable products=dataSet.Tables.Add("Products");
DataColumn productID=products.Columns.Add("ProductID",typeof(int));
DataColumn productName = products.Columns.Add("ProductName",typeof(string));
DataColumn productPrice = products.Columns.Add("ProductPrice",typeof(decimal));

DataTable orderProducts=dataSet.Tables.Add("OrderProducts");
DataColumn opOrderID=orderProducts.Columns.Add("OrderID",typeof(int));
DataColumn opProductID=orderProducts.Columns.Add("ProductID",typeof(int));
DataColumn quantity=orderProducts.Columns.Add("Quantity",typeof(int));
// pks
users.Constraints.Add("PK_Users",userID,true);
orders.Constraints.Add("PK_Orders",orderID,true);
products.Constraints.Add("PK_Products",productID,true);
orderProducts.Constraints.Add("PK_OrderProducts",
new DataColumn[]{ opOrderID, opProductID}
,true);
// fks
orders.Constraints.Add("FK_Orders_Users",userID,oUserID);
orderProducts.Constraints.Add("FK_OrderProducts_Orders",orderID,opOrderID);
orderProducts.Constraints.Add("FK_OrderProducts_Products",productID,opProductID);

This database is easily populated using the DPF:

// creating populator
IDatabasePopulator pop=new DatabasePopulator();
// anaylising internal structure
this.pop.Populate(this.db.DataSet);

After that, you can customize the behavior of every data generator. Once this is done, you are ready to "feed" your database:

//getting the users table populator
ITablePopulator userPop = pop.Tables[users];
// adding new row
users.Rows.Add( userPop.Generate() );
posted on Monday, June 21, 2004 1:03:00 PM UTC  #    Comments [8]

Refly is the library that I have developped to make CodeDom usable. (See my CodeProject article here, or the classic Hello World example). Note that Refly comes with XsdTidy, an application that "pretify" the output of the Xml.exe tool.

Download Now

 

posted on Monday, June 21, 2004 12:17:00 PM UTC  #    Comments [3]
 Sunday, June 20, 2004

If you are doing database testing, you should read this great post by Roy:

Simplified Database Unit testing using Enterprise Services

posted on Sunday, June 20, 2004 10:31:00 PM UTC  #    Comments [1]
 Friday, June 18, 2004

The Production Grammar Framework is finally fully integrated into MbUnit as a new Fixture (GrammarFixture).

An example:

I'm currently building a new framework for generating "relevant" data for randomly populating database (similar ideas to DbMonster). As you may have noticed, I don't practive dogfood much so I decided to start now. I'm writing the test code along with the framework (of course, I'm testing myself here so it's a bit twisted). Anyway, I had to test the following collection:

public interface IDataGeneratorCollection : ICollection
{
    IDataGenerator this[DataColumn column]{get;}
    IDataGenerator this[String columnName]{get;}
    void Add(IDataGenerator dataGenerator);
    void Remove(IDataGenerator dataGenerator);
    void Remove(DataColumn column);
    void Remove(String columnName);
    bool Contains(IDataGenerator dataGenerator);
    bool Contains(DataColumn column);
    bool Contains(String columnName);
    void Clear();
}

At first, I decided to write a TypeFixture and produce a bunch of unit tests for that, but I quickly got bored, so I turned myself to production grammars which are much more fun. The grammar for this collection can be summarized as follows (see the stack example):

-- dg is a IDataGenerator
add := Add(dg)
remove := Remove(dg)
contains := Contains(dg)

guardedRemove := guard(InvalidOperatoinException, remove)

empty := add,guardedRemove,contains
nonEmpty := add,remove,contains

startRule := if(collection.IsEmpty) { empty } else { nonEmpty }

MbUnit Attributes

Now that we have built a grammar we need to tell MbUnit to load the grammar it feed it with seeds:  GrammarFixtureAttribute describes a production grammar fixture, GrammarAttribute describes a method that return a IGrammar instance, SeedAttribute returns an object that is feeded into the production constructor.

[GrammarFixture]
public class DataGeneratorCollectionGrammar : Grammar
{
    ... // rules creation etc...

    [Grammar]
    public Grammar This()
    {
        return this;
    }
    [Seed]
    public int Seed10()
    {
        return 10;
    }
    [Seed]
    public int Seed20()
    {
        return 20;
    }
    [Seed]
    public int Seed50()
    {
        return 50;
    }
    [Seed]
    public int Seed200()
    {
        return 200;
    }
}

Screenshot: the grammar test case + the console output

posted on Saturday, June 19, 2004 5:51:00 AM UTC  #    Comments [3]

Aaron has written a "Hello World" sample using Refly.

Refly is a helper wrapper around the CodeDom namespace that makes it much less "noisy". Refly is used in the Unit Test Generator Addin. If you are using CodeDom regularly, maybe you should have a look at this.

posted on Saturday, June 19, 2004 3:14:00 AM UTC  #    Comments [2]

This is a quick recap on the available features of MbUnit 2.15.1:

Fixtures:

Fixture type define how MbUnit is going to explore a class and build the test cases.

Fixture can be organized in a number of was. Automatically, they are organized by Namespace and Authors, but you can also tag a http://blog.dotnetwiki.org/archive/2004/05/29/277.aspx, and put them into multiple categories

Decorators:

Decorators are used on the "method" level to modify the behavior of a given test. Decorators can be chained to combine their effect.

Assertion classes

Aside from the classic Assert class, there are a number of specialized assertion classes:

 

posted on Friday, June 18, 2004 8:39:00 PM UTC  #    Comments [5]
 Thursday, June 17, 2004

I'm preparing a little Reflector Addin to be able to load and execute MbUnit fixtures inside Reflector. Since the fixture tree contains all the functionalities, it was just a matter of injecting it into Reflector.

Screenshot:

The source code is so short that I'm also publishing (note that I'm using the helper classes described here)

using System;
using System.Windows.Forms;
using Reflector.CodeModel;
using MbUnit.Forms;
namespace Reflector.Graph.Faulty
{ 
    // Reflector package
    public class MbUnitPackage : BasePackage
    {
        [ReflectorWindow("MbUnit")]
        [ReflectorCommandBar(CommandBarTarget.Assembly)]
        private MbUnitWindow MbUnit=new MbUnitWindow(); 
    }

    // Tree View
    public class MbUnitWindow : ReflectorTreeView
    {
        private ReflectorServices services =null;
        public MbUnitWindow()
        {
            this.Dock =DockStyle.Fill;
        }
        // needed to get reflector current element
        public ReflectorServices Services
        {
            get
            {
                return this.services;
            }
            set
            {
                if (this.services!=null)
                {
                    this.services.AssemblyBrowser.ActiveItemChanged-=new EventHandler(this.activeItem_Changed); 
                }
                this.services=value;
                if (this.services!=null)
                {
                    this.services.AssemblyBrowser.ActiveItemChanged+=new EventHandler(this.activeItem_Changed); 
                }
            }
        }
        private void activeItem_Changed(Object sender, EventArgs args)
        {
            this.RemoveAssemblies();
            IAssembly assembly = this.Services.ActiveAssembly;
            if (assembly!=null)
                this.Translate();
        }

        // populate tree with current assembly
        public void Translate()
        {
            IAssembly assembly =this.Services.ActiveAssembly;
            if (assembly==null)
                return;
            this.RemoveAssemblies();
            this.AddAssembly(assembly.Location);
            this.ThreadedPopulateTree();
        }
    }
}
posted on Friday, June 18, 2004 1:06:00 AM UTC  #    Comments [3]

MbUnit 2.1.5.1 Beta is ready for download.  See latest release page on this blog for the download links

Issues, feature requests, and other bugs: please do not post them on the blog. You have two options (please it's easier to track things)

We have a menu!

posted on Thursday, June 17, 2004 7:53:00 AM UTC  #    Comments [17]
 Wednesday, June 16, 2004

This is a preview of a new Addin in the next Reflector.Graph release: Type Tree Map.

A TreeMap is special 2D visualzation of a tree. Since, Reflector provides a tree (Assembly -> Module -> Namespace -> Type -> Members), I wondered if it was possible to visualize with a TreeMap. In .Net, there are 2 controls available that can render treemaps:

I decided to use the later for creating the addin.

Screenshot

Note (1): The nodes represent each part of the type tree from assembly to the class members. Each node is clickable and brings the tree focus to the clicked element.
Note (2): Look at the treemap, and image the nodes are you Namespace/TestFixture/TestCase hierachy. Failed test in red, successfull test in green. Just imagine, that would be the ultimate progress bar for MbUnit!
Note (3): Thanks to Jamie (NUnitAddin) for the idea sharing on this.

posted on Thursday, June 17, 2004 2:52:00 AM UTC  #    Comments [2]

Jamie Cansdale, NUnitAddIn man, pointed out to me that I was cited (very briefly) on .Net rocks.  Here's the summary

John and Barry talk with us about Test-Driven Development, Unit Testing, and other aspects of Extreme Programming that are being used today. We had given lip service to unit testing in past shows, but John and Barry were able to explain the benefits as well as the how-to of test-driven development

http://www.franklins.net/dotnetrocks/, number 67, at 1:27 or so. This deserves a couple beers for me.

posted on Thursday, June 17, 2004 2:36:00 AM UTC  #    Comments [7]
 Tuesday, June 15, 2004

This entry is a little tutorial on how to write your own Reflector Addin. For the past weeks, I have been playing a lot with those and Lutz Roeder was backing me up on MSN for quick questions, so it's my time to return him the favor and write a tutorial about it. So let's get started.A