<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>spec/asynchronous_spec.js</filename>
    </added>
    <added>
      <filename>spec/skipping_spec.js</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,9 +1,15 @@
+Screw.Defaults = Screw.Defaults || {};
+Screw.Defaults.to_run = 'body &gt; .describe &gt; .describes &gt; .describe';
+
 (function($) {
   $(Screw).bind('loaded', function() {
     $('.status').fn({
       display: function() {
         $(this).text(
-          $('.passed').length + $('.failed').length + ' test(s), ' + $('.failed').length + ' failure(s)'
+          $('.it.passed' ).length + $('.failed').length + $('.skipped').length + ' finished, ' +
+          $('.it.failed' ).length + ' failure(s), ' + 
+          $('.it.skipped').length + ' skipped, ' + 
+          $('.it.async'  ).length + ' running asynchronous test(s)'
         );
       }
     });
@@ -44,10 +50,12 @@
       },
       
       run: function() {
+        if ($(this).hasClass('skipped')){return}
+        
         try {
           try {
             $(this).fn('parent').fn('run_befores');
-            $(this).data('screwunit.run')();
+            $(this).data('screwunit.run')($(this));
           } finally {
             $(this).fn('parent').fn('run_afters');
           }
@@ -73,15 +81,15 @@
     });
     
     $('.before').fn({
-      run: function() { $(this).data('screwunit.run')() }
+      run: function() { $(this).data('screwunit.run')($(this)) }
     }); 
   
     $('.after').fn({
-      run: function() { $(this).data('screwunit.run')() }
+      run: function() { $(this).data('screwunit.run')($(this)) }
     });
 
     $(Screw).trigger('before');
-    var to_run = unescape(location.search.slice(1)) || 'body &gt; .describe &gt; .describes &gt; .describe';
+    var to_run = unescape(location.search.slice(1)) || Screw.Defaults.to_run;
     $(to_run)
       .focus()
       .eq(0).trigger('scroll').end()</diff>
      <filename>lib/screw.behaviors.js</filename>
    </modified>
    <modified>
      <diff>@@ -2,18 +2,70 @@ var Screw = (function($) {
   var screw = {
     Unit: function(fn) {
       var contents = fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1];
-      var fn = new Function(&quot;matchers&quot;, &quot;specifications&quot;,
-        &quot;with (specifications) { with (matchers) { &quot; + contents + &quot; } }&quot;
+      var fn = new Function(&quot;matchers&quot;, &quot;specifications&quot;, &quot;utilities&quot;,
+        &quot;with (specifications) { with (matchers) { with (utilities) {&quot; + contents + &quot; } } }&quot;
       );
 
       $(Screw).queue(function() {
         Screw.Specifications.context.push($('body &gt; .describe'));
-        fn.call(this, Screw.Matchers, Screw.Specifications);
+        fn.call(this, Screw.Matchers, Screw.Specifications, Screw.Utilities);
         Screw.Specifications.context.pop();
         $(this).dequeue();
       });
     },
 
+    Utilities: {
+      /*
+       * 'me' is $(this) being passed to the screwunit.run function (see screw.behaviors.js)
+       *   $(this).data('screwunit.run')($(this));
+       */
+       
+      skip: function(me){
+        return {
+          because: function(reason) {
+            me.trigger('skipped', [reason]);
+            throw '';
+          }
+        }
+      },
+      
+      using: function( me ) {
+        return {
+          wait : function( seconds ) {
+            return {
+              and_then: function( fn ) {
+                var f = function() {
+                  var async_count = me.data('async_waiting_count') - 1;
+                  me.data('async_waiting_count', async_count);
+                  if (async_count &lt; 1) {
+                    me.removeClass('async');
+                  }
+
+                  try {
+                    fn(me);
+                  } catch (e) {
+                    me.trigger('failed', [e]);
+                    return;
+                  }
+                  me.trigger('passed');
+                };
+
+                var async_count = me.data('async_waiting_count') ||  0
+                me.data('async_waiting_count', async_count + 1)
+
+                me.addClass('async');
+
+                // allow the &quot;it&quot; we are called from to finish, which will add class &quot;passed&quot;, which we want to remove.
+                setTimeout(function(){ me.trigger('running'); }, 2);
+
+                setTimeout(f, 1000 * parseInt(seconds,10));
+              } 
+            }
+          }
+        }  
+      }
+    },
+
     Specifications: {
       context: [],
 </diff>
      <filename>lib/screw.builder.js</filename>
    </modified>
    <modified>
      <diff>@@ -87,4 +87,16 @@ html {
             cursor: pointer;
             color: #000 !important;
             border-bottom: 1px solid #9A8E51;
-          }
\ No newline at end of file
+          }
+          
+          
+          .describes .describe .its .it.skipped h2 {
+            background-color: #8DEEEE;
+            color: #000000 !important;
+          }
+
+          .describes .describe .its .it.skipped p {
+            margin-left: 1em;
+            color: #000000;
+          }
+          
\ No newline at end of file</diff>
      <filename>lib/screw.css</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,9 @@
           return $(this).addClass('focused');
         })
         .bind('scroll', function() {
-          document.body.scrollTop = $(this).offset().top;
+          var sel = $(this).fn('selector');
+          var use_browser_top = $.inArray(sel, [ Screw.Defaults.to_run + ':eq(0)', 'body &gt; .describe']) &gt;= 0;
+          document.body.scrollTop = use_browser_top ? 0 : $(this).offset().top;
         });
 
       $('.it')
@@ -18,25 +20,52 @@
           $(this).addClass('enqueued');
         })
         .bind('running', function() {
-          $(this).addClass('running');
+          $(this)
+            .addClass('running')
+            .removeClass('failed')
+            .removeClass('passed');
         })
         .bind('passed', function() {
-          $(this).addClass('passed');
+          if ($(this).hasClass('skipped')){return}
+          $(this)
+            .addClass('passed')
+            .removeClass('failed');
+          $('.status').fn('display');
         })
         .bind('failed', function(e, reason) {
+          if ($(this).hasClass('skipped')){return}          
+          reason = reason || '';
           $(this)
             .addClass('failed')
+            .removeClass('passed')
             .append($('&lt;p class=&quot;error&quot;&gt;&lt;/p&gt;').text(reason.toString()));
+          $('.status').fn('display');
           if (reason.fileName || reason.lineNumber) {
             $(this)
               .append($('&lt;p class=&quot;error&quot;&gt;&lt;/p&gt;').text(reason.fileName + &quot; : &quot; + reason.lineNumber));
           }
         })
+        .bind('skipped', function(e, reason) {
+          $(this)
+            .removeClass('failed')
+            .removeClass('passed')
+            .addClass('skipped')
+            .append($('&lt;p class=&quot;skip_reason&quot;&gt;&lt;/p&gt;').text(&quot;Skipped because: &quot; + reason.toString()));
+          $('.status').fn('display');
+        });
+        
+      $('.before')
+        .bind('skipped', function(e, reason){
+          if ($(this).hasClass('skipped')){ return }
+          $(this)
+            .addClass('skipped')
+            .append($('&lt;p class=&quot;skip_reason&quot;&gt;&lt;/p&gt;').text(&quot;Group Skipped because: &quot; + reason.toString()));
+          $('.it', $(this).parent().parent().get(0))
+            .addClass('skipped');
+          $('.status').fn('display');
+        });
     })
     .bind('before', function() {
-      $('.status').text('Running...');
-    })
-    .bind('after', function() {
-      $('.status').fn('display')
+      $('.status').text('Starting...');
     })
 })(jQuery);
\ No newline at end of file</diff>
      <filename>lib/screw.events.js</filename>
    </modified>
    <modified>
      <diff>@@ -5,6 +5,23 @@ Screw.Unit(function() {
   
   describe('Behaviors', function() {
     describe('#run', function() {
+      describe(&quot;A describe block with exceptions&quot;, function() {
+        var after_invoked = false;
+        after(function() {
+          after_invoked = true;
+        });
+        
+        describe(&quot;an exception in a test&quot;, function() {
+          it(&quot;fails because it throws an exception.  This is the only test that should fail&quot;, function() {
+            throw('an exception');
+          });
+          
+          it(&quot;invokes [after]s even if the previous [it] raised an exception&quot;, function() {
+            expect(after_invoked).to(equal, true);
+          });
+        });
+      });
+      
       describe(&quot;a simple [describe]&quot;, function() {
         it(&quot;invokes the global [before] before an [it]&quot;, function() {
           expect(global_before_invoked).to(equal, true);
@@ -138,23 +155,6 @@ Screw.Unit(function() {
           });
         });
       });
-
-      describe(&quot;A describe block with exceptions&quot;, function() {
-        var after_invoked = false;
-        after(function() {
-          after_invoked = true;
-        });
-        
-        describe(&quot;an exception in a test&quot;, function() {
-          it(&quot;fails because it throws an exception&quot;, function() {
-            throw('an exception');
-          });
-          
-          it(&quot;invokes [after]s even if the previous [it] raised an exception&quot;, function() {
-            expect(after_invoked).to(equal, true);
-          });
-        });
-      });
     });
 
     describe(&quot;#selector&quot;, function() {</diff>
      <filename>spec/behaviors_spec.js</filename>
    </modified>
    <modified>
      <diff>@@ -64,7 +64,8 @@ Screw.Unit(function() {
             expect(raised).to(be_true);
         });
         
-        it(&quot;(will fail without prototype) should do responseJSON when the response is JSON&quot;, function () {
+        it(&quot;should do responseJSON when the response is JSON if Prototype is included&quot;, function () {
+            if (!window.Prototype){return}
             TH.Ajax.mock(&quot;/a_url&quot;, &quot;{'foo': 'bar'}&quot;, 200);
             var ajx = new Ajax.Request(&quot;/a_url&quot;, {
                 onComplete: function (resp) { response = resp }</diff>
      <filename>spec/mock_spec.js</filename>
    </modified>
    <modified>
      <diff>@@ -14,6 +14,8 @@
     &lt;script src=&quot;matchers_spec.js&quot;&gt;&lt;/script&gt;
     &lt;script src=&quot;print_spec.js&quot;&gt;&lt;/script&gt;
     &lt;script src=&quot;mock_spec.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;asynchronous_spec.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;skipping_spec.js&quot;&gt;&lt;/script&gt;
 
     &lt;link rel=&quot;stylesheet&quot; href=&quot;../lib/screw.css&quot;&gt;
   &lt;/head&gt;</diff>
      <filename>spec/suite.html</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>ff725f34ec1e2f854e9f894a3697a9385d7e7b94</id>
    </parent>
    <parent>
      <id>321ddcbcbf1c83f08fd4d4359821aee519a230f8</id>
    </parent>
  </parents>
  <author>
    <name>topper</name>
    <email>topper@toppingdesign.com</email>
  </author>
  <url>http://github.com/tobowers/screw-unit/commit/88fc8bb3b2b0c5e5509f37a5d68c7fe7955a2b7b</url>
  <id>88fc8bb3b2b0c5e5509f37a5d68c7fe7955a2b7b</id>
  <committed-date>2008-09-18T07:19:27-07:00</committed-date>
  <authored-date>2008-09-18T07:19:27-07:00</authored-date>
  <message>Merge branch 'merge_branch'</message>
  <tree>ff6a56ac859be1557401eafed0d800fbab280de4</tree>
  <committer>
    <name>topper</name>
    <email>topper@toppingdesign.com</email>
  </committer>
</commit>
