<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Chris's Weblog</title>
  <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/" />
  <link rel="self" href="http://factored-software.com/iimplement/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2008-07-15T05:06:16.0950609-07:00</updated>
  <author>
    <name>(c) 2006 Chris Bilson</name>
  </author>
  <subtitle>Chris's log about software development and other stuff</subtitle>
  <id>http://factored-software.com/iimplement/</id>
  <generator uri="http://www.dasblog.net" version="2.0.7180.0">DasBlog</generator>
  <entry>
    <title>Combinatorial Tests and Splitting Context From Specification</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/07/15/Combinatorial+Tests+And+Splitting+Context+From+Specification.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,2fb7ea34-081d-4af8-839e-63d843221324.aspx</id>
    <published>2008-07-15T05:05:19.7985462-07:00</published>
    <updated>2008-07-15T05:06:16.0950609-07:00</updated>
    <category term="bdd" label="bdd" scheme="http://factored-software.com/iimplement/CategoryView,category,bdd.aspx" />
    <category term="tdd" label="tdd" scheme="http://factored-software.com/iimplement/CategoryView,category,tdd.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Yesterday on twitter I had the start of an interesting conversation with <a href="http://twitter.com/stevenharman">Steve
Harmann</a> and <a href="http://twitter.com/sbellware">Scott Bellware</a>, but then
I had to do work, so I had to stop just when it was getting interesting. 
</p>
        <p>
One of the things I have found useful in writing unit tests for an application I work
on is mbunit’s <a href="http://blog.dotnetwiki.org/CombinatorialTestInTheHeartOfMbUnit.aspx">CombinatorialTest</a>.
If you are familiar with RowTests in mbunit, CombinatorialTests are similar, but allow
you to use a factory method to generate the parameters for the test.
</p>
        <p>
By way of example, below is a dumbed down version of a real test I have. Note that
this was developed before I really knew anything about BDD.
</p>
        <p>
The system under test needs to find the next best move as a number. There are two
candidate moves. If the candidates are on both sides of the number we’re on now (mixed
signals), we don’t move. If they are both on the same side, we move that direction,
but to the number with the smallest change from our current number. I received these
specs from our product owner in the form of an Excel spreadsheet with a formula, mixed
with a crap-load of test data.
</p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
I have found that it’s useful to define a class for the parameter to the test, and
that it’s really useful to have that class have lambdas for the actual test, and that
it’s really, really useful to use Expression&lt;&gt; for the lambdas, so you can print
the result. I am going to call this class a “Specification Class” for lack of a better
term. Here’s the one for the stories described above:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">class</span> PositionSpec</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">{</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">decimal</span> Candidate1
{ get; set; }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">decimal</span> Candidate2
{ get; set; }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">decimal</span> Current
{ get; set; }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">public</span> Expression&lt;Predicate&lt;ModelPosition,<span style="color: #0000ff">decimal</span>&gt;&gt;
Test { get; set; }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">override</span>
              <span style="color: #0000ff">string</span> ToString()</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">return</span> String.Format(<span style="color: #006080">"c1={0:p}
^ c2={1:p} ^ current={2:p} -&gt; {3}"</span>, </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">            Candidate1, Candidate2, Current, Test.Body.ToString());</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">}</pre>
          </div>
        </div>
        <p>
Notice that the Test property is an Expression. If you are not familiar, this is like
a lambda - Expression&lt;Predicate&lt;ModelPosition, decimal&gt;&gt; can do everything
Predicate&lt;ModelPosition, decimal&gt; can do – but you can examine the body of the
expression. I think this is really cool and a gateway to functional+dynamic programming.
In this case though, I just want to use that so I can print the expression in ToString
– mbunit will call this when printing the name of the test in the results, so we can
see which expression we are testing.
</p>
        <p>
Here’s the factory function that produces instances for tests (specifications):
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">public</span> IEnumerable&lt;PositionSpec&gt;
TestPositions()</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">{</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = .15M, Candidate2 = .20M, Current = .17M, </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == .17M };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = .15M, Candidate2 = .20M, Current = .10M, </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == .15M };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = .15M, Candidate2 = .10M, Current = .20M, </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == .15M };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = .15M, Candidate2 = .13M, Current = .10M, </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == .13M };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = .15M, Candidate2 = .17M, Current = .20M, </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == .17M };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = .15M, Candidate2 = .20M, Current = .17M,</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; pos.IsNoActionRequired == <span style="color: #0000ff">true</span> };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = .15M, Candidate2 = 0M, Current = .14M,</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; pos.IsNoActionRequired == <span style="color: #0000ff">true</span> };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = .15M, Candidate2 = 0M, Current = .14M,</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == .14M};</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = .15M, Candidate2 = 0M, Current = .20M,</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == .15M};</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = 0M, Candidate2 = .15M, Current = .14M,</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; pos.IsNoActionRequired == <span style="color: #0000ff">true</span> };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = 0M, Candidate2 = .15M, Current = .14M,</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == .14M};</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = 0M, Candidate2 = .15M, Current = .20M,</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == .15M};</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #0000ff">yield</span>
              <span style="color: #0000ff">return</span>
              <span style="color: #0000ff">new</span> PositionSpec()
{ Candidate1 = 0M, Candidate2 = 0M, Current = .20M,</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Test = (pos, w) =&gt; w == 0M};</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">}</pre>
          </div>
        </div>
        <p>
And finally the test that consumes them:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[CombinatorialTest]</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> should_result_in_smallest_delta_from_current_with_netting(</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    [UsingFactories(<span style="color: #006080">"TestPositions"</span>)]
PositionSpec spec)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">{</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    Mocks.ReplayAll();</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    ModelPosition candidate1 = <span style="color: #0000ff">new</span> ModelPosition(){
Weight = spec.Candidate1 };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    ModelPosition candidate2 = <span style="color: #0000ff">new</span> ModelPosition()</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">        Weight = spec.Candidate2,</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        HeldPositionWeight = spec.Current</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    };</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #0000ff">decimal</span> result
= _methodology.GetNetPositionWeight(candidate2, candidate1);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">    Assert.IsTrue(spec.Test.Compile().Invoke(candidate2, result));</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">}</pre>
          </div>
        </div>
        <p>
The result has the expression bodies printed out, so looks like:
</p>
        <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4">
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">------ Test started: Assembly: XXX.Tests.dll ------</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">Starting the MbUnit Test Execution</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">Exploring XXX.Tests, Version=1.0.0.2, Culture=neutral, PublicKeyToken=<span style="color: #0000ff">null</span></pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">MbUnit 2.41.232.0 Addin</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">Found 13 tests</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[assembly-setup] success</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=15.00 % ^ c2=20.00 % ^ current=17.00 % -&gt; (w = 0.17)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=15.00 % ^ c2=20.00 % ^ current=10.00 % -&gt; (w = 0.15)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=15.00 % ^ c2=10.00 % ^ current=20.00 % -&gt; (w = 0.15)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=15.00 % ^ c2=13.00 % ^ current=10.00 % -&gt; (w = 0.13)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=15.00 % ^ c2=17.00 % ^ current=20.00 % -&gt; (w = 0.17)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=15.00 % ^ c2=20.00 % ^ current=17.00 % -&gt; (pos.IsNoActionRequired = True)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=15.00 % ^ c2=0.00 % ^ current=14.00 % -&gt; (pos.IsNoActionRequired = True)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=15.00 % ^ c2=0.00 % ^ current=14.00 % -&gt; (w = 0.14)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=15.00 % ^ c2=0.00 % ^ current=20.00 % -&gt; (w = 0.15)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=0.00 % ^ c2=15.00 % ^ current=14.00 % -&gt; (pos.IsNoActionRequired = True)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=0.00 % ^ c2=15.00 % ^ current=14.00 % -&gt; (w = 0.14)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=0.00 % ^ c2=15.00 % ^ current=20.00 % -&gt; (w = 0.15)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[success] NettingMethodologyTests.BaseSetup.should_result_in_smallest_delta_from_current_with_netting(TestPositions(c1=0.00 % ^ c2=0.00 % ^ current=20.00 % -&gt; (w = 0)))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">[reports] generating HTML report</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">TestResults: <a href="file:///C:/Users/cbilson/AppData/Roaming/MbUnit/Reports/XXX.Tests.Tests.html">file:<span style="color: #008000">///C:/Users/cbilson/AppData/Roaming/MbUnit/Reports/XXX.Tests.Tests.html
</span></a></pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">13 passed, 0 failed, 0 skipped, took 3.30 seconds.</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"> </pre>
          </div>
        </div>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
So that’s one example. I had a lot of little tiny contexts. I wanted to apply the
same basic proto-spec to each one. I could have done this with a base context class
and a bunch of subclasses, which seems to be the BDD way to do this, but using combinatorial
tests seems more concise and readable to me.
</p>
        <p>
There’s one other really powerful thing you can do with combinatorial tests. Since
you can use these to separate context from spec, you could apply a set of specs to
a set of contexts. Your actual tests would be the cross product of the two, without
having to specify each product. 
</p>
        <p>
For example, say you had a really complicated data entry screen. Your user stories
indicated that everyone needed to be able to edit data in some subset of the fields
on the screen, only admins another subset, and only under certain conditions everyone
could edit all fields. 
</p>
        <p>
There are lots of ways to tackle this, but one way would be to define the two different
subsets using two factories. Then your specifications could be really simple and readable,
like “everyone_should_be_able_to_edit_the_everyone_fields”, “only_admins_can_edit_the_admin_fields”,
and “everyone_can_edit_the_admin_fields_in_some_special_case".”
</p>
        <p>
For admin vs. normal user fields, it would probably be better to just tag the fields
somehow, but what if there were way more conditionals, like “for gold card members
with the super-duper price-protection plan, normal customer service reps should be
able to edit the discount field.” I have a couple of cases like this where the user
interface changes a lot based on a couple of different special conditions and I have
found combinatorial tests really good for this.
</p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
Now that I am getting into BDD, I think I could do a better job of separating the
context from the specification. It seems like the “specification” class I had above
should really be the “context” and I should remove the Test property, since that’s
the core of the specification. I could then use this technique when I have a specification
that applies to a large number of contexts.
</p>
        <img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=2fb7ea34-081d-4af8-839e-63d843221324" />
      </div>
    </content>
  </entry>
  <entry>
    <title>BDD Using Machine.Specifications : Part 2</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/07/13/BDD+Using+MachineSpecifications+Part+2.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,73de8b2b-b5ee-4e09-8eb9-ab0f77b8ac5b.aspx</id>
    <published>2008-07-12T19:12:00-07:00</published>
    <updated>2008-07-14T06:53:00.2297205-07:00</updated>
    <category term="bdd" label="bdd" scheme="http://factored-software.com/iimplement/CategoryView,category,bdd.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
So let’s say I have a user story like:
</p>
        <blockquote>
          <p>
As a Portfolio Analyst
</p>
          <p>
I need to be able to change an account’s market value, overriding what was reported
by the custodian
</p>
          <p>
So I can reflect cash flows I know are going to hit the account.
</p>
        </blockquote>
        <p>
So we talk with them and know that we are going to make the Market Value field on
some screen editable. When they don’t do anything, we will just use the market value
reported by the custodian (which is what we already do now) but when they enter a
manual plug, we will use that value instead.
</p>
        <p>
So the developers talk about it an decide we first want to introduce properties ReportedMarketValue
and EstimatedMarketValue. Here is the original Account class
</p>
        <div>
          <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">class</span> Account</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">{</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">virtual</span>
              <span style="color: rgb(0, 0, 255);">string</span> AccountNumber
{ get; set; }</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">virtual</span>
              <span style="color: rgb(0, 0, 255);">decimal</span> MarketValue
{ get; set; }</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
          </div>
        </div>
        <p>
Which we change to:
</p>
        <div>
          <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">class</span> Account</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">{</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">virtual</span>
              <span style="color: rgb(0, 0, 255);">string</span> AccountNumber
{ get; set; }</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">virtual</span>
              <span style="color: rgb(0, 0, 255);">decimal</span> MarketValue
{ get; set; }</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">virtual</span>
              <span style="color: rgb(0, 0, 255);">decimal</span> ReportedMarketValue
{ get; set; }</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">virtual</span>
              <span style="color: rgb(0, 0, 255);">decimal</span>?
EstimatedMarketValue { get; set; }</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
          </div>
        </div>
        <p>
Next we want to make MarketValue read-only, have it either be EstimatedMarketValue
if there is one, or ReportedMarketValue. All the places that don’t compile anymore
(where someone said “account.MarketValue = “) will be changed to use the ReportedMarketValue
mutator.
</p>
        <p>
…but before that, let’s get our specs in place.
</p>
        <p>
MSpec makes heavy use of lambdas, fluent interface, and a custom nunit test runner
to take away a lot of the curly braces. Again, read Aaron’s blog for the introduction,
but basically, we are going to declare a base class class to establish all the actors
in a series of specs around this story:
</p>
        <div>
          <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">abstract</span>
              <span style="color: rgb(0, 0, 255);">class</span> account_spec</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">{</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">
              <span style="color: rgb(0, 0, 255);">protected</span>
              <span style="color: rgb(0, 0, 255);">static</span> Account
Account { get; <span style="color: rgb(0, 0, 255);">private</span> set; }</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"> </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">  Establish context = () =&gt; {</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    Account = <span style="color: rgb(0, 0, 255);">new</span> Account();</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    Account.ReportedMarketValue = 100M;</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">  };</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
          </div>
        </div>
        <p>
Establish is just a delegate and we’re setting it to an anonymous method to just create
a new Account. Notice that the Account property is static? Yeah, that sucks. You can’t
reference non static members from inside an initializer for a delegate:
</p>
        <p>
          <a href="http://factored-software.com/iimplement/images/forposts/BDDUsingMachine.SpecificationsPart2_9EE2/image.png">
            <img title="image" style="border-width: 0px;" alt="image" src="http://factored-software.com/iimplement/images/forposts/BDDUsingMachine.SpecificationsPart2_9EE2/image_thumb.png" border="0" height="140" width="568" />
          </a>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
I think the driving design choice is to limit the amount of alien noise in the spec.
Here the tradeoff is adding “static” vs. doing the initialization inside of a constructor
or something. Tough call. Whatever, this works, so let’ just go with it.
</p>
        <p>
Next we want to specify what happens when there is no plugged market value:
</p>
        <div>
          <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">[Concerning(<span style="color: rgb(0, 0, 255);">typeof</span>(Account), <span style="color: rgb(0, 96, 128);">"Market
Value"</span>)]</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">class</span> with_no_plugged_market_value
: account_spec</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">{</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">  Because the_account_has_no_plugged_market_value = () =&gt; Account.EstimatedMarketValue = <span style="color: rgb(0, 0, 255);">null</span>;</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">  It should_give_the_reported_market_value_as_the_market_value = () =&gt; </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    Account.MarketValue.ShouldEqual(Account.ReportedMarketValue);</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
          </div>
        </div>
        <p>
There is more decoration here. Let’s go over that:
</p>
        <ul>
          <li>
The Concerning Attribute: Is used to format the output of the test run and to introduce
a “test fixture”. 
</li>
          <li>
Because: is just another anonymous delegate. I think in one of my experiments I tried
having two because’s (I was thinking it be like “because of this and because of that”)
but only one got executed. This makes sense. Just put all your because stuff in the
same block. 
</li>
          <li>
It: is…yep, just another anonymous delegate. You can have multiple It’s. 
</li>
          <li>
ShouldEqual: is a nice extension method that comes with mspec. Thanks! 
</li>
        </ul>
        <p>
When run, this spec fails:
</p>
        <div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
          <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">------ Test started: Assembly: Specs.dll ------ </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"> </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">Account Market Value, with no plugged market value</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">!!» should give the reported market value as the market value !! </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"> </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">TestCase 'should give the reported market value as the market value' failed: </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    NUnit.Framework.AssertionException:   Expected: 100m</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">      But was:  0m</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    at NUnit.Framework.Assert.That(Object actual, Constraint constraint, String message, Object[] args)</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    at NUnit.Framework.Assert.AreEqual(Object expected, Object actual)</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    C:\projects\machine\Source\Specifications\Machine.Specifications\ExtensionMethods.cs(25,0): at Machine.Specifications.ShouldExtensionMethods.ShouldEqual(Object actual, Object expected)</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    C:\Users\cbilson\Documents\Visual Studio 2008\Projects\ClassLibrary2\Specs\Class1.cs(24,0): at Specs.with_no_plugged_market_value.<span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">.ctor</span><span style="color: rgb(0, 0, 255);">&gt;</span>b__1() </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"> </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">0 passed, 1 failed, 0 skipped, took 0.54 seconds.</pre>
          </div>
        </div>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
So we implement it (Spec First Development!):
</p>
        <div>
          <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">virtual</span>
              <span style="color: rgb(0, 0, 255);">decimal</span> MarketValue
{ </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">  get { <span style="color: rgb(0, 0, 255);">return</span> ReportedMarketValue;
}</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">  set { <span style="color: rgb(0, 0, 255);">throw</span><span style="color: rgb(0, 0, 255);">new</span> NotImplementedException();
}</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">}</pre>
          </div>
        </div>
        <p>
        </p>
        <p>
(don’t worry, we’ll get rid of set later in another refactoring – or forget about
it and find a zillion other tests broke.)
</p>
        <p>
Now we pass:
</p>
        <div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
          <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">------ Test started: Assembly: Specs.dll ------</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"> </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">Account Market Value, with no plugged market value</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">  » should give the reported market value as the market value</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"> </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"> </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">1 passed, 0 failed, 0 skipped, took 0.46 seconds.</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"> </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"> </pre>
          </div>
        </div>
        <p>
Note the nice Product-Owner-friendly output. This was one of my bullets from Part
1. Check. 
</p>
        <p>
Remember MTEGOTAG? It turns out that this increases my MTEGOTAG number to about 5
minutes. After that the product owner’s eyes glaze over and their “thinking about
leaving early for a round of golf” program pegs their CPU. They can still search this
output though if they have a question about something. But from a mean of around 13
seconds to 5 minutes is an amazing feat!
</p>
        <p>
The other spec:
</p>
        <div>
          <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">[Concerning(<span style="color: rgb(0, 0, 255);">typeof</span>(Account), <span style="color: rgb(0, 96, 128);">"Market
Value"</span>)]</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">class</span> with_plugged_market_value
: account_spec</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">{</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">  Because the_account_has_plugged_market_value_of_200 = () =&gt; Account.EstimatedMarketValue = 200M;</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">  It should_give_the_estimated_market_value_as_the_market_value = () =&gt;</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    Account.MarketValue.ShouldEqual(Account.EstimatedMarketValue);</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
          </div>
        </div>
        <p>
Which fails until we implement it:
</p>
        <div>
          <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 255);">virtual</span>
              <span style="color: rgb(0, 0, 255);">decimal</span> MarketValue
{ </pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">  get { <span style="color: rgb(0, 0, 255);">return</span> EstimatedMarketValue
?? ReportedMarketValue; }</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">  set { <span style="color: rgb(0, 0, 255);">throw</span><span style="color: rgb(0, 0, 255);">new</span> NotImplementedException();
}</pre>
            <pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">}</pre>
          </div>
        </div>
        <p>
And all our specs run together look like:
</p>
        <table border="1">
          <tbody>
            <tr>
              <td>
                <pre>------ Test started: Assembly: Specs.dll ------<br /><br />
Account Market Value, with no plugged market value<br />
» should give the reported market value as the market value<br /><br />
Account Market Value, with plugged market value<br />
» should give the estimated market value as the market value<br /><br /><br />
2 passed, 0 failed, 0 skipped, took 0.46 seconds.</pre>
              </td>
            </tr>
          </tbody>
        </table>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
This can almost go straight into our trac wiki. Maybe someone I work with will read
this and fix our build scripts to update trac.
</p>
        <p>
One quick note: When you run the spec project in TD.NET, it doesn’t show the output
of all the specs, just how many failed/succeeded. I could probably fix this and submit
a patch. Hopefully I will.
</p>
        <p>
Final things to note: There are a lot of conventions in play here – ex.: the concern’s
name and the spec’s name and how they get formatted in the end. I like conventions
because it means there’s less to explain to get going. I can see new developers being
able to easily learn write specs like this, but I bet they are going to run into a
lot of bizarre compiler errors along the way. Good way for them to learn about lambdas
and c#!
</p>
        <p>
So, apologies for the lame - yet long - and simplistic example. This is <em>almost</em> like
something we did on a real project at work, just way simpler. Now that we have a simple
example to start with, in my next post, I want to go over a more complicated example
– one in which I felt a little bit more pain and confusion. That’s going to take me
longer to type up though. In the meantime, please comment. Thanks!
</p>
        <img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=73de8b2b-b5ee-4e09-8eb9-ab0f77b8ac5b" />
      </div>
    </content>
  </entry>
  <entry>
    <title>BDD Using Machine.Specifications : Part 1</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/07/12/BDD+Using+MachineSpecifications+Part+1.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,11376ee6-c06d-4991-9b1d-e727237f5838.aspx</id>
    <published>2008-07-12T12:05:37.8978717-07:00</published>
    <updated>2008-07-12T12:06:15.6007554-07:00</updated>
    <category term="bdd" label="bdd" scheme="http://factored-software.com/iimplement/CategoryView,category,bdd.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Fellow Seattle ALT.NETter <a href="http://codebetter.com/blogs/aaron.jensen/default.aspx">Aaron
Jensen</a> and his friends at Eleutian released a really interesting library of functionality
several months ago called “<a href="http://www.assembla.com/wiki/show/machine">Machine</a>.”
There are several things in here I can use every day. Not all of it is perfect, but
it’s very innovative, clean, and easy to work with.
</p>
        <p>
Today, I want to talk about Machine.Specifications, or MSpec as I will refer to it
going forward. If you haven’t read <a href="http://codebetter.com/blogs/aaron.jensen/archive/2008/05/08/introducing-machine-specifications-or-mspec-for-short.aspx">Aaron’s
introduction post</a>, read it now, then come back and read this.
</p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
I am still learning BDD but I am already enjoying some benefits of it in my tests.
For the most part, I have just been adopting BDD style naming of my fixtures/tests
(or rather, contexts/specifications), using my existing testing framework (mbunit),
and using really detailed versions of the stories our Product Owners come up with.
I get two main benefits:
</p>
        <ul>
          <li>
Product Owners would know what a test was covering. 
</li>
          <li>
My tests are coupled to the user stories, not the code. 
</li>
        </ul>
        <p>
The advantages are offset by:
</p>
        <ul>
          <li>
Product Owners don’t look at the code. It’s a psychological barrier, but it’s there. 
</li>
          <li>
I am still new to BDD so keep running into things that I find hard to express in BDD
terms. 
</li>
        </ul>
        <p>
One thing almost all BDD frameworks offer that hits one of those bullets is functionality
to format a bullet point list of the specs that are implemented from tests following
a naming convention. That alone is enough reason for me to try some of these frameworks.
</p>
        <blockquote>
          <p>
            <strong>Concept</strong>
            <em>: MTEGOTAG (pronounced “Em Teg-O-Tag”): Mean Time to (Product
Owner) Eyes Glazing Over Thinking About Golf. When I write my specs in c#, this number
is very low, approaching zero. I can keep a Product Owners interest for 10, maybe
20 seconds if I am showing specs in c#. The number gets even lower for each repeated
application per session.</em>
          </p>
        </blockquote>
        <p>
So that’s kind of my motivation. I recently had some time to sit down and actually
do real work in mspec, my next post will be about the results. 
</p>
        <p>
P.S.: If you are in the seattle area and don’t already know this, a bunch of us are <a href="http://sbellware.wufoo.com/forms/seattle-evening-of-bdd-thursday-july-17th-2008/">meeting
to talk about BDD this Thursday</a>. 
</p>
        <img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=11376ee6-c06d-4991-9b1d-e727237f5838" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Foundations of Programming Ebook - Karl Seguin</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/07/01/Foundations+Of+Programming+Ebook+Karl+Seguin.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,96d70927-b5bc-42a6-a0f3-b254437c14f4.aspx</id>
    <published>2008-07-01T08:58:42.3309748-07:00</published>
    <updated>2008-07-01T08:58:42.3309748-07:00</updated>
    <category term="411" label="411" scheme="http://factored-software.com/iimplement/CategoryView,category,411.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <a href="http://codebetter.com/blogs/karlseguin/archive/2008/06/24/foundations-of-programming-ebook.aspx">Foundations
of Programming Ebook - Karl Seguin</a> I just finished reading this book this morning.
It's: 
<ul><li>
Packed with excellent information</li><li>
Concise</li><li>
Free</li></ul>
I would recommend any .net developer read this and will ask anybody I interview if
they have read it from now on.<img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=96d70927-b5bc-42a6-a0f3-b254437c14f4" /></div>
    </content>
  </entry>
  <entry>
    <title>NHibernate 2.0 Beta</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/07/01/NHibernate+20+Beta.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,56f22f97-34c0-40c7-8d7f-cde366bff67c.aspx</id>
    <published>2008-07-01T06:39:18.7282522-07:00</published>
    <updated>2008-07-01T06:39:18.7282522-07:00</updated>
    <category term="nhibernate" label="nhibernate" scheme="http://factored-software.com/iimplement/CategoryView,category,nhibernate.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I was happy to see that <a href="http://ayende.com/Blog/archive/2008/06/30/NHibernate-2.0-Beta-1-Released.aspx">NHibernate
2.0 Beta has been released</a>. Over the past few weeks, in talking to various people,
I have been suprised at the number of people who haven't looked at 2.0 alpha. I've
actually been using it for several months and haven't yet run into any problems, other
than some API changes which was a one time simple change.<br /><br />
Here's to hoping that a new greek letter = more people using newer NHibernate.<br /><p></p><img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=56f22f97-34c0-40c7-8d7f-cde366bff67c" /></div>
    </content>
  </entry>
  <entry>
    <title>Git Pipelines</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/05/16/Git+Pipelines.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,11bee1be-54c6-4c59-9210-32a5151c9ce3.aspx</id>
    <published>2008-05-15T19:07:50.9098983-07:00</published>
    <updated>2008-05-15T19:09:37.8012074-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
When I was a younger programmer I had the privilege of working in a few places where
we had really tight development processes: Daily Builds (before CI was widely known),
test suites (like perl make test type stuff - before TDD became popular) and tools
to help do common things in our process.
</p>
        <p>
One example of a tool like this I remember was working at a company where we were
using CVS and had developed shell scripts to do the work of testing, checking in,
sending a notification, and whatever else it was we did, so you could just type something
like "re-up" and get all in sync and checked in.
</p>
        <p>
When I started using subversion, for some reason I stopped using things like this.
In subversion, I think you are encouraged to hook these things up as hooks on the
server, so clients don't need to have any special scripts or know anything special
to invoke the pre/post-checkin process.
</p>
        <p>
This sounds like a better solution, but it's interesting that I have never once written
a subversion hook script. I don't know why, but it just seems...I don't know...less
visible...harder to test...harder to try out.
</p>
        <p>
Since I started using git, I notice I am building little patterns I do through the
day, like:
</p>
        <pre>git add .; git ci; git co master; git merge NewNettingStrategy; git svn dcommit; git svn co NewNettingStrategy; git merge master</pre>
        <p>
I do this whenever I want to cause a build to happen with whatever I am doing in a
feature branch, then come back to the feature branch.
</p>
        <p>
I usually just keep these things in my history and up-down arrow to invoke them from
powershell, but more and more, I see how these could easily grow into little scripts
to make it real easy to "do things my way." A script could interact with
git to determine things like the current branch, where to merge into, etc. I just
finished one to push my days work to a repo I can get at from home.
</p>
        <p>
Git isn't really any better than subversion in this respect, except for maybe having
more granular control over it, but the mindset lends itself to customization and fitting
to your process, which I really enjoy.
</p>
        <img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=11bee1be-54c6-4c59-9210-32a5151c9ce3" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Drop Dead Simple Podcast Client</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/05/16/Drop+Dead+Simple+Podcast+Client.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,5677d2a7-d8a3-4eba-99c0-c281d2b40097.aspx</id>
    <published>2008-05-15T18:56:42.9056231-07:00</published>
    <updated>2008-05-15T18:56:42.9056231-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I am sick and tired of trying to find a really good podcast client. iTunes has the
best "reach" but itunes sucks in every other respect (I love it when I shift
click a bunch of things while iTunes is thinking real hard about something for 30
seconds, then I release shift, and iTunes thinks I have selected just the last thing 
- "he's not holding down shift now!")
</p>
        <p>
I've tried maybe a dozen other podcast clients and none were worth remembering their
names so I could run them again. A couple of days ago I noticed winamp had podcast
client functionality. After using it for three days and having winamp crash regularly
while trying to manage my podcasts, I gave up and tossed it in the pile with the others.
</p>
        <p>
So, I thought, how fracking hard can this be? A podcast client: it reads rss, looks
at the url of enclosures, and downloads them. What do I know that is really good at
letting me work with XML and is really simple...hmmm....
</p>
        <p>
So I quickly threw together this powershell script (I actually prototyped the whole
thing as a single command line pipeline). Nothing special, but way better than any
of the other podcast clients, and I can make it work exactly how I like:
</p>
        <pre>
          <span style="color: #35687d">$rootPodcastFolder</span> = <span style="color: maroon">'E:\Downloads\Podcasts'</span><span style="color: #35687d">$feeds</span> =
@( <span style="color: maroon">'http://leoville.tv/podcasts/twit.xml'</span>, <span style="color: maroon">'http://feeds.feedburner.com/rubiverse'</span>, <span style="color: maroon">'http://feeds.feedburner.com/netRocksWmadirect'</span>, <span style="color: maroon">'http://feeds.feedburner.com/altnetpodcast'</span>, <span style="color: maroon">'http://channel9.msdn.com/rss.aspx?threadID=312315&amp;format=wma'</span>, <span style="color: maroon">'http://feeds.feedburner.com/Hanselminutes'</span>, <span style="color: maroon">'http://www.npr.org/rss/podcast.php?id=13'</span>, <span style="color: maroon">'http://www.npr.org/rss/podcast.php?id=5'</span>, <span style="color: maroon">'http://blog.stackoverflow.com/?feed=podcast'</span>, <span style="color: maroon">'http://feeds.thisamericanlife.org/talpodcast'</span>, <span style="color: maroon">'http://podcast.thoughtworks.com/itmatters/it_matters.xml'</span> ) <span style="color: #35687d">$agent</span> = <span style="color: #2b91af">new-object</span> net.WebClient <span style="color: blue">foreach</span> (<span style="color: #35687d">$feed</span><span style="color: blue">in</span><span style="color: #35687d">$feeds</span>)
{ <span style="color: #35687d">$document</span> = [xml] <span style="color: #35687d">$agent</span>.DownloadString(<span style="color: #35687d">$feed</span>) <span style="color: #35687d">$title</span> = <span style="color: #35687d">$document</span>.rss.channel.title.Replace(<span style="color: maroon">':'</span>, <span style="color: maroon">'-'</span>) <span style="color: #35687d">$feedFolder</span> =
[io.Path]::Combine(<span style="color: #35687d">$rootPodcastFolder</span>, <span style="color: #35687d">$title</span>) <span style="color: blue">if</span> (![io.Directory]::Exists(<span style="color: #35687d">$feedFolder</span>))
{ [io.Directory]::CreateDirectory(<span style="color: #35687d">$feedFolder</span>)
} <span style="color: #2b91af">Write-Output</span><span style="color: maroon">"Checking
$title ($feedFolder)..."</span><span style="color: blue">foreach</span> (<span style="color: #35687d">$item</span><span style="color: blue">in</span><span style="color: #35687d">$document</span>.rss.channel.item)
{ <span style="color: #35687d">$fileName</span> = [io.Path]::GetFileName(<span style="color: #35687d">$item</span>.enclosure.url) <span style="color: #35687d">$fileName</span> =
[io.Path]::Combine(<span style="color: #35687d">$feedFolder</span>, <span style="color: #35687d">$fileName</span>) <span style="color: blue">if</span> (![io.File]::Exists(<span style="color: #35687d">$fileName</span>))
{ <span style="color: maroon">"`tDownloading {0}..."</span> -f <span style="color: #35687d">$item</span>.enclosure.url <span style="color: #35687d">$agent</span>.DownloadFile(<span style="color: #35687d">$item</span>.enclosure.url, <span style="color: #35687d">$fileName</span>)
} } }</pre>
        <p>
Now, if only powershell could help me copy these files to my windows mobile phone
in less than the decade I've been waiting so far...
</p>
        <img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=5677d2a7-d8a3-4eba-99c0-c281d2b40097" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Mailing Git Patches With Powershell</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/04/30/Mailing+Git+Patches+With+Powershell.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,7a78c940-26be-4056-ac6f-a3fa15f2058f.aspx</id>
    <published>2008-04-30T14:39:51.8407396-07:00</published>
    <updated>2008-04-30T14:39:51.8407396-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Git is a great distributed version control system that I am getting to like more and
more everyday. We don't use git where I work, but for me, git works just as well as
a super-powered subversion client.
</p>
        <p>
I like to have git integrated with the rest of my (cmd) shell, so I use the MSysGit
found <a href="http://code.google.com/p/msysgit/">here</a>. This is as close as you
can get to native git on windows. Using this, I am able to use git in powershell,
cmd scripts, build scripts, or in lots of other places, without having to invoke it
through something like the bash.exe that comes with cygwin.
</p>
        <p>
Unfortunately, as of this writing, msysgit does not include git-send-mail (<a href="http://code.google.com/p/msysgit/issues/detail?id=27&amp;colspec=ID%20Type%20Status%20Priority%20Component%20Owner%20Summary">here's
the issue</a>). As I wrote before, I sometimes need to manually push patches around
between the various computers I work on, and e-mail would work great for this.
</p>
        <p>
Fortunately, <a href="http://www.codeplex.com/PowerShellCX">powershell community extensions</a> has
a Send-SmtpMail cmdlet that can do the same things git-send-mail did - even more actually.
</p>
        <p>
I use pobox.com for my e-mail and their smtp relay will relay mail for me, but only
if I authenticate properly. As far as I know (I haven't actually tried this) git-send-mail
isn't able to authenticate with my e-mail provider.
</p>
        <p>
Anyway, here is what I do, in powershell, to e-mail my patches:
</p>
        <pre>git format-patch -M origin</pre>
        <p>
Then, to send it off:
</p>
        <pre>mail -To cbilson@whereheworks.com `
     -From cbilson@pobox.com `
     -SmtpHost sasl.smtp.pobox.com `
     -Credential (<span style="color: #2b91af">get-credential</span>)
` -AttachmentPath *.path ` -Bcc cbilson@pobox.com ` -Body <span style="color: maroon">"Please
apply this patch. KTHXBY"</span></pre>
        <p>
I get the patches as attachments, save them to a folder somewhere, and just use git-am
to apply them at work.
</p>
        <p>
The kind of weird thing about this is that all the patches are in my gmail account
and I have a folder for them. Given the baseline I started using git from, I could
re-apply all those patches and get back to HEAD (I would likely want to use powershell
to automate that!) So Gmail is my repo.
</p>
        <img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=7a78c940-26be-4056-ac6f-a3fa15f2058f" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Working With Git Patch Files on Windows</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/04/30/Working+With+Git+Patch+Files+On+Windows.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,68987486-aa83-4cef-9030-e9349ef07480.aspx</id>
    <published>2008-04-29T17:20:02.2969767-07:00</published>
    <updated>2008-04-29T17:20:02.2969767-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Due to various network obstacles between my work and personal machines, I often find
it necessary and convenient, when using git, to use skydrive, thumbdrives, or some
other low-tech means to pass around patch files. Git has really nice integration with
common unix mail utilities that make it really sweet to do this on unix.
</p>
        <p>
But I am using windows.
</p>
        <p>
I had to overcome a couple of annoying but obvious hurdles to get this to work. Here's
my current process for cloning a project in an svn repo at work, then passing patches
around:
</p>
        <p>
1. clone the svn repo. Let's call this clone':
</p>
        <pre>git svn clone -s <a href="http://svn-server/MyProject">http://svn-server/MyProject</a></pre>
        <p>
Actually, I am lying. I use this command because our projects are not in the canonical
git layout in our repository:
</p>
        <pre>git svn clone http://svn-server/svn --trunk=trunk/MyProject --branches=branches/MyProject --tags=tags/MyProject</pre>
        <p>
2. Make sure your repo has core.fileMode false (this takes care of many of the other
problems I had with git too):
</p>
        <pre>git repo-config core.fileMode false</pre>
        <p>
3. For some reason my life is easier with core.autocrlf false. Or maybe that's why
I always have to --whitespace nowarn when I apply patches. I don't know. This is just
the way I am doing it and it works.
</p>
        <pre>git config --global core.autocrlf false</pre>
        <p>
4. Clone that repo to take home or wherever. Call this clone''. Remember that the
real magic in cloning is that it creates tracking branches:
</p>
        <pre>git clone --no-checkout C:\Projects\MyProject.git E:\ToTakeCome\MyProject.git</pre>
        <p>
5. Say I am home on clone''. I branch, work, commit. Do the dance, now I want to takes
these changes back to the mother ship. Machines aren't connected. Don't want to bring
laptop to work:
</p>
        <pre>git format-patch -M origin; <span style="color: #2b91af">cp</span> *.patch E:\TakeToWork</pre>
        <p>
6. At work, in clone':
</p>
        <pre>git am -<span style="color: maroon">3</span> --whitespace nowarn E:\FromHome\*.patch</pre>
        <p>
That's basically how I am doing it, after many blind alleys and false starts. My process
is a work in progress, so I will update when it changes.
</p>
        <img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=68987486-aa83-4cef-9030-e9349ef07480" />
      </div>
    </content>
  </entry>
  <entry>
    <title>How To Make Your MSI Install But Not Own An AppPool with Wix</title>
    <link rel="alternate" type="text/html" href="http://factored-software.com/iimplement/2008/04/29/How+To+Make+Your+MSI+Install+But+Not+Own+An+AppPool+With+Wix.aspx" />
    <id>http://factored-software.com/iimplement/PermaLink,guid,a4a61b8c-fefd-4122-b78b-8c4f43dba097.aspx</id>
    <published>2008-04-29T14:04:31.8937776-07:00</published>
    <updated>2008-04-29T14:04:31.8937776-07:00</updated>
    <category term="installer" label="installer" scheme="http://factored-software.com/iimplement/CategoryView,category,installer.aspx" />
    <category term="tool" label="tool" scheme="http://factored-software.com/iimplement/CategoryView,category,tool.aspx" />
    <category term="wix" label="wix" scheme="http://factored-software.com/iimplement/CategoryView,category,wix.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
We use <a href="http://wix.sourceforge.net/">Wix</a> to build installers at my work.
I've <a href="http://factored-software.com/iimplement/2007/12/08/WIX+CI+Builder.aspx">blogged
about this before</a>.
</p>
        <p>
Wix comes with custom actions to create IIS App Pools and Virtual Directories. Up
until today, my wix scripts all WebVirtualDirs and WebAppPools in the same component:
</p>
        <pre>
          <span style="color: blue">&lt;</span>
          <span style="color: maroon">Component</span>
          <span style="color: red">Id</span>='WebApp_WithAppPool' <span style="color: red">Guid</span>='$(var.IIsWithAppPoolSettingsComponentId)'<span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">Condition</span><span style="color: blue">&gt;</span>Not
IISMAJORVERSION="<span style="color: blue">#5</span>"<span style="color: blue">&lt;</span>/<span style="color: maroon">Condition</span><span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">WebAppPool</span><span style="color: red">Id</span>='MyAppPool' <span style="color: red">Name</span>='$(var.AppPool)'
/<span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">WebVirtualDir</span><span style="color: red">Id</span>='MyVDirWithAppPool' <span style="color: red">Alias</span>='IMR/$(var.InstallDirectory)' <span style="color: red">Directory</span>='INSTALLDIR' <span style="color: red">WebSite</span>='Default' <span style="color: red">DirProperties</span>='AppDirProps'<span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">WebApplication</span><span style="color: red">Id</span>="<span style="color: blue">MyAppWithAppPool</span>" <span style="color: red">Name</span>='[ProductName]' <span style="color: red">WebAppPool</span>='MyAppPool'<span style="color: blue">&gt;</span></pre>
        <p>
We recently changed the security model of this application to use a service account,
but the above installer would uninstall the app pool when the application was uninstalled.
When they went to install an upgraded version they would have to find someone that
knew the password for the service account to enter it in the app pool settings after
installing.
</p>
        <p>
A little searching led me to <a href="http://www.mail-archive.com/wix-users@lists.sourceforge.net/msg09413.html">this
mailing list thread</a>, where they recommend adding a Permanent='yes' attribute (which
I didn't realize existed.)
</p>
        <p>
This worked, but then my vdir doesn't get uninstalled, so I just created a new component
for the app pool, made it permanent, and voila:
</p>
        <ul>
          <li>
When installing</li>
          <ul>
            <li>
If the app pool doesn't exist it's created</li>
            <li>
If it exists we leave it alone but still put the app in it.</li>
          </ul>
          <li>
When uninstalling</li>
          <ul>
            <li>
The vdir is deleted, but the app pool is left alone.</li>
          </ul>
        </ul>
        <pre>
          <span style="color: blue">&lt;</span>
          <span style="color: maroon">Component</span>
          <span style="color: red">Id</span>="<span style="color: blue">WebApp_AppPool</span>" <span style="color: red">Guid</span>="<span style="color: blue">$(var.IIsAppPoolComponentId)</span>" <strong><em><span style="color: red">Permanent</span>="<span style="color: blue">yes</span>"</em></strong><span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">Condition</span><span style="color: blue">&gt;</span>Not
IISMAJORVERSION="<span style="color: blue">#5</span>"<span style="color: blue">&lt;</span>/<span style="color: maroon">Condition</span><span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">WebAppPool</span><span style="color: red">Id</span>='MyAppPool' <span style="color: red">Name</span>='$(var.AppPool)'
/<span style="color: blue">&gt;</span><span style="color: blue">&lt;</span>/<span style="color: maroon">Component</span><span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">Component</span><span style="color: red">Id</span>='WebApp_WithAppPool' <span style="color: red">Guid</span>='$(var.IIsWithAppPoolSettingsComponentId)'<span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">Condition</span><span style="color: blue">&gt;</span>Not
IISMAJORVERSION="<span style="color: blue">#5</span>"<span style="color: blue">&lt;</span>/<span style="color: maroon">Condition</span><span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">WebVirtualDir</span><span style="color: red">Id</span>='MyVDirWithAppPool' <span style="color: red">Alias</span>='IMR/$(var.InstallDirectory)' <span style="color: red">Directory</span>='INSTALLDIR' <span style="color: red">WebSite</span>='Default' <span style="color: red">DirProperties</span>='AppDirProps'<span style="color: blue">&gt;</span><span style="color: blue">&lt;</span><span style="color: maroon">WebApplication</span><span style="color: red">Id</span>="<span style="color: blue">MyAppWithAppPool</span>" <span style="color: red">Name</span>='[ProductName]' <span style="color: red">WebAppPool</span>='MyAppPool'<span style="color: blue">&gt;</span></pre>
        <p>
 
</p>
        <p>
It actually took me a little while to find out about Permanent='yes', hence this blog
post.
</p>
        <img width="0" height="0" src="http://factored-software.com/iimplement/aggbug.ashx?id=a4a61b8c-fefd-4122-b78b-8c4f43dba097" />
      </div>
    </content>
  </entry>
</feed>