Re: Writing New Constraints for NUnit

"Simone Busoli" <[email protected]> Mon, 8 Sep 2008 08:10:00 +0200
Newsgroups gmane.comp.windows.dotnet.nunit.user
Message-ID <[email protected]>
--===============1436902837==
Content-Type: multipart/alternative; 
	boundary="----=_Part_70289_20180051.1220854200270"

------=_Part_70289_20180051.1220854200270
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Hi Charlie, no way. I did a clean checkout. Actually, I have several
issues. * If I run the build.bat I get an error saying that it cannot find
the csc compiler in the fx 1.0 folder. I don't have the fx 1.0 installed!
* Then I tried with nant -D:default.runtime=net-2.0 but it complaints about
the SDK not being there.* So I tried changing nunit.proj msbuild file,
setting the TargetFrameworkVersion property to 2.0. I get the
FactoriesAttribute error.
* Then I tried changing the solution the msbuild file points to from 2005 to
2008 but now the error is that a project named adhoc-tests.csproj has no
inputs specified.

Building NUnit is challenging!

On Mon, Sep 8, 2008 at 2:13 AM, Charlie Poole <[email protected]> wrote:

>  Yes, we're eating our own dogfood! I added a number of tests that use 2.5
> features.
> So using TD.Net is not possible till there's a release that supports it.
>
> I think you're running into the same problem reported by somebody else on
> one
> of our lists - the Nant build script for nunit.framework contains an entry
> for
> FactoriesAttribute.cs rather than TestCases attribute. I fixed this only
> recently.
>
> I suggest trying to get the very latest source. If you still have problems,
> let
> me know so I can update CVS correctly
>
> (One mistake I sometimes make is to update from within the src directory.
> Make sure you do it from the top level directory to get everything.)
>
> Charlie
>
>  ------------------------------
> *From:* Simone Busoli [mailto:[email protected]]
> *Sent:* Sunday, September 07, 2008 4:17 PM
> *To:* Charlie Poole
> *Cc:* [email protected]
> *Subject:* Re: [Nunit-users] Writing New Constraints for NUnit
>
>  Thanks for the guide. I'm trying to write the
> BinarySerializableConstraint but I'm having some issues with building and
> testing NUnit. So far I had been able to build and run tests from within VS
> via TD.NET, but now I noticed that base test classes use NUnit 2.5
> features so I had to rely on something else. I tried building NUnit with
> nant but no success, it complaints about missing files, specifically a
> Factory[something].cs. Then, since I can run the build with VS 2008, I
> downloaded NUnit 2.5 alpha 3 (won't trust the build on my machine) and tried
> with that, but I'm getting red all over the place in the tests for the
> constraints, while everything's green for the other stuff in Tests and
> Syntax namespaces. At a quick look it seems that what's failing are the
> tests defined in the ConstraintTestBase class (FailsWithBadValues,
> ProvidesProperFailureMessage), those using the TestCases attribute in other
> words.
>
> On Sun, Sep 7, 2008 at 7:35 PM, Charlie Poole <[email protected]> wrote:
>
>> Hi All,
>>
>> I've been asked to provide more info on the increasingly complicated
>> process of adding a new constraint to NUnit. Since I still expect
>> it to change - and hopefully get simpler - I'm doing it on these
>> mailing lists as "current but subject to change" information.
>>
>> This is basically a "how-to" but I've added a postscript about
>> why the design is as it is at the end.
>>
>> Actually, adding a constraint is easy. It's documented here:
>> http://nunit.org/?p=customConstraints&r=2.5 It gets more
>> complicated when you also want to work with the syntax
>> of NUnit's fluent interface for Asserts.
>>
>> I generally write constraints test first, jumping between the
>> tests and the constraint and between the syntax tests and
>> the syntactic elements. That's hard to describe, so I'll just
>> tell you what's needed at the end here.
>>
>> 1. The Constraint
>> I assume you're writing a simple constraint, one that does
>> not operate on other constraints. Inherit your constraint
>> class from Constraint and override the two abstract members
>> Match() and WriteDescriptionTo(). Be sure to set the value
>> of the protected field "actual" in your Match method, since
>> that is used in any error message. Depending on the constraint
>> you are writing, you might need to override other methods, but
>> leave them alone unless you need to do it.
>>
>> If your  constraint has a generic variation, be sure to define
>> it within the scope of an #if NET_2_0 condition. If it operates
>> on any collections, try to make it work with IEnumerable
>> only and avoid copying the collection.
>>
>> An important rule for constraints is to check for invalid
>> arguments and throw an exception. Do NOT just return false.
>> While this may work for simple cases, it will mess up more
>> complicated usage where constraints are combined with
>> various operators. And, of course, it may hide an error.
>>
>> 2. Constraint Tests
>> Derive one or more classes from ConstraintTestBase. Each of
>> those will be used to test one instance of the constraint.
>> How many you need depend on how many variations there are
>> within your constraint. Be sure to create separate tests
>> for generic variations -within an #if statement.
>>
>> Write any extra tests you need, adding them to the same
>> classes or within a separate fixture.
>>
>> NOTE: If you stop here, your constraint is useable by
>> creating it with new. You can write statements like:
>>  Assert.That( xxx, new MyConstraint(...) );
>>
>> NOTE: See below if your constraint takes modifiers
>>
>> 3. Syntactic Elements
>> You will need to pick one or more key words for use
>> in the NUnit syntax. Pick something that will be
>> meaningful while keeping it reasonably short.
>>
>> Currently, you must add your syntactic element in
>> three places. I'm looking at using code generation
>> to eliminate this duplication. The following
>> classes need to be updated:
>>
>> * PartialConstraintExpression - look at how other
>>  simple constraints are implemented here. If
>>  your constraint takes modifiers, see below.
>>  Otherwise, you will just need a method similar
>>  to this one for TypeOf:
>>
>>  public ConstraintExpression TypeOf(Type expectedType)
>>  {
>>    return this.Append(new ExactTypeConstraint(expectedType));
>>  }
>>
>> * Is/Has - you decide which is better, or consult
>>  on the list if you're convinced that you need
>>  a new class. Add a method similar to this:
>>
>>  public static ConstraintExpression TypeOf(Type expectedType)
>>  {
>>    return new PartialConstraintExpression().TypeOf(expectedType);
>>  }
>>
>> * ConstraintFactory: Add a method similar to this:
>>
>>  public ConstraintExpression TypeOf(Type expectedType)
>>  {
>>    return Is.TypeOf(expectedType);
>>  }
>>
>> NOTE: It's important to keep the actual logic in the
>> PartialConstraintBuilder class, with the others depending
>> on it.
>>
>> NOTE: If your constraint takes no args, use properties
>> rather than methods - it's easier to read.
>>
>> 4. Syntax Tests
>> Derive one or more classes from SyntaxTest. You will
>> need one for each different syntax you need to test.
>> If you forget to add code to any of the three classes
>> above, these tests will tell you.
>>
>> At this point you're done... UNLESS you want to add
>> modifiers to your class. If your constraint will take
>> any modifiers, I suggest you do all of the above first,
>> then add the first one and make it work, then add
>> the others. Come back to this note if/when you want
>> to add a modifier...
>>
>> Welcome Back!
>>
>> In the NUnit syntax, a modifier is a property or method
>> that returns the object itself, after making some sort
>> of state change. Existing examples of modifiers are
>> Within(), IgnoreCase and Descending. Here's a simple
>> modifier:
>>
>>  public EqualConstraint IgnoreCase
>>  {
>>    get { caseInsensitive = true; return this; }
>>  }
>>
>> With the above addition, it's possible to write
>>  new EqualConstraint("hello").IgnoreCase
>> but NOT
>>  Is.EqualTo("hello").IgnoreCase
>>
>> In order to make the syntax work, it's currently
>> necessary to create a ConstraintModifier class.
>> These classes inherit from ConstraintModifier
>> and are usually implemented as nested classes
>> within the constraint itself, so as to allow
>> access to private members of the constraint.
>>
>> Here's a simplified version of the one for
>> EqualConstraint:
>>
>>  public class Modifier : ConstraintModifier
>>  {
>>    private EqualConstraint constraint;
>>
>>    public Modifier(EqualConstraint constraint,
>>                    ConstraintExpression builder)
>>      : base(constraint, builder)
>>    {
>>      this.constraint = constraint;
>>    }
>>
>>    public Modifier IgnoreCase
>>    {
>>        get { constraint.caseInsensitive = true; return this; }
>>    }
>>  }
>>
>> After implementing the above, the three syntax classes
>> need to be changed so our methods return EqualConstraint.Modifier.
>> ConstraintFactory and Is/Has require no further changes but
>> PartialConstraintExpression will now look like this:
>>
>>  public EqualConstraint.Modifier EqualTo(object expected)
>>  {
>>    EqualConstraint constraint = new EqualConstraint(expected);
>>    return new EqualConstraint.Modifier(constraint,
>> this.Append(constraint));
>>  }
>>
>> That's "all" there is to it! :-)
>>
>> Charlie
>>
>> Theoretical PostScript:
>>
>> In case you wonder Why we neeed all the classes:
>>
>> We want to provide a good object model, while *at*the*same*time*
>> having only reasonable choices appear in the intellisense. And
>> we want whatever you can compile to make sense as much as
>> is possible, so that there aren't too many runtime checks.
>>
>> So we need separate PartialConstraintExpression and
>> ConstraintExpression classes to make sure you can't
>> enter ...And.And... or ...Null.Null... and similar
>> meaningless stuff.
>>
>> We need Is/Has to provide static methods to get the
>> expression started.
>>
>> We need ConstraintFactory, to supply instance methods
>> for use by those who prefer to derive test classes
>> from AssertionHelper. We could eliminnate that
>> class by eliminating the feature.
>>
>> In particular, the Modifier classes are needed because we
>> are dealing with a ConstraintExpression, but want the
>> choices offered to the user to represent those provided
>> for an Equal Constraint. The Modifier class ties together
>> the whole expression and the "leading edge" constraint
>> in a way that lets us have both. If the user ends the
>> expression, the Modifier's implementation of IConstraint
>> is used. If the user types "IgnoreCase" the EqualConstraint
>> is used. If the user types "And" or "Or", that's handled
>> by the ConstraintExpression.
>>
>> I'm working on a few approaches to this extra class.
>>
>>
>>
>>
>>
>>
>> -------------------------------------------------------------------------
>> This SF.Net email is sponsored by the Moblin Your Move Developer's
>> challenge
>> Build the coolest Linux based applications with Moblin SDK & win great
>> prizes
>> Grand prize is a trip for two to an Open Source event anywhere in the
>> world
>> http://moblin-contest.org/redirect.php?banner_id=100&url=/
>> _______________________________________________
>> Nunit-users mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/nunit-users
>>
>
>

------=_Part_70289_20180051.1220854200270
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

<div dir="ltr">Hi Charlie, no way. I did a clean checkout. Actually, I have several issues.&nbsp;<div>* If I run the build.bat I get an error saying that it cannot find the csc compiler in the fx 1.0 folder. I don&#39;t have the fx 1.0 installed!&nbsp;</div>
<div>* Then I tried with nant -D:default.runtime=net-2.0 but it complaints about the SDK not being there.<div>* So I tried changing nunit.proj msbuild file, setting the&nbsp;TargetFrameworkVersion property to 2.0. I get the FactoriesAttribute error.</div>
<div>* Then I tried changing the solution the msbuild file points to from 2005 to 2008 but now the error is that a project named adhoc-tests.csproj has no inputs specified.</div><div><br></div><div>Building NUnit is challenging!<br>
<br><div class="gmail_quote">On Mon, Sep 8, 2008 at 2:13 AM, Charlie Poole <span dir="ltr">&lt;<a href="mailto:[email protected]">[email protected]</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">




<div>
<div><span><font face="Arial" color="#0000ff" size="2">Yes, 
we&#39;re eating our own dogfood! I added a number of tests that use 2.5 
features.</font></span></div>
<div><span><font face="Arial" color="#0000ff" size="2">So 
using TD.Net is not possible till there&#39;s a release that supports 
it.</font></span></div>
<div><span><font face="Arial" color="#0000ff" size="2"></font></span>&nbsp;</div>
<div><span><font face="Arial" color="#0000ff" size="2">I 
think you&#39;re running into the same problem reported by somebody else on 
one</font></span></div>
<div><span><font face="Arial" color="#0000ff" size="2">of our 
lists - the Nant build script for nunit.framework contains an entry 
for</font></span></div>
<div><span><font face="Arial" color="#0000ff" size="2">FactoriesAttribute.cs rather than TestCases attribute. I fixed this only 
recently.</font></span></div>
<div><span><font face="Arial" color="#0000ff" size="2"></font></span>&nbsp;</div>
<div><span><font face="Arial" color="#0000ff" size="2">I 
suggest trying to get the very latest source. If you still have problems, 
let</font></span></div>
<div><span><font face="Arial" color="#0000ff" size="2">me 
know so I can update CVS correctly</font></span></div>
<div><span><font face="Arial" color="#0000ff" size="2"></font></span>&nbsp;</div>
<div><span><font face="Arial" color="#0000ff" size="2">(One 
mistake I sometimes make is to update from within the src 
directory.</font></span></div>
<div><span><font face="Arial" color="#0000ff" size="2">Make 
sure you do it from the top level directory to get 
everything.)</font></span></div>
<div><span><font face="Arial" color="#0000ff" size="2"></font></span>&nbsp;</div>
<div><span><font face="Arial" color="#0000ff" size="2">Charlie</font></span></div><br>
<blockquote dir="ltr" style="padding-left:5px;margin-left:5px;border-left:#0000ff 2px solid;margin-right:0px">
  <div lang="en-us" dir="ltr" align="left">
  <hr>
  <font face="Tahoma" size="2"><b>From:</b> Simone Busoli 
  [mailto:<a href="mailto:[email protected]" target="_blank">[email protected]</a>] <br><b>Sent:</b> Sunday, September 07, 2008 
  4:17 PM<br><b>To:</b> Charlie Poole<br><b>Cc:</b> 
  <a href="mailto:[email protected]" target="_blank">[email protected]</a><br><b>Subject:</b> Re: [Nunit-users] Writing 
  New Constraints for NUnit<br></font><br></div><div><div></div><div class="Wj3C7c">
  <div></div>
  <div dir="ltr">Thanks for the guide. I&#39;m trying to write the 
  BinarySerializableConstraint but I&#39;m having some issues with building and 
  testing NUnit. So far I had been able to build and run tests from within VS 
  via <a href="http://TD.NET" target="_blank">TD.NET</a>, but now I noticed that base test 
  classes use NUnit 2.5 features so I had to rely on something else. I tried 
  building NUnit with nant but no success, it complaints about missing files, 
  specifically a Factory[something].cs. Then, since I can run the build with VS 
  2008, I downloaded NUnit 2.5 alpha 3 (won&#39;t trust the build on my machine) and 
  tried with that, but I&#39;m getting red all over the place in the tests for the 
  constraints, while everything&#39;s green for the other stuff in Tests and Syntax 
  namespaces. At a quick look it seems that what&#39;s failing are the tests defined 
  in the ConstraintTestBase class (FailsWithBadValues, 
  ProvidesProperFailureMessage), those using the&nbsp;TestCases attribute in 
  other words.<br><br>
  <div class="gmail_quote">On Sun, Sep 7, 2008 at 7:35 PM, Charlie Poole <span dir="ltr">&lt;<a href="mailto:[email protected]" target="_blank">[email protected]</a>&gt;</span> wrote:<br>
  <blockquote class="gmail_quote" style="padding-left:1ex;margin:0px 0px 0px 0.8ex;border-left:#ccc 1px solid">Hi 
    All,<br><br>I&#39;ve been asked to provide more info on the increasingly 
    complicated<br>process of adding a new constraint to NUnit. Since I still 
    expect<br>it to change - and hopefully get simpler - I&#39;m doing it on 
    these<br>mailing lists as &quot;current but subject to change&quot; 
    information.<br><br>This is basically a &quot;how-to&quot; but I&#39;ve added a postscript 
    about<br>why the design is as it is at the end.<br><br>Actually, adding a 
    constraint is easy. It&#39;s documented here:<br><a href="http://nunit.org/?p=customConstraints&amp;r=2.5" target="_blank">http://nunit.org/?p=customConstraints&amp;r=2.5</a> It gets 
    more<br>complicated when you also want to work with the syntax<br>of NUnit&#39;s 
    fluent interface for Asserts.<br><br>I generally write constraints test 
    first, jumping between the<br>tests and the constraint and between the 
    syntax tests and<br>the syntactic elements. That&#39;s hard to describe, so I&#39;ll 
    just<br>tell you what&#39;s needed at the end here.<br><br>1. The 
    Constraint<br>I assume you&#39;re writing a simple constraint, one that 
    does<br>not operate on other constraints. Inherit your constraint<br>class 
    from Constraint and override the two abstract members<br>Match() and 
    WriteDescriptionTo(). Be sure to set the value<br>of the protected field 
    &quot;actual&quot; in your Match method, since<br>that is used in any error message. 
    Depending on the constraint<br>you are writing, you might need to override 
    other methods, but<br>leave them alone unless you need to do it.<br><br>If 
    your &nbsp;constraint has a generic variation, be sure to define<br>it 
    within the scope of an #if NET_2_0 condition. If it operates<br>on any 
    collections, try to make it work with IEnumerable<br>only and avoid copying 
    the collection.<br><br>An important rule for constraints is to check for 
    invalid<br>arguments and throw an exception. Do NOT just return 
    false.<br>While this may work for simple cases, it will mess up 
    more<br>complicated usage where constraints are combined with<br>various 
    operators. And, of course, it may hide an error.<br><br>2. Constraint 
    Tests<br>Derive one or more classes from ConstraintTestBase. Each 
    of<br>those will be used to test one instance of the constraint.<br>How many 
    you need depend on how many variations there are<br>within your constraint. 
    Be sure to create separate tests<br>for generic variations -within an #if 
    statement.<br><br>Write any extra tests you need, adding them to the 
    same<br>classes or within a separate fixture.<br><br>NOTE: If you stop here, 
    your constraint is useable by<br>creating it with new. You can write 
    statements like:<br>&nbsp;Assert.That( xxx, new MyConstraint(...) 
    );<br><br>NOTE: See below if your constraint takes modifiers<br><br>3. 
    Syntactic Elements<br>You will need to pick one or more key words for 
    use<br>in the NUnit syntax. Pick something that will be<br>meaningful while 
    keeping it reasonably short.<br><br>Currently, you must add your syntactic 
    element in<br>three places. I&#39;m looking at using code generation<br>to 
    eliminate this duplication. The following<br>classes need to be 
    updated:<br><br>* PartialConstraintExpression - look at how 
    other<br>&nbsp;simple constraints are implemented here. If<br>&nbsp;your 
    constraint takes modifiers, see below.<br>&nbsp;Otherwise, you will just 
    need a method similar<br>&nbsp;to this one for TypeOf:<br><br>&nbsp;public 
    ConstraintExpression TypeOf(Type expectedType)<br>&nbsp;{<br>&nbsp; 
    &nbsp;return this.Append(new 
    ExactTypeConstraint(expectedType));<br>&nbsp;}<br><br>* Is/Has - you decide 
    which is better, or consult<br>&nbsp;on the list if you&#39;re convinced that 
    you need<br>&nbsp;a new class. Add a method similar to 
    this:<br><br>&nbsp;public static ConstraintExpression TypeOf(Type 
    expectedType)<br>&nbsp;{<br>&nbsp; &nbsp;return new 
    PartialConstraintExpression().TypeOf(expectedType);<br>&nbsp;}<br><br>* 
    ConstraintFactory: Add a method similar to this:<br><br>&nbsp;public 
    ConstraintExpression TypeOf(Type expectedType)<br>&nbsp;{<br>&nbsp; 
    &nbsp;return Is.TypeOf(expectedType);<br>&nbsp;}<br><br>NOTE: It&#39;s important 
    to keep the actual logic in the<br>PartialConstraintBuilder class, with the 
    others depending<br>on it.<br><br>NOTE: If your constraint takes no args, 
    use properties<br>rather than methods - it&#39;s easier to read.<br><br>4. 
    Syntax Tests<br>Derive one or more classes from SyntaxTest. You will<br>need 
    one for each different syntax you need to test.<br>If you forget to add code 
    to any of the three classes<br>above, these tests will tell you.<br><br>At 
    this point you&#39;re done... UNLESS you want to add<br>modifiers to your class. 
    If your constraint will take<br>any modifiers, I suggest you do all of the 
    above first,<br>then add the first one and make it work, then add<br>the 
    others. Come back to this note if/when you want<br>to add a 
    modifier...<br><br>Welcome Back!<br><br>In the NUnit syntax, a modifier is a 
    property or method<br>that returns the object itself, after making some 
    sort<br>of state change. Existing examples of modifiers are<br>Within(), 
    IgnoreCase and Descending. Here&#39;s a simple<br>modifier:<br><br>&nbsp;public 
    EqualConstraint IgnoreCase<br>&nbsp;{<br>&nbsp; &nbsp;get { caseInsensitive 
    = true; return this; }<br>&nbsp;}<br><br>With the above addition, it&#39;s 
    possible to write<br>&nbsp;new EqualConstraint(&quot;hello&quot;).IgnoreCase<br>but 
    NOT<br>&nbsp;Is.EqualTo(&quot;hello&quot;).IgnoreCase<br><br>In order to make the 
    syntax work, it&#39;s currently<br>necessary to create a ConstraintModifier 
    class.<br>These classes inherit from ConstraintModifier<br>and are usually 
    implemented as nested classes<br>within the constraint itself, so as to 
    allow<br>access to private members of the constraint.<br><br>Here&#39;s a 
    simplified version of the one for<br>EqualConstraint:<br><br>&nbsp;public 
    class Modifier : ConstraintModifier<br>&nbsp;{<br>&nbsp; &nbsp;private 
    EqualConstraint constraint;<br><br>&nbsp; &nbsp;public 
    Modifier(EqualConstraint constraint,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ConstraintExpression builder)<br>&nbsp; 
    &nbsp; &nbsp;: base(constraint, builder)<br>&nbsp; &nbsp;{<br>&nbsp; &nbsp; 
    &nbsp;this.constraint = constraint;<br>&nbsp; &nbsp;}<br><br>&nbsp; 
    &nbsp;public Modifier IgnoreCase<br>&nbsp; &nbsp;{<br>&nbsp; &nbsp; &nbsp; 
    &nbsp;get { constraint.caseInsensitive = true; return this; }<br>&nbsp; 
    &nbsp;}<br>&nbsp;}<br><br>After implementing the above, the three syntax 
    classes<br>need to be changed so our methods return 
    EqualConstraint.Modifier.<br>ConstraintFactory and Is/Has require no further 
    changes but<br>PartialConstraintExpression will now look like 
    this:<br><br>&nbsp;public EqualConstraint.Modifier EqualTo(object 
    expected)<br>&nbsp;{<br>&nbsp; &nbsp;EqualConstraint constraint = new 
    EqualConstraint(expected);<br>&nbsp; &nbsp;return new 
    EqualConstraint.Modifier(constraint,<br>this.Append(constraint));<br>&nbsp;}<br><br>That&#39;s 
    &quot;all&quot; there is to it! :-)<br><br>Charlie<br><br>Theoretical 
    PostScript:<br><br>In case you wonder Why we neeed all the 
    classes:<br><br>We want to provide a good object model, while 
    *at*the*same*time*<br>having only reasonable choices appear in the 
    intellisense. And<br>we want whatever you can compile to make sense as much 
    as<br>is possible, so that there aren&#39;t too many runtime checks.<br><br>So 
    we need separate PartialConstraintExpression and<br>ConstraintExpression 
    classes to make sure you can&#39;t<br>enter ...And.And... or ...Null.Null... and 
    similar<br>meaningless stuff.<br><br>We need Is/Has to provide static 
    methods to get the<br>expression started.<br><br>We need ConstraintFactory, 
    to supply instance methods<br>for use by those who prefer to derive test 
    classes<br>from AssertionHelper. We could eliminnate that<br>class by 
    eliminating the feature.<br><br>In particular, the Modifier classes are 
    needed because we<br>are dealing with a ConstraintExpression, but want 
    the<br>choices offered to the user to represent those provided<br>for an 
    Equal Constraint. The Modifier class ties together<br>the whole expression 
    and the &quot;leading edge&quot; constraint<br>in a way that lets us have both. If the 
    user ends the<br>expression, the Modifier&#39;s implementation of 
    IConstraint<br>is used. If the user types &quot;IgnoreCase&quot; the 
    EqualConstraint<br>is used. If the user types &quot;And&quot; or &quot;Or&quot;, that&#39;s 
    handled<br>by the ConstraintExpression.<br><br>I&#39;m working on a few 
    approaches to this extra 
    class.<br><br><br><br><br><br><br>-------------------------------------------------------------------------<br>This 
    SF.Net email is sponsored by the Moblin Your Move Developer&#39;s 
    challenge<br>Build the coolest Linux based applications with Moblin SDK 
    &amp; win great prizes<br>Grand prize is a trip for two to an Open Source 
    event anywhere in the world<br><a href="http://moblin-contest.org/redirect.php?banner_id=100&amp;url=/" target="_blank">http://moblin-contest.org/redirect.php?banner_id=100&amp;url=/</a><br>_______________________________________________<br>
Nunit-users 
    mailing list<br><a href="mailto:[email protected]" target="_blank">[email protected]</a><br><a href="https://lists.sourceforge.net/lists/listinfo/nunit-users" target="_blank">https://lists.sourceforge.net/lists/listinfo/nunit-users</a><br>
</blockquote></div><br></div></div></div></blockquote></div>
</blockquote></div><br></div></div></div>

------=_Part_70289_20180051.1220854200270--


--===============1436902837==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
--===============1436902837==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Nunit-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/nunit-users

--===============1436902837==--