
// JSpec - Core - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)

;(function(){

  JSpec = {
    version   : '3.3.2',
    assert    : true,
    cache     : {},
    suites    : [],
    modules   : [],
    allSuites : [],
    matchers  : {},
    stubbed   : [],
    options   : {},
    request   : 'XMLHttpRequest' in this ? XMLHttpRequest : null,
    stats     : { specs: 0, assertions: 0, failures: 0, passes: 0, specsFinished: 0, suitesFinished: 0 },

    /**
     * Default context in which bodies are evaluated.
     *
     * Replace context simply by setting JSpec.context
     * to your own like below:
     *
     * JSpec.context = { foo : 'bar' }
     *
     * Contexts can be changed within any body, this can be useful
     * in order to provide specific helper methods to specific suites.
     *
     * To reset (usually in after hook) simply set to null like below:
     *
     * JSpec.context = null
     *
     */

     defaultContext : {
      
      /**
       * Return an object used for proxy assertions. 
       * This object is used to indicate that an object
       * should be an instance of _object_, not the constructor
       * itself.
       *
       * @param  {function} constructor
       * @return {hash}
       * @api public
       */
      
      an_instance_of : function(constructor) {
        return { an_instance_of : constructor }
      },
      
      /**
       * Load fixture at _path_.
       *
       * Fixtures are resolved as:
       *
       *  - <path>
       *  - <path>.html
       *
       * @param  {string} path
       * @return {string}
       * @api public
       */
      
      fixture : function(path) {
        if (JSpec.cache[path]) return JSpec.cache[path]
        return JSpec.cache[path] = 
          JSpec.tryLoading(JSpec.options.fixturePath + '/' + path) ||
          JSpec.tryLoading(JSpec.options.fixturePath + '/' + path + '.html')
      }
    },

    // --- Objects
    
    reporters : {
      
      /**
       * Report to server.
       * 
       * Options:
       *  - uri           specific uri to report to.
       *  - verbose       weither or not to output messages
       *  - failuresOnly  output failure messages only
       *
       * @api public
       */
      
      Server : function(results, options) {
        var uri = options.uri || window.location.protocol + "//" + window.location.host + '/results'
        JSpec.post(uri, {
          stats: JSpec.stats,
          options: options,
          results: map(results.allSuites, function(suite) {
            if (suite.hasSpecs())
              return {
                description: suite.description,
                specs: map(suite.specs, function(spec) {
                  return {
                    description: spec.description,
                    message: !spec.passed() ? spec.failure().message : null,
                    status: spec.requiresImplementation() ? 'pending' :
                              spec.passed() ? 'pass' :
                                'fail',
                    assertions: map(spec.assertions, function(assertion){
                      return {
                        passed: assertion.passed  
                      }
                    })
                  }
                })
              }
          })
        })
  			if ('close' in main) main.close()
      },

      /**
       * Default reporter, outputting to the DOM.
       *
       * Options:
       *   - reportToId    id of element to output reports to, defaults to 'jspec'
       *   - failuresOnly  displays only suites with failing specs
       *
       * @api public
       */

      DOM : function(results, options) {
        var id = option('reportToId') || 'jspec',
            report = document.getElementById(id),
            failuresOnly = option('failuresOnly'),
            classes = results.stats.failures ? 'has-failures' : ''
        if (!report) throw 'JSpec requires the element #' + id + ' to output its reports'
        
        function bodyContents(body) {
          return JSpec.
            escape(JSpec.contentsOf(body)).
            replace(/^ */gm, function(a){ return (new Array(Math.round(a.length / 3))).join(' ') }).
            replace(/\r\n|\r|\n/gm, '<br/>')
        }
        
        report.innerHTML = '<div id="jspec-report" class="' + classes + '"><div class="heading"> \
        <span class="passes">Passes: <em>' + results.stats.passes + '</em></span>                \
        <span class="failures">Failures: <em>' + results.stats.failures + '</em></span>          \
        <span class="passes">Duration: <em>' + results.duration + '</em> ms</span>          \
        </div><table class="suites">' + map(results.allSuites, function(suite) {
          var displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran
          if (displaySuite && suite.hasSpecs())
            return '<tr class="description"><td colspan="2">' + escape(suite.description) + '</td></tr>' +
              map(suite.specs, function(i, spec) {
                return '<tr class="' + (i % 2 ? 'odd' : 'even') + '">' +
                  (spec.requiresImplementation() ?
                    '<td class="requires-implementation" colspan="2">' + escape(spec.description) + '</td>' :
                      (spec.passed() && !failuresOnly) ?
                        '<td class="pass">' + escape(spec.description)+ '</td><td>' + spec.assertionsGraph() + '</td>' :
                          !spec.passed() ?
                            '<td class="fail">' + escape(spec.description) + 
  													map(spec.failures(), function(a){ return '<em>' + escape(a.message) + '</em>' }).join('') +
 														'</td><td>' + spec.assertionsGraph() + '</td>' :
                              '') +
                  '<tr class="body"><td colspan="2"><pre>' + bodyContents(spec.body) + '</pre></td></tr>'
              }).join('') + '</tr>'
        }).join('') + '</table></div>'
      },
      
      /**
       * Terminal reporter.
       *
       * @api public
       */
       
       Terminal : function(results, options) {
         var failuresOnly = option('failuresOnly')
         print(color("\n Passes: ", 'bold') + color(results.stats.passes, 'green') + 
               color(" Failures: ", 'bold') + color(results.stats.failures, 'red') +
               color(" Duration: ", 'bold') + color(results.duration, 'green') + " ms \n")
              
         function indent(string) {
           return string.replace(/^(.)/gm, '  $1')
         }
         
         each(results.allSuites, function(suite) {
           var displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran
            if (displaySuite && suite.hasSpecs()) {
              print(color(' ' + suite.description, 'bold'))
              each(suite.specs, function(spec){
                var assertionsGraph = inject(spec.assertions, '', function(graph, assertion){
                  return graph + color('.', assertion.passed ? 'green' : 'red')
                })
                if (spec.requiresImplementation())
                  print(color('  ' + spec.description, 'blue') + assertionsGraph)
                else if (spec.passed() && !failuresOnly)
                  print(color('  ' + spec.description, 'green') + assertionsGraph)
                else if (!spec.passed())
                  print(color('  ' + spec.description, 'red') + assertionsGraph + 
                        "\n" + indent(map(spec.failures(), function(a){ return a.message }).join("\n")) + "\n")
              })
              print("")
            }
         })
         
         quit(results.stats.failures)
       }
    },
    
    Assertion : function(matcher, actual, expected, negate) {
      extend(this, {
        message: '',
        passed: false,
        actual: actual,
        negate: negate,
        matcher: matcher,
        expected: expected,
        
        // Report assertion results
        
        report : function() {
          if (JSpec.assert) 
            this.passed ? JSpec.stats.passes++ : JSpec.stats.failures++
          return this
        },
        
        // Run the assertion
        
        run : function() {
          // TODO: remove unshifting 
          expected.unshift(actual)
          this.result = matcher.match.apply(this, expected)
          this.passed = negate ? !this.result : this.result
          if (!this.passed) this.message = matcher.message.call(this, actual, expected, negate, matcher.name)
          return this
        }
      })
    },
    
    ProxyAssertion : function(object, method, times, negate) {
      var self = this
      var old = object[method]
      
      // Proxy
      
      object[method] = function(){
        args = toArray(arguments)
        result = old.apply(object, args)
        self.calls.push({ args : args, result : result })
        return result
      }
      
      // Times
      
      this.times = {
        once  : 1,
        twice : 2
      }[times] || times || 1
      
      extend(this, {
        calls: [],
        message: '',
        defer: true,
        passed: false,
        negate: negate,
        object: object,
        method: method,
        
        // Proxy return value
        
        and_return : function(result) {
          this.expectedResult = result
          return this
        },
        
        // Proxy arguments passed
        
        with_args : function() {
          this.expectedArgs = toArray(arguments)
          return this
        },
        
        // Check if any calls have failing results
        
        anyResultsFail : function() {
          return any(this.calls, function(call){
            return self.expectedResult.an_instance_of ?
                     call.result.constructor != self.expectedResult.an_instance_of:
                       !equal(self.expectedResult, call.result)
          })
        },
        
        // Check if any calls have passing results
        
        anyResultsPass : function() {
          return any(this.calls, function(call){
            return self.expectedResult.an_instance_of ?
                     call.result.constructor == self.expectedResult.an_instance_of:
                       equal(self.expectedResult, call.result)
          })
        },
        
        // Return the passing result
        
        passingResult : function() {
          return this.anyResultsPass().result
        },

        // Return the failing result
        
        failingResult : function() {
          return this.anyResultsFail().result
        },
        
        // Check if any arguments fail
        
        anyArgsFail : function() {
          return any(this.calls, function(call){
            return any(self.expectedArgs, function(i, arg){
              if (arg == null) return call.args[i] == null
              return arg.an_instance_of ?
                       call.args[i].constructor != arg.an_instance_of:
                         !equal(arg, call.args[i])
                       
            })
          })
        },
        
        // Check if any arguments pass
        
        anyArgsPass : function() {
          return any(this.calls, function(call){
            return any(self.expectedArgs, function(i, arg){
              return arg.an_instance_of ?
                       call.args[i].constructor == arg.an_instance_of:
                         equal(arg, call.args[i])
                       
            })
          })
        },
        
        // Return the passing args
        
        passingArgs : function() {
          return this.anyArgsPass().args
        },
                
        // Return the failing args
        
        failingArgs : function() {
          return this.anyArgsFail().args
        },
        
        // Report assertion results
        
        report : function() {
          if (JSpec.assert) 
            this.passed ? ++JSpec.stats.passes : ++JSpec.stats.failures
          return this
        },
        
        // Run the assertion
                
        run : function() {
          var methodString = 'expected ' + object.toString() + '.' + method + '()' + (negate ? ' not' : '' )
          
          function times(n) {
            return n > 2 ?  n + ' times' : { 1: 'once', 2: 'twice' }[n]
          }
          
          if (this.expectedResult != null && (negate ? this.anyResultsPass() : this.anyResultsFail()))
            this.message = methodString + ' to return ' + puts(this.expectedResult) + 
              ' but ' + (negate ? 'it did' : 'got ' + puts(this.failingResult())) 

          if (this.expectedArgs && (negate ? !this.expectedResult && this.anyArgsPass() : this.anyArgsFail()))
            this.message = methodString + ' to be called with ' + puts.apply(this, this.expectedArgs) +
             ' but was' + (negate ? '' : ' called with ' + puts.apply(this, this.failingArgs()))

          if (negate ? !this.expectedResult && !this.expectedArgs && this.calls.length >= this.times : this.calls.length != this.times)
            this.message = methodString + ' to be called ' + times(this.times) + 
            ', but ' +  (this.calls.length == 0 ? ' was not called' : ' was called ' + times(this.calls.length))
                
          if (!this.message.length) 
            this.passed = true
          
          return this
        }
      })
    },
      
    /**
     * Specification Suite block object.
     *
     * @param {string} description
     * @param {function} body
     * @api private
     */

    Suite : function(description, body) {
      var self = this
      extend(this, {
        body: body,
        description: description,
        suites: [],
        specs: [],
        ran: false,
        hooks: { 'before' : [], 'after' : [], 'before_each' : [], 'after_each' : [] },
        
        // Add a spec to the suite

        addSpec : function(description, body) {
          var spec = new JSpec.Spec(description, body)
          this.specs.push(spec)
          JSpec.stats.specs++ // TODO: abstract
          spec.suite = this
        },

        // Add a hook to the suite

        addHook : function(hook, body) {
          this.hooks[hook].push(body)
        },

        // Add a nested suite

        addSuite : function(description, body) {
          var suite = new JSpec.Suite(description, body)
          JSpec.allSuites.push(suite)
          suite.name = suite.description
          suite.description = this.description + ' ' + suite.description
          this.suites.push(suite)
          suite.suite = this
        },

        // Invoke a hook in context to this suite

        hook : function(hook) {
          if (this.suite) this.suite.hook(hook)
          each(this.hooks[hook], function(body) {
            JSpec.evalBody(body, "Error in hook '" + hook + "', suite '" + self.description + "': ")
          })
        },

        // Check if nested suites are present

        hasSuites : function() {
          return this.suites.length  
        },

        // Check if this suite has specs

        hasSpecs : function() {
          return this.specs.length
        },

        // Check if the entire suite passed

        passed : function() {
          return !any(this.specs, function(spec){
            return !spec.passed() 
          })
        }
      })
    },
    
    /**
     * Specification block object.
     *
     * @param {string} description
     * @param {function} body
     * @api private
     */

    Spec : function(description, body) {
      extend(this, {
        body: body,
        description: description,
        assertions: [],
        
        // Add passing assertion
        
        pass : function(message) {
          this.assertions.push({ passed: true, message: message })
          if (JSpec.assert) ++JSpec.stats.passes
        },
        
        // Add failing assertion
        
        fail : function(message) {
          this.assertions.push({ passed: false, message: message })
          if (JSpec.assert) ++JSpec.stats.failures
        },
                
        // Run deferred assertions
        
        runDeferredAssertions : function() {
          each(this.assertions, function(assertion){
            if (assertion.defer) assertion.run().report(), hook('afterAssertion', assertion)
          })
        },
        
        // Find first failing assertion

        failure : function() {
          return find(this.assertions, function(assertion){
            return !assertion.passed
          })
        },

        // Find all failing assertions

        failures : function() {
          return select(this.assertions, function(assertion){
            return !assertion.passed
          })
        },

        // Weither or not the spec passed

        passed : function() {
          return !this.failure()
        },

        // Weither or not the spec requires implementation (no assertions)

        requiresImplementation : function() {
          return this.assertions.length == 0
        },

        // Sprite based assertions graph

        assertionsGraph : function() {
          return map(this.assertions, function(assertion){
            return '<span class="assertion ' + (assertion.passed ? 'passed' : 'failed') + '"></span>'
          }).join('')
        }
      })
    },
    
    Module : function(methods) {
      extend(this, methods)
    },
    
    JSON : {
      
      /**
       * Generic sequences.
       */
      
      meta : {
        '\b' : '\\b',
        '\t' : '\\t',
        '\n' : '\\n',
        '\f' : '\\f',
        '\r' : '\\r',
        '"'  : '\\"',
        '\\' : '\\\\'
      },
      
      /**
       * Escapable sequences.
       */
      
      escapable : /[\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
      
      /**
       * JSON encode _object_.
       *
       * @param  {mixed} object
       * @return {string}
       * @api private
       */
       
      encode : function(object) {
        var self = this
        if (object == undefined || object == null) return 'null'
        if (object === true) return 'true'
        if (object === false) return 'false'
        switch (typeof object) {
          case 'number': return object
          case 'string': return this.escapable.test(object) ?
            '"' + object.replace(this.escapable, function (a) {
              return typeof self.meta[a] === 'string' ? self.meta[a] :
                '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4)
            }) + '"' :
            '"' + object + '"'
          case 'object':  
            if (object.constructor == Array)
              return '[' + map(object, function(val){
                return self.encode(val)
              }).join(', ') + ']'
            else if (object)
              return '{' + map(object, function(key, val){
                return self.encode(key) + ':' + self.encode(val)
              }).join(', ') + '}'
        }
        return 'null'
      }
    },
    
    // --- DSLs
    
    DSLs : {
      snake : {
        expect : function(actual){
          return JSpec.expect(actual)
        },

        describe : function(description, body) {
          return JSpec.currentSuite.addSuite(description, body)
        },

        it : function(description, body) {
          return JSpec.currentSuite.addSpec(description, body)
        },

        before : function(body) {
          return JSpec.currentSuite.addHook('before', body)
        },

        after : function(body) {
          return JSpec.currentSuite.addHook('after', body)
        },

        before_each : function(body) {
          return JSpec.currentSuite.addHook('before_each', body)
        },

        after_each : function(body) {
          return JSpec.currentSuite.addHook('after_each', body)
        },
        
        should_behave_like : function(description) {
          return JSpec.shareBehaviorsOf(description)
        }
      }
    },

    // --- Methods
    
    /**
     * Check if _value_ is 'stop'. For use as a
     * utility callback function.
     *
     * @param  {mixed} value
     * @return {bool}
     * @api public
     */
    
    haveStopped : function(value) {
      return value === 'stop'
    },
    
    /**
     * Include _object_ which may be a hash or Module instance.
     *
     * @param  {hash, Module} object
     * @return {JSpec}
     * @api public
     */
    
    include : function(object) {
      var module = object.constructor == JSpec.Module ? object : new JSpec.Module(object)
      this.modules.push(module)
      if ('init' in module) module.init()
      if ('utilities' in module) extend(this.defaultContext, module.utilities)
      if ('matchers' in module) this.addMatchers(module.matchers)
      if ('reporters' in module) extend(this.reporters, module.reporters)
      if ('DSLs' in module)
        each(module.DSLs, function(name, methods){
          JSpec.DSLs[name] = JSpec.DSLs[name] || {}
          extend(JSpec.DSLs[name], methods)
        })
      return this
    },
    
    /**
     * Add a module hook _name_, which is immediately
     * called per module with the _args_ given. An array of
     * hook return values is returned.
     *
     * @param  {name} string
     * @param  {...} args
     * @return {array}
     * @api private
     */
    
    hook : function(name, args) {
      args = toArray(arguments, 1)
      return inject(JSpec.modules, [], function(results, module){
        if (typeof module[name] == 'function')
          results.push(JSpec.evalHook(module, name, args))
      })
    },
    
    /**
     * Eval _module_ hook _name_ with _args_. Evaluates in context
     * to the module itself, JSpec, and JSpec.context.
     *
     * @param  {Module} module
     * @param  {string} name
     * @param  {array} args
     * @return {mixed}
     * @api private
     */
    
    evalHook : function(module, name, args) {
      hook('evaluatingHookBody', module, name)
      try { return module[name].apply(module, args) }
      catch(e) { error('Error in hook ' + module.name + '.' + name + ': ', e) }
    },
    
    /**
     * Same as hook() however accepts only one _arg_ which is
     * considered immutable. This function passes the arg
     * to the first module, then passes the return value of the last
     * module called, to the following module. 
     *
     * @param  {string} name
     * @param  {mixed} arg
     * @return {mixed}
     * @api private
     */
    
    hookImmutable : function(name, arg) {
      return inject(JSpec.modules, arg, function(result, module){
        if (typeof module[name] == 'function')
          return JSpec.evalHook(module, name, [result])
      })
    },
    
    /**
     * Find a suite by its description or name.
     *
     * @param  {string} description
     * @return {Suite}
     * @api private
     */
    
    findSuite : function(description) {
      return find(this.allSuites, function(suite){
        return suite.name == description || suite.description == description
      })
    },
    
    /**
     * Share behaviors (specs) of the given suite with
     * the current suite.
     *
     * @param  {string} description
     * @api public
     */
    
    shareBehaviorsOf : function(description) {
      if (suite = this.findSuite(description)) this.copySpecs(suite, this.currentSuite)
      else throw 'failed to share behaviors. ' + puts(description) + ' is not a valid Suite name'
    },
    
    /**
     * Copy specs from one suite to another. 
     *
     * @param  {Suite} fromSuite
     * @param  {Suite} toSuite
     * @api public
     */
    
    copySpecs : function(fromSuite, toSuite) {
      each(fromSuite.specs, function(spec){
        var newSpec = new Object();
        extend(newSpec, spec);
        newSpec.assertions = [];
        toSuite.specs.push(newSpec);
      })
    },
    
    /**
     * Convert arguments to an array.
     *
     * @param  {object} arguments
     * @param  {int} offset
     * @return {array}
     * @api public
     */
    
    toArray : function(arguments, offset) {
      return Array.prototype.slice.call(arguments, offset || 0)
    },
    
    /**
     * Return ANSI-escaped colored string.
     *
     * @param  {string} string
     * @param  {string} color
     * @return {string}
     * @api public
     */
    
    color : function(string, color) {
      return "\u001B[" + {
       bold    : 1,
       black   : 30,
       red     : 31,
       green   : 32,
       yellow  : 33,
       blue    : 34,
       magenta : 35,
       cyan    : 36,
       white   : 37
      }[color] + 'm' + string + "\u001B[0m"
    },
    
    /**
     * Default matcher message callback.
     *
     * @api private
     */
    
    defaultMatcherMessage : function(actual, expected, negate, name) {
      return 'expected ' + puts(actual) + ' to ' + 
               (negate ? 'not ' : '') + 
                  name.replace(/_/g, ' ') +
                    ' ' + (expected.length > 1 ?
                      puts.apply(this, expected.slice(1)) :
                        '')
    },
    
    /**
     * Normalize a matcher message.
     *
     * When no messge callback is present the defaultMatcherMessage
     * will be assigned, will suffice for most matchers.
     *
     * @param  {hash} matcher
     * @return {hash}
     * @api public
     */
    
    normalizeMatcherMessage : function(matcher) {
      if (typeof matcher.message != 'function') 
        matcher.message = this.defaultMatcherMessage
      return matcher
    },
    
    /**
     * Normalize a matcher body
     * 
     * This process allows the following conversions until
     * the matcher is in its final normalized hash state.
     *
     * - '==' becomes 'actual == expected'
     * - 'actual == expected' becomes 'return actual == expected'
     * - function(actual, expected) { return actual == expected } becomes 
     *   { match : function(actual, expected) { return actual == expected }}
     *
     * @param  {mixed} body
     * @return {hash}
     * @api public
     */
    
    normalizeMatcherBody : function(body) {
      switch (body.constructor) {
        case String:
          if (captures = body.match(/^alias (\w+)/)) return JSpec.matchers[last(captures)]
          if (body.length < 4) body = 'actual ' + body + ' expected'
          return { match: function(actual, expected) { return eval(body) }}  
          
        case Function:
          return { match: body }
          
        default:
          return body
      }
    },
    
    /**
     * Get option value. This method first checks if
     * the option key has been set via the query string,
     * otherwise returning the options hash value.
     *
     * @param  {string} key
     * @return {mixed}
     * @api public
     */
     
     option : function(key) {
       return (value = query(key)) !== null ? value :
                JSpec.options[key] || null
     },
     
     /**
      * Check if object _a_, is equal to object _b_.
      *
      * @param  {object} a
      * @param  {object} b
      * @return {bool}
      * @api private
      */
     
     equal: function(a, b) {
       if (typeof a != typeof b) return
       if (a === b) return true
       if (a instanceof RegExp)
         return a.toString() === b.toString()
       if (a instanceof Date)
         return Number(a) === Number(b)
       if (typeof a != 'object') return
       if (a.length !== undefined)
         if (a.length !== b.length) return
         else
           for (var i = 0, len = a.length; i < len; ++i)
             if (!equal(a[i], b[i]))
               return
       for (var key in a)
         if (!equal(a[key], b[key]))
           return
       return true
     },

    /**
     * Return last element of an array.
     *
     * @param  {array} array
     * @return {object}
     * @api public
     */

    last : function(array) {
      return array[array.length - 1]
    },

    /**
     * Convert object(s) to a print-friend string.
     *
     * @param  {...} object
     * @return {string}
     * @api public
     */

    puts : function(object) {
      if (arguments.length > 1)
        return map(toArray(arguments), function(arg){
          return puts(arg)
        }).join(', ')
      if (object === undefined) return 'undefined'
      if (object === null) return 'null'
      if (object === true) return 'true'
      if (object === false) return 'false'
      if (object.an_instance_of) return 'an instance of ' + object.an_instance_of.name
      if (object.jquery && object.selector.length > 0) return 'selector ' + puts(object.selector)
      if (object.jquery) return object.get(0).outerHTML
      if (object.nodeName) return object.outerHTML
      switch (object.constructor) {
        case Function: return object.name || object 
        case String: 
          return '"' + object
            .replace(/"/g,  '\\"')
            .replace(/\n/g, '\\n')
            .replace(/\t/g, '\\t')
            + '"'
        case Array: 
          return inject(object, '[', function(b, v){
            return b + ', ' + puts(v)
          }).replace('[,', '[') + ' ]'
        case Object:
          object.__hit__ = true
          return inject(object, '{', function(b, k, v) {
            if (k == '__hit__') return b
            return b + ', ' + k + ': ' + (v && v.__hit__ ? '<circular reference>' : puts(v))
          }).replace('{,', '{') + ' }'
        default: 
          return object.toString()
      }
    },

    /**
     * Escape HTML.
     *
     * @param  {string} html
     * @return {string}
     * @api public
     */

     escape : function(html) {
       return html.toString()
         .replace(/&/gmi, '&amp;')
         .replace(/"/gmi, '&quot;')
         .replace(/>/gmi, '&gt;')
         .replace(/</gmi, '&lt;')
     },
     
     /**
      * Perform an assertion without reporting.
      *
      * This method is primarily used for internal
      * matchers in order retain DRYness. May be invoked 
      * like below:
      *
      *   does('foo', 'eql', 'foo')
      *   does([1,2], 'include', 1, 2)
      *
      * External hooks are not run for internal assertions
      * performed by does().
      *
      * @param  {mixed} actual
      * @param  {string} matcher
      * @param  {...} expected
      * @return {mixed}
      * @api private
      */
     
     does : function(actual, matcher, expected) {
       var assertion = new JSpec.Assertion(JSpec.matchers[matcher], actual, toArray(arguments, 2))
       return assertion.run().result
     },

    /**
     * Perform an assertion.
     *
     *   expect(true).to('be', true)
     *   expect('foo').not_to('include', 'bar')
     *   expect([1, [2]]).to('include', 1, [2])
     *
     * @param  {mixed} actual
     * @return {hash}
     * @api public
     */

    expect : function(actual) {
      function assert(matcher, args, negate) {
        var expected = toArray(args, 1)
        matcher.negate = negate  
        assertion = new JSpec.Assertion(matcher, actual, expected, negate)
        hook('beforeAssertion', assertion)
        if (matcher.defer) assertion.run()
        else JSpec.currentSpec.assertions.push(assertion.run().report()), hook('afterAssertion', assertion)
        return assertion.result
      }
      
      function to(matcher) {
        return assert(matcher, arguments, false)
      }
      
      function not_to(matcher) {
        return assert(matcher, arguments, true)
      }
      
      return {
        to : to,
        should : to,
        not_to: not_to,
        should_not : not_to
      }
    },

    /**
     * Strim whitespace or chars.
     *
     * @param  {string} string
     * @param  {string} chars
     * @return {string}
     * @api public
     */

     strip : function(string, chars) {
       return string.
         replace(new RegExp('['  + (chars || '\\s') + ']*$'), '').
         replace(new RegExp('^[' + (chars || '\\s') + ']*'),  '')
     },
     
     /**
      * Call an iterator callback with arguments a, or b
      * depending on the arity of the callback.
      *
      * @param  {function} callback
      * @param  {mixed} a
      * @param  {mixed} b
      * @return {mixed}
      * @api private
      */
     
     callIterator : function(callback, a, b) {
       return callback.length == 1 ? callback(b) : callback(a, b)
     },
     
     /**
      * Extend an object with another.
      *
      * @param  {object} object
      * @param  {object} other
      * @api public
      */
     
     extend : function(object, other) {
       each(other, function(property, value){
         object[property] = value
       })
     },
     
     /**
      * Iterate an object, invoking the given callback.
      *
      * @param  {hash, array} object
      * @param  {function} callback
      * @return {JSpec}
      * @api public
      */

     each : function(object, callback) {
       if (object.constructor == Array)
         for (var i = 0, len = object.length; i < len; ++i)
           callIterator(callback, i, object[i])
       else
         for (var key in object) 
           if (object.hasOwnProperty(key))
             callIterator(callback, key, object[key])
     },

     /**
      * Iterate with memo.
      *
      * @param  {hash, array} object
      * @param  {object} memo
      * @param  {function} callback
      * @return {object}
      * @api public
      */

     inject : function(object, memo, callback) {
       each(object, function(key, value){
         memo = (callback.length == 2 ?
                   callback(memo, value):
                     callback(memo, key, value)) ||
                       memo
       })
       return memo
     },
     
     /**
      * Destub _object_'s _method_. When no _method_ is passed
      * all stubbed methods are destubbed. When no arguments
      * are passed every object found in JSpec.stubbed will be
      * destubbed.
      *
      * @param  {mixed} object
      * @param  {string} method
      * @api public
      */
     
     destub : function(object, method) {
       if (method) {
         if (object['__prototype__' + method])
           delete object[method]
         else
           object[method] = object['__original__' + method]
         delete object['__prototype__' + method]
         delete object['__original____' + method]
       }
       else if (object) {
         for (var key in object)
           if (captures = key.match(/^(?:__prototype__|__original__)(.*)/))
             destub(object, captures[1])
       }
       else
         while (JSpec.stubbed.length)
            destub(JSpec.stubbed.shift())
     },
     
     /**
      * Stub _object_'s _method_. 
      *
      * stub(foo, 'toString').and_return('bar')
      *
      * @param  {mixed} object
      * @param  {string} method
      * @return {hash}
      * @api public
      */
     
     stub : function(object, method) {
       hook('stubbing', object, method)
       JSpec.stubbed.push(object)
       var type = object.hasOwnProperty(method) ? '__original__' : '__prototype__'
       object[type + method] = object[method]
       object[method] = function(){}
       return {
         and_return : function(value) {
           if (typeof value == 'function') object[method] = value
           else object[method] = function(){ return value }
         }
      }
     },
     
    /**
     * Map callback return values.
     *
     * @param  {hash, array} object
     * @param  {function} callback
     * @return {array}
     * @api public
     */

    map : function(object, callback) {
      return inject(object, [], function(memo, key, value){
        memo.push(callIterator(callback, key, value))
      })
    },
    
    /**
     * Returns the first matching expression or null.
     *
     * @param  {hash, array} object
     * @param  {function} callback
     * @return {mixed}
     * @api public
     */
         
    any : function(object, callback) {
      return inject(object, null, function(state, key, value){
        if (state == undefined)
          return callIterator(callback, key, value) ? value : state
      })
    },
    
    /**
     * Returns an array of values collected when the callback
     * given evaluates to true.
     *
     * @param  {hash, array} object
     * @return {function} callback
     * @return {array}
     * @api public
     */
    
    select : function(object, callback) {
      return inject(object, [], function(selected, key, value){
        if (callIterator(callback, key, value))
          selected.push(value)
      })
    },

    /**
     * Define matchers.
     *
     * @param  {hash} matchers
     * @api public
     */

    addMatchers : function(matchers) {
      each(matchers, function(name, body){
        JSpec.addMatcher(name, body)  
      })
    },
    
    /**
     * Define a matcher.
     *
     * @param  {string} name
     * @param  {hash, function, string} body
     * @api public
     */
    
    addMatcher : function(name, body) {
      hook('addingMatcher', name, body)
      if (name.indexOf(' ') != -1) {
        var matchers = name.split(/\s+/)
        var prefix = matchers.shift()
        each(matchers, function(name) {
          JSpec.addMatcher(prefix + '_' + name, body(name))
        })
      }
      this.matchers[name] = this.normalizeMatcherMessage(this.normalizeMatcherBody(body))
      this.matchers[name].name = name
    },
    
    /**
     * Add a root suite to JSpec.
     *
     * @param  {string} description
     * @param  {body} function
     * @api public
     */
    
    describe : function(description, body) {
      var suite = new JSpec.Suite(description, body)
      hook('addingSuite', suite)
      this.allSuites.push(suite)
      this.suites.push(suite)
    },
    
    /**
     * Return the contents of a function body.
     *
     * @param  {function} body
     * @return {string}
     * @api public
     */
    
    contentsOf : function(body) {
      return body.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1]
    },

    /**
     * Evaluate a JSpec capture body.
     *
     * @param  {function} body
     * @param  {string} errorMessage (optional)
     * @return {Type}
     * @api private
     */

    evalBody : function(body, errorMessage) {
      var dsl = this.DSL || this.DSLs.snake
      var matchers = this.matchers
      var context = this.context || this.defaultContext
      var contents = this.contentsOf(body)
      hook('evaluatingBody', dsl, matchers, context, contents)
      try { with (dsl){ with (context) { with (matchers) { eval(contents) }}} }
      catch(e) { error(errorMessage, e) }
    },

    /**
     * Pre-process a string of JSpec.
     *
     * @param  {string} input
     * @return {string}
     * @api private
     */

    preprocess : function(input) {
      if (typeof input != 'string') return
      input = hookImmutable('preprocessing', input)
      return input.
        replace(/\t/g, '  ').
        replace(/\r\n|\n|\r/g, '\n').
        split('__END__')[0].
        replace(/([\w\.]+)\.(stub|destub)\((.*?)\)$/gm, '$2($1, $3)').
        replace(/describe\s+(.*?)$/gm, 'describe($1, function(){').
        replace(/^\s+it\s+(.*?)$/gm, ' it($1, function(){').
        replace(/^ *(before_each|after_each|before|after)(?= |\n|$)/gm, 'JSpec.currentSuite.addHook("$1", function(){').
        replace(/^\s*end(?=\s|$)/gm, '});').
        replace(/-\{/g, 'function(){').
        replace(/(\d+)\.\.(\d+)/g, function(_, a, b){ return range(a, b) }).
        replace(/\.should([_\.]not)?[_\.](\w+)(?: |;|$)(.*)$/gm, '.should$1_$2($3)').
        replace(/([\/\s]*)(.+?)\.(should(?:[_\.]not)?)[_\.](\w+)\((.*)\)\s*;?$/gm, '$1 expect($2).$3($4, $5)').
        replace(/, \)/g, ')').
        replace(/should\.not/g, 'should_not')
    },

    /**
     * Create a range string which can be evaluated to a native array.
     *
     * @param  {int} start
     * @param  {int} end
     * @return {string}
     * @api public
     */

    range : function(start, end) {
      var current = parseInt(start), end = parseInt(end), values = [current]
      if (end > current) while (++current <= end) values.push(current)
      else               while (--current >= end) values.push(current)
      return '[' + values + ']'
    },

    /**
     * Report on the results. 
     *
     * @api public
     */

    report : function() {
      this.duration = Number(new Date) - this.start
      hook('reporting', JSpec.options)
      new (JSpec.options.reporter || JSpec.reporters.DOM)(JSpec, JSpec.options)
    },

    /**
     * Run the spec suites. Options are merged
     * with JSpec options when present.
     *
     * @param  {hash} options
     * @return {JSpec}
     * @api public
     */

    run : function(options) {
      if (any(hook('running'), haveStopped)) return this
      if (options) extend(this.options, options)
      this.start = Number(new Date)
      each(this.suites, function(suite) { JSpec.runSuite(suite) })
      return this
    },
    
    /**
     * Run a suite.
     *
     * @param  {Suite} suite
     * @api public
     */

    runSuite : function(suite) {
      this.currentSuite = suite
      this.evalBody(suite.body)
      suite.ran = true
      hook('beforeSuite', suite), suite.hook('before')
      each(suite.specs, function(spec) {
        hook('beforeSpec', spec)
        suite.hook('before_each')
        JSpec.runSpec(spec)
        hook('afterSpec', spec)
        suite.hook('after_each')
      })
      if (suite.hasSuites()) {
        each(suite.suites, function(suite) {
          JSpec.runSuite(suite)
        })
      }
      hook('afterSuite', suite), suite.hook('after')
      this.stats.suitesFinished++
    },
         
    /**
     * Report a failure for the current spec.
     *
     * @param  {string} message
     * @api public
     */
     
     fail : function(message) {
       JSpec.currentSpec.fail(message)
     },
     
     /**
      * Report a passing assertion for the current spec.
      *
      * @param  {string} message
      * @api public
      */
      
     pass : function(message) {
       JSpec.currentSpec.pass(message)
     },

    /**
     * Run a spec.
     *
     * @param  {Spec} spec
     * @api public
     */

    runSpec : function(spec) {
      this.currentSpec = spec
      try { this.evalBody(spec.body) }
      catch (e) { fail(e) }
      spec.runDeferredAssertions()
      destub()
      this.stats.specsFinished++
      this.stats.assertions += spec.assertions.length
    },

    /**
     * Require a dependency, with optional message.
     *
     * @param  {string} dependency
     * @param  {string} message (optional)
     * @return {JSpec}
     * @api public
     */

    requires : function(dependency, message) {
      hook('requiring', dependency, message)
      try { eval(dependency) }
      catch (e) { throw 'JSpec depends on ' + dependency + ' ' + message }
      return this
    },

    /**
     * Query against the current query strings keys
     * or the queryString specified.
     *
     * @param  {string} key
     * @param  {string} queryString
     * @return {string, null}
     * @api private
     */

    query : function(key, queryString) {
      var queryString = (queryString || (main.location ? main.location.search : null) || '').substring(1)
      return inject(queryString.split('&'), null, function(value, pair){
        parts = pair.split('=')
        return parts[0] == key ? parts[1].replace(/%20|\+/gmi, ' ') : value
      })
    },

    /**
     * Throw a JSpec related error.
     *
     * @param {string} message
     * @param {Exception} e
     * @api public
     */

    error : function(message, e) {
      throw (message ? message : '') + e.toString() + 
              (e.line ? ' near line ' + e.line : '')
    },
    
    /**
     * Ad-hoc POST request for JSpec server usage.
     *
     * @param  {string} uri
     * @param  {string} data
     * @api private
     */
    
    post : function(uri, data) {
      if (any(hook('posting', uri, data), haveStopped)) return
      var request = this.xhr()
      request.open('POST', uri, false)
      request.setRequestHeader('Content-Type', 'application/json')
      request.send(JSpec.JSON.encode(data))
    },

    /**
     * Instantiate an XMLHttpRequest.
     *
     * Here we utilize IE's lame ActiveXObjects first which
     * allow IE access serve files via the file: protocol, otherwise
     * we then default to XMLHttpRequest.
     *
     * @return {XMLHttpRequest, ActiveXObject}
     * @api private
     */
    
    xhr : function() {
      return this.ieXhr() || new JSpec.request
    },
    
    /**
     * Return Microsoft piece of crap ActiveXObject.
     *
     * @return {ActiveXObject}
     * @api public
     */
    
    ieXhr : function() {
      function object(str) {
        try { return new ActiveXObject(str) } catch(e) {}
      }
      return object('Msxml2.XMLHTTP.6.0') ||
        object('Msxml2.XMLHTTP.3.0') ||
        object('Msxml2.XMLHTTP') ||
        object('Microsoft.XMLHTTP')
    },
    
    /**
     * Check for HTTP request support.
     *
     * @return {bool}
     * @api private
     */
    
    hasXhr : function() {
      return JSpec.request || 'ActiveXObject' in main
    },
    
    /**
     * Try loading _file_ returning the contents
     * string or null. Chain to locate / read a file.
     *
     * @param  {string} file
     * @return {string}
     * @api public
     */
    
    tryLoading : function(file) {
      try { return JSpec.load(file) } catch (e) {}
    },

    /**
     * Load a _file_'s contents.
     *
     * @param  {string} file
     * @param  {function} callback
     * @return {string}
     * @api public
     */

    load : function(file, callback) {
      if (any(hook('loading', file), haveStopped)) return
      if ('readFile' in main)
        return readFile(file)
      else if (this.hasXhr()) {
        var request = this.xhr()
        request.open('GET', file, false)
        request.send(null)
        if (request.readyState == 4 && 
           (request.status == 0 || 
            request.status.toString().charAt(0) == 2)) 
          return request.responseText
      }
      else
        error("failed to load `" + file + "'")
    },

    /**
     * Load, pre-process, and evaluate a file.
     *
     * @param {string} file
     * @param {JSpec}
     * @api public
     */

    exec : function(file) {
      if (any(hook('executing', file), haveStopped)) return this
      eval('with (JSpec){' + this.preprocess(this.load(file)) + '}')
      return this
    }
  }
  
  // --- Node.js support
  
  if (typeof GLOBAL === 'object' && typeof exports === 'object')
    quit = process.exit,
    print = require('sys').puts,
    readFile = require('fs').readFileSync
  
  // --- Utility functions

  var main = this,
      find = JSpec.any,
      utils = 'haveStopped stub hookImmutable hook destub map any last pass fail range each option inject select \
               error escape extend puts query strip color does addMatchers callIterator toArray equal'.split(/\s+/)
  while (utils.length) eval('var ' + utils[0] + ' = JSpec.' + utils.shift())
  if (!main.setTimeout) main.setTimeout = function(callback){ callback() }

  // --- Matchers

  addMatchers({
    equal              : "===",
    eql                : "equal(actual, expected)",
    be                 : "alias equal",
    be_greater_than    : ">",
    be_less_than       : "<",
    be_at_least        : ">=",
    be_at_most         : "<=",
    be_a               : "actual.constructor == expected",
    be_an              : "alias be_a",
    be_an_instance_of  : "actual instanceof expected",
    be_null            : "actual == null",
    be_true            : "actual == true",
    be_false           : "actual == false",
    be_undefined       : "typeof actual == 'undefined'",
    be_type            : "typeof actual == expected",
    match              : "typeof actual == 'string' ? actual.match(expected) : false",
    respond_to         : "typeof actual[expected] == 'function'",
    have_length        : "actual.length == expected",
    be_within          : "actual >= expected[0] && actual <= last(expected)",
    have_length_within : "actual.length >= expected[0] && actual.length <= last(expected)",
    
    receive : { defer : true, match : function(actual, method, times) {
      proxy = new JSpec.ProxyAssertion(actual, method, times, this.negate)
      JSpec.currentSpec.assertions.push(proxy)
      return proxy
    }},
    
    be_empty : function(actual) {
      if (actual.constructor == Object && actual.length == undefined)
        for (var key in actual)
          return false;
      return !actual.length
    },

    include : function(actual) {
      for (state = true, i = 1; i < arguments.length; i++) {
        arg = arguments[i]
        switch (actual.constructor) {
          case String: 
          case Number:
          case RegExp:
          case Function:
            state = actual.toString().indexOf(arg) !== -1
            break
         
          case Object:
            state = arg in actual
            break
          
          case Array: 
            state = any(actual, function(value){ return equal(value, arg) })
            break
        }
        if (!state) return false
      }
      return true
    },

    throw_error : { match : function(actual, expected, message) {
      try { actual() }
      catch (e) {
        this.e = e
        var assert = function(arg) {
          switch (arg.constructor) {
            case RegExp   : return arg.test(e.message || e.toString())
            case String   : return arg == (e.message || e.toString())
            case Function : return e instanceof arg || e.name == arg.name
          }
        }
        return message ? assert(expected) && assert(message) :
                 expected ? assert(expected) :
                   true
      }
    }, message : function(actual, expected, negate) {
      // TODO: refactor when actual is not in expected [0]
      var message_for = function(i) {
        if (expected[i] == undefined) return 'exception'
        switch (expected[i].constructor) {
          case RegExp   : return 'exception matching ' + puts(expected[i])
          case String   : return 'exception of ' + puts(expected[i])
          case Function : return expected[i].name || 'Error'
        }
      }
      exception = message_for(1) + (expected[2] ? ' and ' + message_for(2) : '')
      return 'expected ' + exception + (negate ? ' not ' : '' ) +
               ' to be thrown, but ' + (this.e ? 'got ' + puts(this.e) : 'nothing was')
    }},
    
    have : function(actual, length, property) {
      return actual[property].length == length
    },
    
    have_at_least : function(actual, length, property) {
      return actual[property].length >= length
    },
    
    have_at_most :function(actual, length, property) {
      return actual[property].length <= length
    },
    
    have_within : function(actual, range, property) {
      length = actual[property].length
      return length >= range.shift() && length <= range.pop()
    },
    
    have_prop : function(actual, property, value) {
      return actual[property] == null || 
               actual[property] instanceof Function ? false:
                 value == null ? true:
                   does(actual[property], 'eql', value)
    },
    
    have_property : function(actual, property, value) {
      return actual[property] == null ||
               actual[property] instanceof Function ? false:
                 value == null ? true:
                   value === actual[property]
    }
  })
  
})()
