Chris McKelt

Remembering Thoughts

 

Recent comments

Archive

Authors

Categories

None


Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2012

PSAKE- Gallio–SpecFlow–XUnit–on the build server

This is a quick post to show how to get PowerShell with PSAKE to run Specflow acceptance tests on the build server using Gallio.

The folder with our build scripts looks like this

 

image

 

The environments folder contains all of the configuration files for each environment

 

image

 

Build server process

 

The build/check-in process is now as follows.

1. Developer checks in.

2. Build server detects changes – cleans everything and then pulls down latest SVN code

3. Cruise control builds code in release mode –> If compile fails –> build fail

4. Unit tests run in place à if any test fails –> build fail

5. On success a new folder with the VERSION number is created      --- this is our artefacts

6. This build is then deployed to the integration server and the Acceptance tests are run – Results are output to a folder

7. If the Acceptance tests fails -> build fail

8. On Success the build is packaged for deployment (config files modified for environment)

 

Cruise control originally calls default.ps1 passing in the environment.

<powershell>
                <scriptsDirectory>C:\CCWorking\Phoenix\CodeBase\Build\BuildScripts</scriptsDirectory><!--Scrips folder-->
                <script>default.ps1</script>
                <buildArgs>-environment:integration</buildArgs><!-- Project working folder -workingDir C:\project1\working-->
                <executable>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</executable>
                <buildTimeoutSeconds>10000</buildTimeoutSeconds>
                <description>Phoenix Build</description>
        </powershell>

 

This calls build.ps1

PSAKE tasks include

 

Task default -depends PrintInformation, CleanEnvironment, Clean, SetupEnvironment, MakeBuild, BuildDatabase, DeployIntegrationBuild, IntegrationTest, DeployBuild, UpdateConfigFiles

 

To run the acceptance tests using Gallio

The following Powershell function is used:@

Usage for Gallio tests:

Task Test-System -Description "Runs the system tests via Gallio" {
Test-Gallio $proj $configuration $platform $dll "system" "Test.System"
# Test-Gallio ".\src\Test.Unit\Test.Unit.csproj" Release x64 ".\src\Test.Unit\bin\Release\x64\Test.Unit.dll" "unit"
}
}
#>
function Test-Gallio($proj, $configuration, $platform, $dll, $report_name, $report_dir, $namespace_filter){
   Write-Host "GALLIO TEST proj --  $proj"
   Write-Host "GALLIO TEST configuration --  $configuration"
   Write-Host "GALLIO TEST platform --  $platform"
   Write-Host "GALLIO TEST dll --  $dll"
   Write-Host "GALLIO TEST report_name --  $report_name"
   Write-Host "GALLIO TEST namespace_filter --  $namespace_filter"
 

    if ( (Get-PSSnapin -Name Gallio -ErrorAction SilentlyContinue) -eq $null )
    {
         Add-PSSnapin Gallio
    }
  $result = Run-Gallio $dll -filter Namespace:/$namespace_filter/ -ReportTypes text,html,xml -ReportDirectory $report_dir  -ReportNameFormat $report_name-test-report  #-NoProgress -NoEchoResults
  get-content "$report_dir\$report_name-test-report.txt" | Write-Host
  Write-Host $result.ResultsSummary
  if ($result.Statistics.FailedCount -gt 0) {
    Write-Warning "Some unit tests have failed."
    $Error = $result.ResultsSummary
    exit $result.ResultCode
  }
 
  Remove-PSSnapin Gallio
 
}

 

From an acceptance test entered into SpecFlow as follows:

image

On checkin the build will run and output the result of this test in a report called AcceptanceTests-test-report.html 

image


image


Posted by chris on Sunday, November 13, 2011 11:40 PM
Permalink | Comments (0) | Post RSSRSS comment feed

NANT CruiseControl NUnit - How to get unit tests running and displaying on the build server

 
<target name="webtest" haltonfailure="false" failonerror="true">
    <echo message="Running unit tests"/>
        <echo message="${project.local.folder}"/>
        <property name="test_dll_folder" value="${project.local.folder}\McKelt.Tests\bin\Debug\"/>
        <exec failonerror="true" program="${nunit-console.exe}" workingdir="${project.local.folder}" verbose="true" append="true" commandline="${test_dll_folder}McKelt.Tests.dll /xml=${test_dll_folder}TestResults.xml /output=${test_dll_folder}TestOutput.txt /err=${test_dll_folder}TestErrorOutput.txt">
    </exec>
    <echo message="-- TEST COMPLETE -- "/>
</target>

 

Follow these instructions -- http://confluence.public.thoughtworks.org/display/CCNETCOMM/Improved+MSBuild+Integration

 

In the following file – c:\program files\CruiseControl.Net\Server\CCNet.config

 

<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
<workingDirectory>C:\CCWorking\ChallengerOnlineForms\CodeBase\</workingDirectory>
<projectFile>ChallengerOnlineForms.sln</projectFile>
<buildArgs> /noconsolelogger /p:Configuration=Debug /v:quiet </buildArgs>
<targets>Rebuild</targets>
<timeout>120</timeout>
<logger>c:\Program Files\CruiseControl.NET\server\Rodemeyer.MsBuildToCCNet.dll</logger>
</msbuild>
</tasks>
<publishers>
<merge>
<files>
<file>C:\CCWorking\ChallengerOnlineForms\CodeBase\Challenger.Web.Application.Tests\bin\Debug\testresults.xml</file>
<file>C:\CCWorking\ChallengerOnlineForms\CodeBase\Challenger.Service.Implementations.Tests\bin\Debug\testresults.xml</file>
<file>C:\CCWorking\ChallengerOnlineForms\CodeBase\Tests\AcceptanceTests\bin\Debug\TestResults.xml</file>
<file>C:\CCWorking\ChallengerOnlineForms\CodeBase\Challenger.Web.Application.Tests\bin\Debug\*Output.txt</file>
<file>C:\CCWorking\ChallengerOnlineForms\CodeBase\Challenger.Service.Implementations.Tests\bin\Debug\*Output.txt</file>
<file>C:\CCWorking\ChallengerOnlineForms\CodeBase\Tests\AcceptanceTests\bin\Debug\*Output.txt</file>
</files>
</merge>
<xmllogger/>
</publishers>
 
In your dashboard.config
 
 
<?xml version="1.0" encoding="utf-8"?>
<dashboard>
<remoteServices>
<servers>
<!-- Update this list to include all the servers you want to connect to. NB - each server name must be unique -->
<server name="local" url="tcp://localhost:21234/CruiseManager.rem" allowForceBuild="true" allowStartStopBuild="true" backwardsCompatible="false" />
</servers>
</remoteServices>
<plugins>
<farmPlugins>
<farmReportFarmPlugin />
<cctrayDownloadPlugin />
<administrationPlugin password="" />
</farmPlugins>
<serverPlugins>
<serverReportServerPlugin />
</serverPlugins>
<projectPlugins>
<projectReportProjectPlugin />
<viewProjectStatusPlugin />
<latestBuildReportProjectPlugin />
<viewAllBuildsProjectPlugin />
</projectPlugins>
<buildPlugins>
<buildReportBuildPlugin>
<xslFileNames>
<xslFile>xsl\header.xsl</xslFile>
<xslFile>xsl\msbuild2ccnet.xsl</xslFile>
<xslFile>xsl\modifications.xsl</xslFile>
<xslFile>xsl\unittests.xsl</xslFile>
</xslFileNames>
</buildReportBuildPlugin>
<buildLogBuildPlugin />
<xslReportBuildPlugin description="NAnt Output" actionName="NAntOutputBuildReport" xslFileName="xsl\NAnt.xsl"></xslReportBuildPlugin>
<xslReportBuildPlugin description="NAnt Timings" actionName="NAntTimingsBuildReport" xslFileName="xsl\NAntTiming.xsl"></xslReportBuildPlugin>
<xslReportBuildPlugin description="NUnit Details" actionName="NUnitDetailsBuildReport" xslFileName="xsl\tests.xsl"></xslReportBuildPlugin>
<xslReportBuildPlugin description="NUnit Timings" actionName="NUnitTimingsBuildReport" xslFileName="xsl\timing.xsl"></xslReportBuildPlugin>
</buildPlugins>
<securityPlugins>
<simpleSecurity />
</securityPlugins>
</plugins>
</dashboard>


Posted by chris on Wednesday, May 18, 2011 3:53 AM
Permalink | Comments (0) | Post RSSRSS comment feed

SpecFlow Acceptance Tests

Using SpecFlow heres how I solved the following problem

PROBLEM : SALES TAXES

Basic sales tax is applicable at a rate of 10% on all goods, except books, food, and medical products that are exempt.
Import duty is an additional sales tax applicable on all imported goods at a rate of 5%, with no exemptions.

When I purchase items I receive a receipt which lists the name of all the items and their price (including tax), finishing with the total cost of the items, and the total amounts of sales taxes paid. 
The rounding rules for sales tax are that for a tax rate of n%, a shelf price of p contains (np/100 rounded up to the nearest 0.05) amount of sales tax.

Write an application that prints out the receipt details for these shopping baskets...

INPUT:

Input 1:
1 book at 12.49
1 music CD at 14.99
1 chocolate bar at 0.85

Input 2:
1 imported box of chocolates at 10.00
1 imported bottle of perfume at 47.50

Input 3:
1 imported bottle of perfume at 27.99
1 bottle of perfume at 18.99
1 packet of headache pills at 9.75
1 box of imported chocolates at 11.25

OUTPUT

Output 1:
1 book : 12.49
1 music CD: 16.49
1 chocolate bar: 0.85
Sales Taxes: 1.50
Total: 29.83

Output 2:
1 imported box of chocolates: 10.50
1 imported bottle of perfume: 54.65
Sales Taxes: 7.65
Total: 65.15

Output 3:
1 imported bottle of perfume: 32.19
1 bottle of perfume: 20.89
1 packet of headache pills: 9.75
1 imported box of chocolates: 11.85
Sales Taxes: 6.70
Total: 74.68
==========

 

A Quick overview of the application

The solution is a console application that parses given files (i.e. Input1.txt) and creates an output formatted as requested in the problem.

It looks like this:

 

image_thumb1

 

[Projects]

SalesTaxApplication    -- Console Application that imports text files ie input1.txt -- these a copied to the bin folder at compile time 
                                   -- but you just just pass in a file path McKelt.SalesTaxApplication [/s filename]
                                   -- McKelt.SalesTaxApplication /s input3.txt
Domain                       -- contains core model & other shared classes
Acceptance Tests        -- uses SpecFlow for BDD acceptance tests - was hoping to have reusable steps but didnt get round to this sorry -- http://stackoverflow.com/questions/5228030/specflow-re-usable-step-definitions
Unit Tests                    -- used MBUnit with Resharper for testing TDD style

[Design]

I choose to use a state pattern for managing the order object.
As the order transitions to completed I choose to use chained commands to execute tasks
So once the order is complete the following commands are kicked off:
        -- CalculateSalesTaxCommand
        -- CalculateImportedSalesTaxCommand
        -- CalculateTotalCostWithoutTaxCommand
 
Probably YAGNI but this is just a demo

[Other]

NuGet used to get the following packages.
Args            -- Command Line processor
Castle.Core        
Castle.Windsor
Rhino Mocks
MBUnit
SpecFlow
SoftwareApproach.TestingExtensions -- VisualStudioTestingExtensions.1.1.0.0

SystemWrapper used to wrap all IO calls for ease of testing -- http://systemwrapper.codeplex.com/

 

The order can be seen below – its contains a CurrentState object that manages he order process:

public class Order
  {
      public Order()
      {
          OrderItems = new List<OrderItem>();
          this.CurrentState = new NotCreated(this);
      }

      public virtual int Id { get; set; }
      public virtual string Name { get; set; }
      public IList<OrderItem> OrderItems { get; set; }
      public virtual IOrderState CurrentState { get; set; }
      public Decimal TotalTax { get; set; }
      public Decimal TotalCostWithoutTax { get; set; }
      public decimal TotalOrderCost
      {
          get { return TotalTax + TotalCostWithoutTax; }
      }

      public virtual void AddProduct(Product product)
      {
          AddProduct(product, 1);
      }

      public virtual void AddProduct(Product product, int quantity)
      {
          var oi = new OrderItem { Product = product, Quantity = quantity };

          if (OrderItems.Any(a=>a.Product.Id == product.Id))
          {
              int originalQuantity = OrderItems.Single(a => a.Product.Id == product.Id).Quantity;
              OrderItems.Single(a => a.Product.Id == product.Id).Quantity = (originalQuantity + quantity);
          }
          else
          {
              OrderItems.Add(oi);   
          }
      }

      public virtual void Become(IOrderState orderState)
      {
          orderState.BecomeCommands.Execute();
          CurrentState.Become(orderState);
      }
  }

 

The states the order can be in are:

  • NotCreated
  • Created
  • Completed

As the order moves to its next stage a chain of commands is kicked off.

  • NotCreated  –  NoCommand (does nothing)
  • Created       –  NoCommand (does nothing)
  • Completed   -- CalculateSalesTaxCommand, CalculateImportedSalesTaxCommand, CalculateTotalCostWithoutTaxCommand –> run in order these do the calculations

In starting development, I started with the BDD Acceptance test – this runs red so then I develop unit tests which after red/green/refactor I rerun the acceptance test which goes green

Here is the Spec flow feature file for the order creation

Feature: Customer Order Creation
    To create an order
    As a user
    I enter the customers details
    And the Order is created

@CustomerOrderCreation
Scenario: Create an order
    Given a Customer
    When the Customers name is Test Customer
    When I create an order
    Then a new order is created

 

Ands here the BDD code file

[Binding]
   public class CustomerOrderCreationFlow
   {
       protected Customer customer;
       protected IOrderService orderService;
       protected Order order;

       [Given(@"a Customer")]
       public void GivenACustomer()
       {
           customer = new Customer();
       }

       [When(@"I create an order")]
       public void WhenICreateAnOrder()
       {
           orderService = new OrderService();
           order = orderService.Create(customer);
       }

       [When(@"the Customers name is Test Customer")]
       public void WhenTheCustomersNameIsTestCustomer()
       {
           customer.FirstName = "Test";
           customer.LastName = "Customer";
       }

       [Then(@"a new order is created")]
       public void ThenANewOrderIsCreated()
       {
           order.ShouldNotBeNull("Order is null");
           order.CurrentState.ShouldBeOfType(typeof (Created));
       }

Adding orders

 

Feature: Manage an order
    As a user
    I want to change the customer order
    I add a product
    Then an order item is added to the order

@AddSingleProduct
Scenario: Add single product to an order
    Given A Customer with Name Joe Smith
    Given an order
    When I add a product
    Then an order item should be added


@AddMultipleProducts
Scenario: Add Multiple Products to an Order
    Given A Customer with Name Joe Smith
    Given an order
    When I add the following products
      | Id        | Name            | ProductType     | Imported    | Price    |
      | 1        | A-Book           | Book            | True        | 33.45    |
      | 2        | CD               | Medical         | false       | 15.00    |
      | 3        | Chocolates       | Food            | true        | 5.00    |
      | 4        | Gym Socks        | Other           | false       | 3.00    |
    Then an order item should be added

And the code:

 

[Binding]
    public class OrderInProgressFlow 
    {
        private Order order;
        private IOrderService orderService;
        private Customer customer;
        private Product product;
        private IList<Product> tableProducts;


        [Given(@"an order")]
        public void GivenAnOrder()
        {
            var stubOrder = new Order()
            {
                Name = string.Format("Order for {0} {1}", customer.FirstName, customer.LastName),
            };
            stubOrder.CurrentState = new Created(stubOrder);
            orderService = MockRepository.GenerateMock<IOrderService>();
            orderService.Stub(a => a.Create(customer)).Return(stubOrder);
            order = orderService.Create(customer);
        }

        [Given(@"A Customer with Name Joe Smith")]
        public void GivenACustomerWithNameJoeSmith()
        {
            customer = new Customer {FirstName = "Joe", LastName = "Smith"};
        }


        [When(@"I add a product")]
        public void WhenIAddAProduct()
        {
            product = new ProductBuilder()
                .WithId(1)
                .WithPrice(5)
                .WithName("AAA")
                .WithProductType(ProductType.Other)
                .Build();

            order.AddProduct(product);
        }


        [Then(@"an order item should be added")]
        public void ThenAnOrderItemShouldBeAdded()
        {
            if (product != null)
            {
                order.OrderItems.Any(a => a.Product.Id == product.Id).ShouldBeTrue();    
            }
            else
            {
                tableProducts.Each(a => order.OrderItems.Any(b => b.Product.Id == a.Id).ShouldBeTrue());
            }
            
        }

        [When(@"I add the following products")]
        public void WhenIAddTheFollowingProducts(Table table)
        {
            tableProducts = new List<Product>();
            SpecFlowHelpers.ConvertTableToProductList(table);
            tableProducts.Each(order.AddProduct);
        }

And finally the big one – Order Completion

 

Feature: Sales tax should be 10% for all goods except books food and medical products
    When an order is completed
    As a user
    I want to calculate the sales taxes

@CalculateSalesTax1
Scenario: Calculate Sales Tax
    Given A Customer with Name Joe Smith
    Given an order that is in progress
    When I add the following products to the inprogress order
      | Id        | Name            | ProductType    | Imported     | Price    |
      | 1        | A-Book        | Book            | false        | 12.49    |
      | 2        | Music CD        | Other             | false        | 14.99    |
      | 3        | Chocolates    | Food             | false        | 00.85    |
    When the order is completed
    Then the sales tax should be 1.50 
    And the total should be 29.83

@CalculateSalesTax2
Scenario: Calculate Sales Tax for imported items
    Given A Customer with Name Joe Smith
    Given an order that is in progress
    When I add the following imported products to the inprogress order
      | Id        | Name            | ProductType    | Imported     | Price    |
      | 1        | Chocolates    | Food            | true        | 10.00    |
      | 2        | Perfume CD    | Other             | true        | 47.50    |
    When the order is completed
    Then the sales tax should be 7.65 



@CalculateSalesTax3
Scenario: Calculate Sales Tax for both types of items
Given A Customer with Name Joe Smith
Given an order that is in progress
When I add the following imported products to the inprogress order
    | Id           | Name            | ProductType    | Imported    | Price    |
    | 1            | perfume         | Other          | true        | 27.99    |
    | 2            | perfume         | Other          | false       | 18.99    |
    | 3            | pills           | Medical        | false       | 9.75     |
    | 4            | chocolate       | Food           | true        | 11.25    |
When the order is completed
Then the sales tax should be 6.70

And the code:

Note: Really this should be refactored into different re-usable steps and separate feature files – see this http://stackoverflow.com/questions/5228030/specflow-re-usable-step-definitions

 

[Binding]
    public class OrderCompleteFlow 
    {
        private Order order;
        private IOrderService orderService;
        private Customer customer;
        private IList<Product> tableProducts;

        [Given(@"an order thats in progress")]
        public void GivenAnOrderThatsInProgress()
        {
            customer = MockRepository.GenerateStub<Customer>();
            order = new Order()
            {
                Name = string.Format("Order for {0} {1}", customer.FirstName, customer.LastName),
            };
            order.CurrentState = new Created(order);
            
        }


        [When(@"I add the following products to the inprogress order")]
        public void WhenIAddTheFollowingProductsToTheInprogressOrder(Table table)
        {
            AddSpecFlowTableProductsToProductList(table);
        }

        private void AddSpecFlowTableProductsToProductList(Table table)
        {
            tableProducts = new List<Product>();
            tableProducts = SpecFlowHelpers.ConvertTableToProductList(table);
            tableProducts.Each(order.AddProduct);
        }

        [When(@"I add the following imported products to the inprogress order")]
        public void WhenIAddTheFollowingImportedProductsToTheInprogressOrder(Table table)
        {
            AddSpecFlowTableProductsToProductList(table);
        }

        [When(@"the order is completed")]
        public void WhenTheOrderIsCompleted()
        {
            orderService = IocContainer.Instance.Resolve<IOrderService>();
            orderService.Complete(order);
        }


        [Then(@"the sales tax should be 1\.50")]
        public void ThenTheSalesTaxShouldBe1_50()
        {
            order.TotalTax.ShouldEqual(1.5m);
        }

        [Then(@"the total should be 29\.83")]
        public void ThenTheTotalShouldBe29_83()
        {
            order.TotalOrderCost.ShouldEqual(29.83m);
        }


        [Then(@"the sales tax should be 7\.65")]
        public void ThenTheSalesTaxShouldBe7_65()
        {
            order.TotalTax.ShouldEqual(7.65m);
        }

        [Then(@"the sales tax should be 6\.70")]
        public void ThenTheSalesTaxShouldBe6_70()
        {
            order.TotalTax.ShouldEqual(6.70m);
        }

    }

 

Download the code here


Posted by Chris on Friday, March 11, 2011 2:34 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Holiday reading on my Kindle

  • Pro C# 2010 and the .NET 4 Platform, Fifth Edition
  • Agile Principles Patterns and Practices In C#
  • Foundations of F#
  • Functional Programming for the Real World
  • Addison-Wesley - Cooper - C# Design Patterns- A Tutorial
  • Threading in C# -- Joseph Albahari
  • Code Complete 2nd Edition
  • The Art of Rails (2008)
  • Beginning Ruby on Rails E-Commerce (2006)
  • Design Patterns in Ruby (2007)
  • Too Big to Fail  The Inside Story of How Wall Street and Washington Fought to Save the Financial System
  • Schweser -- Corporate finance, Portfolio management and Equity investments
  • A Brief History of Time – Stephen Hawking

Posted by Chris on Friday, January 28, 2011 5:28 PM
Permalink | Comments (5) | Post RSSRSS comment feed

Spec Flow, Specifications and Chained Commands

A quick experiment with Spec Flow -- http://www.specflow.org/

Spec flow feature

 

Feature: Run Specification rules
To stop large postage costs
As a user
I want to be stopped from buying to much if I am in Australia

@CountryAllowedToProcessOrderWithLargeCost
Scenario: Orders of 20 cannot be sent to Australia
    Given I have a customer with an order for socks
And the order is to be sent to Australia
When I process the order
Then I should not be able to place the order

Spec flow acceptance test

 

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Core;
using Core.OrderStates;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TechTalk.SpecFlow;
 
namespace AcceptanceTests.StepDefinitions
{
    [Binding]
    public class StepDefinitions
    {
        private Customer customer;
        private Order order;
        private Product product;
        private bool orderOk;
 
        [Given(@"I have a customer with an order for socks")]
        public void GivenIHaveACustomerWithAnOrderForSocks()
        {
            customer = new Customer(){FirstName = "chris", LastName = "mckelt"};
            product = new SockProduct() {Id = 1, Name = "AAA", Price = 30};
            order = new Order(customer);
            order.AddProduct(product);
         
        }
 
        [Given(@"the order is to be sent to Australia")]
        public void GivenTheOrderIsToBeSentToAustralia()
        {
            order.SetShippingDestination(ShippingDestination.Australia);
        }
 
        [Then(@"I should not be able to place the order")]
        public void ThenIShouldNotBeAbleToPlaceTheOrder()
        {
            Assert.IsFalse(orderOk);
        }
 
        [When(@"I process the order")]
        public void WhenIProcessTheOrder()
        {
            orderOk = order.CanBecome(new OrderConfirmed());
        }
    }
}

 

The state change from ‘order placed’ to ‘order confirmed’ is not allowed due to 2 specifications

public ISpecification<Order> CreateCanBecomeSpecification(IOrderState newState)
      {
          ISpecification<Order> spec = new CustomerNameCannotBeEmptySpecification();
          spec = spec.And(new ShippingToAustraliaWithPriceOver20NotAllowedSpecification());
          return spec;
      }

Download code


Posted by chris on Saturday, October 16, 2010 6:13 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Custom NHibernate User Type

How to use a custom NHibernate User Type

 

To store the state of a Risk (ie RiskState) as a value in a column we can use a NHibernate.UserType

 

The RiskState can be one of the following: (these are all derived from RiskState which implements IRiskState)

image

Our user type
 
 public class RiskStateNameUserType : IUserType
    {
        #region IUserType Members
 
        public object Assemble(object cached, object owner)
        {
            return cached;
        }
 
        public object DeepCopy(object value)
        {
            return value;
        }
 
        public object Disassemble(object value)
        {
            return value;
        }
 
        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }
 
        public bool IsMutable
        {
            get { return false; }
        }
 
        public object NullSafeGet(System.Data.IDataReader dr, string[] names, object owner)
        {
            var property0 = NHibernateUtil.String.NullSafeGet(dr, names[0]);
 
            if (property0 == null)
            {
                return null;
            }
 
            IRiskState state;
 
            if (owner is Risk)
            {
                state =
                    (IRiskState)
                    Activator.CreateInstance(Type.GetType(typeof(IRiskState).Namespace + "." + (string)property0),
                                             owner);
            }
            else
            {
                state =
                    (IRiskState)
                    Activator.CreateInstance(Type.GetType(typeof(IRiskState).Namespace + "." + (string)property0));
 
            }
 
            return state;
 
        }
 
        public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
        {
            if (value == null)
            {
                ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
            }
            else
            {
                var state = (IRiskState)value;
                ((IDataParameter)cmd.Parameters[index]).Value = state.GetType().Name;
            }
        }
 
        public object Replace(object original, object target, object owner)
        {
            return original;
        }
 
        public Type ReturnedType
        {
            get { return typeof(RiskState); } 
        }
 
        public NHibernate.SqlTypes.SqlType[] SqlTypes
        {
            get { return new[] { NHibernateUtil.String.SqlType }; }
        }
 
        public new bool Equals(object x, object y)
        {
            if (x == null && y == null) return true;
            if (x == null || y == null) return false;
            return x.GetType() == y.GetType();
        }
 
        #endregion
 
    }
 
Using this on a property as follows:
 
 
 [Property(ColumnType = "Matlock.Core.Risks.RiskStateNameUserType, Matlock.Core")]
 public IRiskState RequiredState { get; set; }

 

We can now store types:

 

image

 

 

If importing from a file and we want to parse a string to our user type

 

        protected T GetCustomType<T>(XElement dsl, string attributeName)
        {
            string attribute = (string)dsl.Attribute(attributeName);
            var customType = (T)Activator.CreateInstance(Type.GetType(typeof(T).Namespace + "." + attribute));
            return customType;
        }
 

Posted by chris on Thursday, August 26, 2010 1:06 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Invalid object name 'master.dbo.spt_values'.

This means your SQL Master DB is in a bad state.

To fix:

Error- Invalid object name 'master.dbo.spt_values'.

CD

"C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Install"

run u_tables.sql in master....


Posted by chris on Tuesday, August 24, 2010 8:31 AM
Permalink | Comments (1) | Post RSSRSS comment feed

Agile Flavours

XP

  • 5 values
  • 14 principles
  • 12 Primary practices
  • 11 Corollary practices

Lean

  • 7 principles
  • 22 thinking tools

Scrum

  • 5 Values
  • 3 Roles (Product owner, scrum master, scrum team)
  • 3 Ceremonies  (Sprint planning meeting, Stand up, review & retrospective)
  • 3 Work Products (product backlog, sprint backlog, burndown chart)
  • (depending on which definition you choose)

DSDM Atern

  • 8 Principles
  • 5 Lifecycle phases
  • 12 roles
  • 17 work products
  • 5 key techniques

Agile Unified Process

  • 6 Principles
  • 7 Disciplines
  • 4 Lifecycle Phases
  • 14 Roles
  • 8 minimum deliverables
  • 4 guidance pieces

Posted by chris on Tuesday, August 03, 2010 2:44 AM
Permalink | Comments (1) | Post RSSRSS comment feed

RhinoMocks – WhenCalled

The following test would fail without this

 

.WhenCalled(invocation => invocation.ReturnValue = new TestResult(){IsTrue = true, Message = "BBB"})

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Matlock.Core.Shared;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Rhino.Mocks;

namespace Matlock.Tests
{
    [TestClass]
    public class ChrisTest
    {

        private IRuleService ruleService;

        [TestMethod]
        public void ShouldNotChangeReturnedTestResult()
        {
            ruleService = MockRepository.GenerateMock<IRuleService>();
            var testResult = new TestResult();
            testResult.IsTrue = true;
            testResult.Message = "AAA";
            ruleService.Stub(a => a.GetTestResult()).Return(testResult)
                .WhenCalled(invocation => invocation.ReturnValue = new TestResult(){IsTrue = true, Message = "BBB"});



            var testClass = new TestClass(ruleService);
            testClass.KillTheString();
            Assert.IsTrue(testClass.StringIsThere());
            
        }

        public interface IRuleService
        {
            TestResult GetTestResult();
        }

        public class TestResult
        {
            public bool IsTrue { get; set; }
            public string Message { get; set; }
        }

        private class TestClass
        {
            private readonly IRuleService ruleService;

            public TestClass(IRuleService ruleService)
            {
                this.ruleService = ruleService;
            }

            public void KillTheString()
            {
                var result = ruleService.GetTestResult();
                result.Message = string.Empty;
            }

            public bool StringIsThere()
            {
                var result = ruleService.GetTestResult();
                return !string.IsNullOrEmpty(result.Message);
            }
        }
    }
}

Posted by chris on Tuesday, July 06, 2010 1:51 AM
Permalink | Comments (1) | Post RSSRSS comment feed

Crystal Software Development

Crystal Software Development Download


Posted by chris on Wednesday, June 30, 2010 6:56 AM
Permalink | Comments (0) | Post RSSRSS comment feed