<html>
<head>
  <title>Assertive Expressive</title>

  <style>
    #container{ margin: 0 auto; width: 800px; }

    /* Debug borders */
    /* p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 { border: 1px solid red; } */

    body { font-size: 16px; line-height: 20px; margin: 1em 5% 1em 5%; font-family: Verdana, Arial, Helvetica, sans-serif; }
    a { color: #336; text-decoration: underline; }
    a:visited { color: #334; }
    em { font-style: italic; }
    strong { font-weight: bold; }
    tt { color: navy; }

    h1, h2, h3, h4, h5, h6 { color: #223; margin-top: 1.2em; margin-bottom: 0.5em; line-height: 1.3; }
    h1 { border-bottom: 2px solid silver; }
    h2 { border-bottom: 2px solid silver; padding-top: 0.5em; }

    hr { border: 1px solid silver; }

    p { color: #222; text-align: justify; margin-top: 0.5em; margin-bottom: 0.5em; line-height: 1.4em; }

    pre { padding: 10; margin: 0; font-family: monospace; font-size: 0.9em; }
    pre.pass { color: green; }
    pre.fail { color: red; }
    pre.error { color: red; font-weight: bold; }

    span#author { color: #527bbd; font-weight: bold; font-size: 1.1em; }
    span#email { }
    span#revision { }

    div#footer { font-size: small; border-top: 2px solid silver; padding-top: 0.5em; margin-top: 4.0em; }
    div#footer-text { float: left; padding-bottom: 0.5em; }
    div#footer-badges { float: right; padding-bottom: 0.5em; }

    /* Block element content. */
    div.content { padding: 0; }

    /* Block element titles. */
    h1.title { font-weight: bold; text-align: left; font-size: 3em; margin-top: 1.0em; margin-bottom: 0.5em; }

    /* Block element titles. */
    div.title, caption.title { font-weight: bold; text-align: left; margin-top: 1.0em; margin-bottom: 0.5em; }
    div.title + * { margin-top: 0; }
    td div.title:first-child { margin-top: 0.0em; }
    div.content div.title:first-child { margin-top: 0.0em; }
    div.content + div.title { margin-top: 0.0em; }
    div.sidebarblock > div.content { background: #ffffee; border: 1px solid silver; padding: 0.5em; }

    img { border-style: none; }

    dl { margin-top: 0.8em; margin-bottom: 0.8em; }
    dt { margin-top: 0.5em; margin-bottom: 0; font-style: italic; }
    dd > *:first-child { margin-top: 0; }
    ul, ol { list-style-position: outside; }

    thead { font-weight: bold; }
    tfoot { font-weight: bold; }
  </style>

  <!-- TODO: only include if these files exists -->
  <link href="../assets/styles/spec.css" type="text/css" rel="stylesheet">
  <!-- spec.css might be a problem with clobber -->
  <link href="spec.css" type="text/css" rel="stylesheet">

  

  <!-- JQuery is needed -->
  <script src="jquery.js" type="text/javascript" language="javascript"></script>

</head>

<body>

  <!-- Side Table of Contents -->
  <div id="sidebar" style="position: fixed; top: 10; right: 10; background: white;">
    <a href="javascript: toc_toggle();">
      <img src="img/icon/book.jpg" height="30px;" style="border: none;" alt="TOC" align="right"/>
    </a>

    <div id="toc_side" class="toc">
    </div>
  </div>

  <div id="container">
    <div id="header">
      <img src="img/icon/book.jpg" align="left" style="padding-right: 10px;" alt=""/>

      <h1 class="title">Assertive Expressive</h1>

      <h1>Table of Contents</h1>

      <div class="toc">
      </div>
    </div>

    <div id="content">
      <h1>Introduction</h1>
<p>
AE is an assertions framework for Ruby. It&#8217;s designed around the
concept of an Assertor. The Assertor is an Assertion Functor, or
Higher-Order Function, which reroutes method calls while monitoring them
for failing conditions.
</p>
<h2>What&#8217;s Provided</h2>
<p>
Requiring the AE library.
</p>
<pre>
  require 'ae'
</pre>
<p>
Loads two classes, <tt>Assertion</tt> and <tt>Assertor</tt>, the Kernel
method <tt>assert</tt> and it&#8217;s ancillaries +assert!+ and
<tt>refute</tt> and a set of core extensions that make writing certain
types of assertions easier.
</p>
<h2>Assertion and Assertor Classes</h2>
<p>
The <tt>Assertion</tt> class is a subclass of <tt>Exception</tt>. It is the
error raised when an assertion fails.
</p>
<p>
The <tt>Assertion</tt> class is at the heart of AE. All other AE method
resolve by&#8230; The <tt>Assertion</tt> class is at subclass of Exception.
When an assertion is made, and fails, it is an instance of Assertion that
is raised.
</p>
<pre>
  Assertion.assert.raised? do
    msg = &quot;my failure message&quot;
    assert false, msg
  end
</pre>
<p>
Like any raised exception, the last Assertion message is available via
+$!+.
</p>
<p>
(FYI, in Test::Unit the equivalent class was called AssertionFailureError.
AE has adopted the shortened term for my fingers sake ;) Also, recently it
was discoverd to be the choosen term in minitest &#8212;proving good ideas
find their way to the top.)
</p>
<p>
Assertions themsevles are not generally used in creating tests or behavior
specifications. Rather they are used to create additonal types of assertion
methods.
</p>
<p>
As mentioned above the <tt>Assertor</tt> class is a type of Functor, or
Higher-Order function, which intercedes with a normal message invocation to
monitor for failed conditions, upon which is raises Assertion exceptions.
</p>
<h2>Assertion Methods</h2>
<p>
The three methods, <tt>assert</tt>, +assert!+ and <tt>refute</tt> all
return an Assertor instance when used fluidly, i.e. magic-dot notation,
higher-order notation, functor notation, whatever you prefer to call it.
</p>
<pre>
  assert(Assertor === assert)
</pre>
<p>
This allows us to write statements like:
</p>
<pre>
  1.assert == 1
</pre>
<p>
If the operation evaluates to false or nil, then an Assertion error is
raised.
</p>
<pre>
  Assertion.assert.raised? do
    1.assert == 2
  end
</pre>
<p>
The methods +assert!+ and <tt>refute</tt> are just like <tt>assert</tt>
expect they purport the negative condition. Patterned after Ruby&#8217;s
own use of +!+ as meaning <tt>not</tt>, +assert!+ should be read
&quot;assert not&quot;. While <tt>refute</tt> exists for the sake of those
that find the use of a &quot;bang method&quot; for this purpose unsuited to
them.
</p>
<h2>How It All Works</h2>
<p>
An Assertor essentially sits in wait for a method call (via
method_missing). When that happens it applies the method to the original
receiver, but wrapped in a clause that raises an Assertion should the
statement fail. If we wanted to be pedantic, we could write our assertions
like:
</p>
<pre>
  raise Assertion.new(&quot;1 != 1&quot;) unless 1 == 1
</pre>
<p>
Instead of
</p>
<pre>
  1.assert == 1
</pre>
<p>
Obviously using Assertor methods are whole lot more concise.
</p>


<h1>Assert Method</h1>
<h2>Compatible with Test::Unit</h2>
<p>
The +#assert+ method is designed to be backward compatible with the same
method in +Test::Unit+.
</p>
<p>
Using an argument, #assert will check that an argument evaluates to true.
Optionally one can send along a meaningful message should the assertion
fail.
</p>
<pre>
  assert(true, &quot;Not true!&quot;)

  Assertion.assert.raised? do
    assert(false, &quot;Not true!&quot;)
  end
</pre>
<h2>Assert with a Block</h2>
<p>
In addition #assert has been extended to accept a block. Like the case of
the argument, the block is expected to return something that evaluates as
true.
</p>
<pre>
  assert do
    true
  end

  Assertion.assert.raised? do
    assert do
      false
    end
  end
</pre>
<p>
We should also mention that, while probably not very useful, since the
arity of a block can be checked, one can also pass the receiver into the
block as a block argument.
</p>
<pre>
  &quot;hi&quot;.assert do |s|
    /h/ =~ s
  end
</pre>
<h2>Antonyms for Assert</h2>
<p>
We can state the opposite assertion using #assert!
</p>
<pre>
  10.assert! == 9
</pre>
<p>
Or, because some people do not like the use of a bang method, +#refute+.
</p>
<pre>
  10.refute == 9
</pre>
<p>
These terms can be used just as #assert is used in all examples, but with
the opposite inference.
</p>
<p>
Another way to get the opposite inference, is to use #not.
</p>
<pre>
  10.assert.not == 9
</pre>
<h2>Identity Assertions</h2>
<p>
Rather then the general form:
</p>
<pre>
  x = 10
  x.assert.object_id == x.object_id
</pre>
<p>
We can use Ruby&#8217;s own +equal?+ method.
</p>
<pre>
  x.assert.equal?(x)
</pre>
<p>
AE provides +identical?+ method as an alternative to make it a bit more
clear.
</p>
<pre>
  x.assert.identical?(x)
</pre>
<h2>Equality Assertions</h2>
<p>
The most common assertion is that of value equality (+==_), as we have seen
throughout this document. But other forms of equality can be verified as
easily. We have already mentioned identity. In addition there is *Type
Equality*.
</p>
<pre>
  17.assert.eql? 17

  Assertion.assert.raised? do
    17.assert.eql? 17.0
  end
</pre>
<p>
And there is *Case Equality*.
</p>
<pre>
  Numeric.assert === 3
</pre>
<h2>Checking Equality with a Block</h2>
<p>
Because operators can not take blocks, and at times blocks can be
convenient means of supplying a value to an assertion, AE has defined
alternate renditions of the equality methods. For equal? and eql?, the
method name remains the same, they simply can take a block instead of
argument if need be.
</p>
<p>
For *Value Equality*, +==+, the method is called +eq?+.
</p>
<pre>
  10.assert.eq? do
    10.0
  end
</pre>
<p>
And should it fail&#8230;
</p>
<pre>
  Assertion.assert.raised? do
    10.assert.eq? do
      20
    end
  end
</pre>
<p>
For *Case Equality, +===+, it is +case?+.
</p>
<pre>
  Numeric.assert.case? do
    &quot;3&quot;.to_i
  end

  Assertion.assert.raised? do
    Numeric.assert.case? do
      &quot;3&quot;
    end
  end
</pre>
<h2>Exception Assertions</h2>
<p>
Validating errors is easy too, as has already been shown in the document to
verify assertion failures.
</p>
<pre>
  StandardError.assert.raised? do
    unknown_method
  end
</pre>
<h2>Assertions on Object State</h2>
<p>
While testing or specifying the internal state of an object is generally
considered poor form, there are times when it is necessay. Assert combined
with <tt>instance_eval</tt> makes it easy too.
</p>
<pre>
  class X
    attr :a
    def initialize(a); @a = a; end
  end

  x = X.new(1)

  x.assert.instance_eval do
    @a == 1
  end
</pre>
<h2>Catch/Try Assertions</h2>
<p>
Catch/Try throws can be tested via +Symbol#thrown?+.
</p>
<pre>
  :hookme.assert.thrown? do
    throw :hookme
  end
</pre>
<p>
Alternatively, a lambda containing the potential throw can be the receiver
using +throws?+.
</p>
<pre>
  hook = lambda{ throw :hookme }

  hook.assert.throws?(:hookme)
</pre>
<h2>Assertions on Proc Changes</h2>
<p>
I have to admit I&#8217;m not sure how this is useful, but I found it in
the Bacon API and ported it over just for sake of thoroughness.
</p>
<pre>
  a = 0

  l = lambda{ a }

  l.assert.change?{ a +=1 }
</pre>
<h2>Assertion on literal True, False and Nil</h2>
<p>
Ruby already provides the #nil? method.
</p>
<pre>
  nil.assert.nil?
</pre>
<p>
AE add true? and false? which acts accordingly.
</p>
<pre>
  true.assert.true?
  false.assert.false?
</pre>
<h2>Send Assertions</h2>
<p>
Assert that a method can be successfully called.
</p>
<pre>
  &quot;STRING&quot;.assert.send?(:upcase)
</pre>
<h2>Numeric Delta and Epsilon</h2>
<p>
You may wish to assert that a numeric value is with some range.
</p>
<pre>
  3.in_delta?(1,5)
</pre>
<p>
Or minimum range.
</p>
<pre>
  3.in_epsilon?(3,5)
</pre>
<h2>Custom Lambda Assertions</h2>
<p>
Passing a lambda to the subjunctive method, will use it as if it were a
block of the method. This allows for a simple way to quickly create
reusable assertions.
</p>
<pre>
  palindrome = lambda{ |x| x == x.reverse }

  &quot;abracarba&quot;.assert palindrome
</pre>
<p>
QED.
</p>

<h1>Subjunctives</h1>
<p>
Okay. I can hear the BDDers rumbling, &quot;where&#8217;s the
&#8216;should&#8217;?&quot; Well, AE has nothing against
&#8216;should&#8217;, but there are different approaches for utilizing
should nomenclature in specifications, and AE wants to be open to these
techniques. One of which it the way Shoulda (http://shoulda.rubyforge.org)
utilizes <tt>should</tt> in a way analogous to RSpec&#8217;s use of
<tt>it</tt>.
</p>
<p>
Even so, AE provides a an optional mixin called Subjunctive which can be
used to create assertor methods using English subjunctive terms such as
<tt>should</tt> (or <tt>must</tt>, <tt>shall</tt> and <tt>will</tt>.
Whatever you like.) To load this library use:
</p>
<pre>
  require 'ae/subjunctive'
</pre>
<p>
Then all that is required it to define your subjunctive method for all
objects. For example:
</p>
<pre>
  def will(*args, &amp;block)
    Assertor.new(self, :backtrace=&gt;caller).be(*args,&amp;block)
  end
</pre>
<p>
It&#8217;s that easy. Because of their popularity AE provides two such
terms, <tt>should</tt> and <tt>must</tt> as optional add-ons.
</p>
<pre>
  require 'ae/subjunctive/should'
  require 'ae/subjunctive/must'
</pre>
<p>
We will use these two methods interchangeable for the rest of this
demonstration, but to be clear they both work exactly the same way, and
almost exactly like #assert.
</p>
<p>
Keep in mind, AE &quot;conical&quot; functionality does not entail
subjunctive forms, or <tt>should</tt> or <tt>must</tt> assertor methods.
These are simply options you can load via your test_helper.rb, or similar
script, if you prefer or need to support these nomenclatures.
</p>
<h2>Fluent Notation and Antonyms</h2>
<p>
Like <tt>assert</tt>, <tt>should</tt> and <tt>must</tt> can be used as a
higher order function.
</p>
<pre>
  4.should == 4
  4.must   == 4
</pre>
<p>
With the antonym of +should!+ (read as &quot;should not&quot;) or
<tt>shouldnt</tt>, and for <tt>must</tt>, +must!+ or <tt>wont</tt>.
</p>
<pre>
  4.should!  == 5
  4.shouldnt == 5

  4.must! == 5
  4.wont  == 5
</pre>
<h2>To Be</h2>
<p>
On occasions where the English readability of a specification is hindered,
<tt>be</tt> can be used.
</p>
<pre>
  StandardError.must.be.raised? do
    unknown_method
  end
</pre>
<p>
The <tt>be</tt> method is the same as <tt>assert</tt> with the single
exception that it will compare a lone argument to the receiver using
+equate?+, unlike <tt>assert</tt> which simply check to see that the
argument evalutates as true.
</p>
<pre>
  10.should.be 10
  10.should.be 10.0
  10.should.be Numeric
</pre>
<h2>Indefinite Articles</h2>
<p>
Addtional anglogic forms are &#8216;a&#8217; and &#8216;an&#8217;,
equivalent to &#8216;be&#8217; except that they use +case?+ instead of
+equate?+,
</p>
<pre>
  &quot;hi&quot;.must.be.a String
</pre>
<p>
Otherwise they are interchangeble.
</p>
<pre>
  &quot;hi&quot;.must.be.an.instance_of?(String)
</pre>
<p>
The indefinite articles work well when a noun follow as an arguments.
</p>
<pre>
  palindrome = lambda{ |x| x == x.reverse }

  &quot;abracarba&quot;.must.be.a palindrome
</pre>
<h2>Verifying Object State</h2>
<p>
The block notation of the subjunctive form is similar to <tt>assert</tt>,
with the important exception that the block is is evaluated in the scope of
the receiver via #instance_eval, if no block parameter is designated. This
can be also be used to test the state of an object.
</p>
<pre>
  class X
    attr :a
    def initialize(a); @a = a; end
  end

  x = X.new(4)

  x.must do
    4 == @a
  end
</pre>
<p>
And should it fail&#8230;
</p>
<pre>
  Assertion.assert.raised? do
    x.must do
      5 == @a
    end
  end
</pre>
<p>
For some this might seem controversial &#8212;to test underlying
implementation. And you will get no argument here, it should be used
thoughtfully, but there are occasions when such validations are necessary.
</p>
<p>
QED.
</p>


    </div>
  </div>

</body>

</html>

<script src="../assets/scripts/spec.js" type="text/javascript" language="javascript"></script>

<script type="text/javascript" language="javascript">
  /*****************************************************************
   * $.toc()
   * by rebecca murphey
   * rmurphey gmail com
   *
   * This function is called on its own and takes as an argument
   * a list of selectors with which it will build a table of
   * contents. 
   *
   * The first selector will make up the top level of the TOC;
   * the second selector will make up the second level of the TOC;
   * etc.
   *
   * This function returns a div containing nested unordered lists;
   * each list item is linked to an anchor tag added before the item
   * on the page.
   *
   * usage: $.toc('h1,h2,h3').prependTo('body');
   ************************************************************************/
  (function($) { 
    $.toc = function(tocList) {
      $(tocList).addClass('jquery-toc');
      var tocListArray = tocList.split(',');
      $.each(tocListArray, function(i,v) { tocListArray[i] = $.trim(v); });
      var $elements = $('.jquery-toc');
      $('body').append('<div></div>');
      var $toc = $('body div:last');
      var lastLevel = 1;
      $toc.append('<ul class="jquery-toc-1"></ul>');
      $elements.each(function() {
        var $e = $(this);
        var text = $e.text();
        var anchor = text.replace(/ /g,'-');
        $e.before('<a name="' + anchor + '"></a>');
        var level;
        $.each(tocListArray, function(i,v) { 
          if (v.match(' ')) {
            var vArray = v.split(' '); 
            var e = vArray[vArray.length - 1];
          } else { e = v; }
          if ($e.is(e)) { level = i+1; } 
        });
        var className = 'jquery-toc-' + level;
        var li = '<li><a href="#' + anchor + '">' + text + '</a></li>';
        if (level == lastLevel) {
          $('ul.' + className + ':last',$toc).append(li);
        } else if (level > lastLevel) {
          var parentLevel = level - 1;
          var parentClassName = 'jquery-toc-' + parentLevel;
          $('ul.' + parentClassName + ':last',$toc).
            append('<ul class="' + className + '"></ul>');
          $('ul.' + className + ':last',$toc).append(li);
        } else if (level < lastLevel) {
          $('ul.' + className + ':last',$toc).append(li);
        }
        lastLevel = level;
      });
      var $toc_ul = $('ul.jquery-toc-1',$toc);
      $toc.remove();
      return($toc_ul);
   }
  })(jQuery);
</script>

<script>
  function toc_toggle() {
    $('#toc_side').toggle();
    $("pre").addClass("pass");
    $("pre:contains('FAIL:')").addClass("fail");
    $("pre:contains('ERROR:')").addClass("error");
  };

  $.toc('#content h1,h2,h3,h4').appendTo('.toc');

  toc_toggle();
</script>