BDD on Steroids

Wednesday, March 11, 2009 1:40:59 PM (Mountain Standard Time, UTC-07:00)

In the last couple of weeks I had a chance to sprinkle some of JP's syntactic sugar, all over my projects. It's amazing how much more concise my units test have become. I've had a couple of issues where I was mocking out the behavior of some Win Forms controls, but for the most part it's been an awesome experience!

I just wanted to take a moment to say Thank you JP! I am enjoying using your BDD (on steroids) extensions. If you haven't already you need to check it out here. NOW!

Maaad, maaaad props Mr. JP!

 

   10     public class behaves_like_save_changes_view_bound_to_presenter : concerns_for<SaveChangesView>

   11     {

   12         context c = () => { presenter = an<ISaveChangesPresenter>(); };

   13 

   14         because b = () => sut.attach_to(presenter);

   15 

   16         static protected ISaveChangesPresenter presenter;

   17     }

   18 

   19     public class when_the_save_button_is_clicked : behaves_like_save_changes_view_bound_to_presenter

   20     {

   21         it should_forward_the_call_to_the_presenter = () => presenter.was_told_to(x => x.save());

   22 

   23         because b = () => EventTrigger.trigger_event<Events.ControlEvents>(

   24                               x => x.OnClick(new EventArgs()),

   25                               sut.ux_save_button

   26                               );

   27     }

   28 

   29     public class when_the_cancel_button_is_clicked : behaves_like_save_changes_view_bound_to_presenter

   30     {

   31         it should_forward_the_call_to_the_presenter = () => presenter.was_told_to(x => x.cancel());

   32 

   33         because b = () => EventTrigger.trigger_event<Events.ControlEvents>(

   34                               x => x.OnClick(new EventArgs()),

   35                               sut.ux_cancel_button

   36                               );

   37     }

   38 

   39     public class when_the_do_not_save_button_is_clicked : behaves_like_save_changes_view_bound_to_presenter

   40     {

   41         it should_forward_the_call_to_the_presenter = () => presenter.was_told_to(x => x.dont_save());

   42 

   43         because b = () => EventTrigger.trigger_event<Events.ControlEvents>(

   44                               x => x.OnClick(new EventArgs()),

   45                               sut.ux_do_not_save_button

   46                               );

   47     }

 

Update: I posted the wrong link up top. here's the latest link.

#

Keepin' it real with SVN

Friday, February 01, 2008 4:05:09 PM (Mountain Standard Time, UTC-07:00)

Earlier this month I read...

Pragmatic Version Control: Using Subversion (The Pragmatic Starter Kit Series)(2nd Edition)
by Mike Mason

Read more about this title...

If you're an svn or tortoise junkie I recommend that you check out this book. Although most of the information provided in this book can probably be found in the SVN documentation, I much preferred reading this top to bottom. This book walks you through several different project scenarios and shows you how to effectively use svn as your source control system.

The appendices also offers a lot of very helpful information on setup and third party tools. Some must have tools for svn are:

  • TortoiseSVN
  • VisualSVN
  • SVN.exe

I love that visual svn takes care of things like moving files, add and deleting it really simplifies the check in process. Tortoise is a great windows explorer shell that provides a wicked abstraction over the svn shell.

Since reading the book I've found that I'm using tortoise less for checkin's and updates. Here's a couple of simple commands to get you started:

Update:

svnUp

Commit (check in):

svnci

#

NAnt: Start Using the C# 3.0 Compiler Without Visual Studio 2008

Wednesday, December 05, 2007 9:25:46 PM (Mountain Standard Time, UTC-07:00)

One of the benefits about building with NAnt is being able to flip the switch and start targeting a different compiler, without having to switch to the latest version of Visual Studio. Although, you wont get the intellisense provided by studio for new features.

So today we flipped the switch on a project at work, from targeting the C# 2.0 compiler to the C# 3.0 compiler. We haven't started leveraging any of the new functionality available in the new compiler but at least we know we can start.

So to flip the switch you'll need to update your "nant.exe.config" file to include the .NET Framework version 3.5. Remember with this release we got a new version of the .NET Framework assemblies, a new C# 3.0 compiler but we're still running it all in the 2.0 version of the CLR.

The new xml element to add to your "Nant.exe.config" file looks something like this:

                <framework
                    name="net-3.5"
                    family="net"
                    version="3.5"
                    description="Microsoft .NET Framework 3.5"
                    runtimeengine=""
                    sdkdirectory="${path::combine(sdkInstallRoot, 'bin')}"
                    frameworkdirectory="${path::combine(installRoot, 'v3.5')}"
                    frameworkassemblydirectory="${path::combine(installRoot, 'v2.0.50727')}"
                    clrversion="2.0.50727">
                    <task-assemblies>
                        <!-- include .NET specific assemblies -->
                        <include name="tasks/net/*.dll" />
                        <!-- include .NET 2.0 specific assemblies -->
                        <include name="tasks/net/2.0/**/*.dll" />
                        <!-- include Microsoft.NET specific task assembly -->
                        <include name="NAnt.MSNetTasks.dll" />
                        <!-- include Microsoft.NET specific test assembly -->
                        <include name="NAnt.MSNet.Tests.dll" />
                    </task-assemblies>
                    <project>
                        <readregistry
                            property="installRoot"
                            key="SOFTWARE\Microsoft\.NETFramework\InstallRoot"
                            hive="LocalMachine" />
                        <readregistry
                            property="sdkInstallRoot"
                            key="SOFTWARE\Microsoft\.NETFramework\sdkInstallRootv2.0"
                            hive="LocalMachine"
                            failonerror="false" />
                    </project>
                    <tasks>
                        <task name="csc">
                            <attribute name="exename">csc</attribute>
                            <attribute name="supportsnowarnlist">true</attribute>
                            <attribute name="supportswarnaserrorlist">true</attribute>
                            <attribute name="supportskeycontainer">true</attribute>
                            <attribute name="supportskeyfile">true</attribute>
                            <attribute name="supportsplatform">true</attribute>
                            <attribute name="supportslangversion">true</attribute>
                        </task>
                        <task name="vbc">
                            <attribute name="exename">vbc</attribute>
                            <attribute name="supportsdocgeneration">true</attribute>
                            <attribute name="supportsnostdlib">true</attribute>
                            <attribute name="supportsnowarnlist">true</attribute>
                            <attribute name="supportskeycontainer">true</attribute>
                            <attribute name="supportskeyfile">true</attribute>
                            <attribute name="supportsplatform">true</attribute>
                            <attribute name="supportswarnaserrorlist">true</attribute>
                        </task>
                        <task name="jsc">
                            <attribute name="exename">jsc</attribute>
                            <attribute name="supportsplatform">true</attribute>
                        </task>
                        <task name="vjc">
                            <attribute name="exename">vjc</attribute>
                            <attribute name="supportsnowarnlist">true</attribute>
                            <attribute name="supportskeycontainer">true</attribute>
                            <attribute name="supportskeyfile">true</attribute>
                        </task>
                        <task name="resgen">
                            <attribute name="exename">resgen</attribute>
                            <attribute name="supportsassemblyreferences">true</attribute>
                            <attribute name="supportsexternalfilereferences">true</attribute>
                        </task>
                        <task name="al">
                            <attribute name="exename">al</attribute>
                        </task>
                        <task name="delay-sign">
                            <attribute name="exename">sn</attribute>
                        </task>
                        <task name="license">
                            <attribute name="exename">lc</attribute>
                            <attribute name="supportsassemblyreferences">true</attribute>
                        </task>
                        <task name="ilasm">
                            <attribute name="exename">ilasm</attribute>
                        </task>
                        <task name="ildasm">
                            <attribute name="exename">ildasm</attribute>
                        </task>
                    </tasks>
                </framework>                 

To flip the switch you can either override the nant setting in your build file ...

<property name="nant.settings.currentframework" value="net-3.5" />

or you can change the default target framework in the "nant.exe.config" file.

<platform name="win32" default="net-3.5">

I can't steal the credit for figuring this out, I spent about an hour adding the new framework version to the Nant.exe.config file but the thing I missed was that there is no new version of the CLR. So Thank you Mr. Palermo!

Source Nant.exe.config

#

Wintellect's Power Collections Library

Monday, September 24, 2007 7:24:22 PM (Mountain Standard Time, UTC-07:00)

Are you bored of the standard collections available in the .NET Framework? Are you looking to get more out of your collections? Well....

Ok enough of the info-mercial, so I came across the Wintellect's Power Collections Library and wanted to share. This library offers a bunch of different data structures that are not available in an out of the box .NET Framework install.

It's got collections like:

  • Deque
  • MultiDictionary
  • Bag
  • OrderedBag
  • OrderedDictionary
  • Set
  • OrderedSet
  • OrderedMultiDictionary

The library is now up on codeplex and the source is all available. Take a look... i just started digging, and I've got some ideas for my own home brewed collection.

#

NAnt: Running Your Unit Tests

Friday, June 08, 2007 8:12:54 AM (Mountain Standard Time, UTC-07:00)

There's a lot of cool things that you can do with nAnt, like running your tests against NUnit or another unit testing framework. Let's pretend we already have a target called "compile" that will compile our application into an assembly into the build folder. See...

We can create a new target that will compile our test project(s) into a single test assembly and save it to our build folder, where we saved our application assembly. The following target will recurse through a subdirectory called "test" and compile all files with a .cs extension into our test assembly.

    <target name="test.compile" depends="compile">
        <csc target="library" output="build\${project::get-name()}.Test.dll" debug="${debug}">
            <sources>
                <include name="src\test\**\*.cs" />
                <exclude name="src\test\**\AssemblyInfo.cs" />
            </sources>
            
            <references>
                <include name="build\${project::get-name()}.dll" />
                <include name="tools\nunit\bin\nunit.framework.dll" />
                <include name="tools\rhinomocks\Rhino.Mocks.dll" />
            </references>
        </csc>
    </target>    

The references element allows us to include other assemblies that our test assembly depends on. In the above case I'm using NUnit, and RhinoMocks. Our test assembly also depends on the application assembly, after all that is what our tests are supposed to be testing.

So far we have compiled our application assembly and test assembly, and saved them to the same directory called build. Now lets create a target that will run our unit tests using the nunit-console.exe.

    <target name="test" depends="test.compile">

        <copy todir="build" flatten="true">
            <fileset basedir="tools">
                <include name="**\Rhino.Mocks.dll" />
            </fileset>
        </copy>

        <copy todir="build" flatten="true">
            <fileset basedir="tools\nunit\bin">
                <include name="*.dll" />
            </fileset>
        </copy>
        
        <exec basedir="tools\nunit\bin" 
            useruntimeengine="true" 
            workingdir="build" 
            program="nunit-console.exe" 
            commandline="${project::get-name()}.Test.dll /xml=${project::get-name()}.Test-Result.xml" />        
        
    </target>

The above target will copy over the Rhino.Mocks.dll, and NUnit dlls into our build folder. Then execute "nunit-console.exe" from the command line and pass it in the path to our test assembly, and will tell it what to name the xml file that nunit will spit out with the test results.

As you can see the test results are also shown to the console window. As you can see, I have run 8 tests, with 3 failures. (Looks like I've made a breaking change!)

#

nAnt: Compiling Your Applications

Friday, June 08, 2007 7:11:51 AM (Mountain Standard Time, UTC-07:00)

I've been spending some time trying to learn how to create builds using nAnt. You can use a special nAnt element to compile your .cs source files against the C# compiler.

    <target name="compile">
        <csc target="library" output="build\${project::get-name()}.dll" debug="${debug}">
            <sources>
                <include name="src\app\**\*.cs" />
                <exclude name="src\app\**\AssemblyInfo.cs" />
            </sources>                        
        </csc>
    </target>

The above target will compile all .cs files into a single assembly called <PROJECT_NAME>.dll. ( You specify your project name in the name attribute of the project element.)

<project name="LogMyTime">

The compile target will recurse through all the files in a subdirectory called "src" and compile all the files with a .cs extension into the final assembly, excluding the AssemblyInfo.cs file (If you have multiple projects, each one will most likely have a different "AssemblyInfo.cs" file containing assembly info for that project.). The target will try to save the assembly to a folder called "build".

Before compiling you should ensure that the build folder exists. To do this you could create another nAnt target that creates the build directory. Here is an example.

    <target name="init">
        <mkdir dir="build" />
    </target>

We could now create a dependency between the compile target and the init target so that, the init target always runs before attempting to compile by adding the "depends" attribute.

    <target name="compile" depends="init"> ... </target>

Now we can run our nAnt task from the commandline:

The output will tell us what nAnt targets ran and if there were any compilation warnings or errors:

Related Resources:

#

Content Management Systems: Umbraco 2.1.6

Friday, June 01, 2007 10:41:06 AM (Mountain Standard Time, UTC-07:00)

Umbraco is open source .NET content management system. It's current release is version 2.1.6, and seems to look like if offers a better UI then some of the other content management systems. The demo shows you how to create pages and users and some other things.

You can check out the demos at http://umbraco.org/frontpage/demos.aspx

Umbraco needs .NET Framework 1.1, Microsoft SQL Server ( I used 2005 ) or MSDE. The target browsers are claimed to be:

  • Internet Explorer 5.5,
  • Firefox (no version specified, but I found it sucked on 2.0.0.4)
  • Safari

I was kind of impressed by the demo's but let down when I actually tried to install this guy and use it. When I tried to pull the source from the SVN server I received errors about to many locks and gave up. Maybe you'll have better luck: svn://svn.umbraco.org/var/lib/svn/Umbraco2.1

The Installation

I had a lot of problems installing Umbraco, I copied the full project after I downloaded it from here.

I created a folder in C:\inetpub\wwwroot\ called umbraco21 (C:\inetpub\wwwroot\umbraco21). I fired up inetmgr.exe, and changed the properties for this site to create an application. And specified ASP.NET version to 1.1.4322

 

 

 

 

 

I then opened up the web.config in notepad++, the documentation says that you have to change 4 keys in the config file:

  • umbracoReservedPaths
  • umbracoContentXML
  • umbracoStorageDirectory
  • umbracoPath

The original looks like:

<add key="umbracoReservedPaths" value="/umbraco/,/install"/>
<add key="umbracoContentXML" value="/data/umbraco.xml"/>
<add key="umbracoStorageDirectory" value="/data"/>
<add key="umbracoPath" value="/umbraco" />

I found the documentation didn't really describe what these really mean or how they were supposed to be used so I tried a few different variations before finally getting the installation wizard to start up properly. (Note: the forward slash at the start was very important!)

    <add key="umbracoReservedUrls" value=",/umbracoTextGen.aspx,"/>
    <add key="umbracoReservedPaths" value="/umbraco21/umbraco/,/umbraco21/install"/>
    <add key="umbracoContentXML" value="/umbraco21/data/umbraco.xml"/>
    <add key="umbracoStorageDirectory" value="/umbraco21/data"/>
    <add key="umbracoPath" value="/umbraco21/umbraco" />

Next, I then fired up firefox and punched in http://localhost/umbraco21 into my browser, and got the Umbraco 2.1 Configuration Wizard!

 

 

 

When I pressed Next, I found that I was staring at "Directory Listing Denied" (take a look at the URI in the address bar!)

It appears that the install wizard tried to add a query string to the page and post back to itself, I had not specified a default document in my IIS configuration. So I went back and set "Default.aspx" as the default document!

The database setup was moderately simple, as long as the connection string is set properly in the web.config file.

At the end of the wizard I was told to add the following key to the web.config and to delete in the /install folder.

<add key="umbracoConfigurationDone" value="211"/>

During the process you're asked to set a password for a default user, but it never told you what the default username was. I had to dig it out of the database but it's "umbraco".

Once I logged in I found that nothing seemed to render properly in Firefox.

 

If you start to dig into the source you'll see that it uses IFrames, and Frames in different sections of the Administrator section. Because of this I basically could not do anything in FireFox 2.0. So I tried Internet Explorer 7.0, when I did I kept receiving JavaScript warnings and saw the same thing. I could do anything with Umbraco... I suppose you could say my experience with Umbraco is a non-experience.

#

What's Open about Open ID?

Wednesday, May 09, 2007 6:49:10 PM (Mountain Standard Time, UTC-07:00)

Open ID is definitely an interesting concept. The basic premise is that you maintain a single Identity that you can use to verify who you are to different sites that support Open ID.

You identify yourself with a unique URI. To log in to a Open ID site you enter your Uri. The website should then re-direct you to your Open ID provider, where you provide your log in credentials to verify that it's actually you trying to claim to use this Open ID.

Here's a good screen cast on the topic Open ID screen cast.

There are several libraries written in different languages available to developers for use on their Open ID affiliate sites. Found here... The one I tinkered with was Nerdbanks Open ID web control, which references JanRains Open ID library. The control was very simple to use and start using... the full source is available and released under a LGPL license.

I ran the Nerdbanks assembly against FxCop and found several things that could be improved on. Personally, I would want to fix a lot of these issues before using this myself, but it's nice to have a starting point to begin working with. The Nerdbanks assembly also contains a lot of extra code all bundled into a single assembly, again my personal preference would be to probably break out the "tools" from the "web controls" into separate assembly's.

Open ID seems like a pretty cool concept and it's nice to have libraries available to start with... anyways this just skims the surface of what Open ID is... but hopefully it's a good primer!

#