describe 'haml'
  describe '.version'
    it 'should be a triplet'
      haml.version.should.match(/^\d+\.\d+\.\d+$/)
    end
  end
  describe '.compile()'
    it 'should return a function'
      var fn = haml.compile('%foo= bar');
      fn({ bar: 'baz' }).should.equal '\nbaz'
    end
  end
  describe 'Parser'
    it 'should be available for extension'
      haml.Parser.should.not.be_undefined
    end
  end
  describe '.render()'
    before
      assertAs = function(name, type, options) {
        var str = fixture(name + '.haml')
        try {
          var html = haml.render(str, options).trim(),
              expected = fixture(name + '.' + type).trim()
          if (html === expected)
            pass()
          else
            fail('got:\n' + html + '\n\nexpected:\n' + expected)
        } catch (err) {
          if (err instanceof haml.HamlError) {
            throw err
          } else {
            fail('\n:' + err.stack + '\n')
          }
        }
      }
      assert = function(name, options) {
        assertAs(name, 'html', options, 'CRLF', '\r\n')
      }
      assertXML = function(name, options) {
        assertAs(name, 'xml', options, 'CRLF', '\r\n')
      }
    end
    
    it 'should allow passing of a context object'
      assert('context', { context: 'yay' })
    end
    
    it 'should allow passing of literals'
      assert('literals', { locals: { user: 'tj' }})
    end
    
    it 'should not fail on trailing indents'
      assert('trailing-indent')
    end
    
    it 'should add xml support via the "xml" option'
      assertXML('feed', { xml: true })
    end
    
    it 'should support xml namespaces'
      assertXML('namespace')
    end
    
    it 'should utilize "filename" option when an error is thrown'
      try { assert('error', { filename: 'error.haml' }) }
      catch (err) {
        err.message.should.eql '(error.haml):3 invalid indentation; got 3, when previous was 1'
      }
    end
    
    it 'should default filename to "Haml" when an error is thrown'
      try { assert('error') }
      catch (err) {
        err.message.should.eql '(Haml):3 invalid indentation; got 3, when previous was 1'
      }
    end
    
    it 'should bitch when "cache" is true without a filename given'
      // -{ assert('tag.simple', { cache: true }) }.should.throw_error
    end
    
    it 'should pre-compiled and cache when "cache" is true'
      assert('tag.simple', { cache: true, filename: 'tag.simple.haml' })
      assert('tag.simple', { cache: true, filename: 'tag.simple.haml' })
    end
    
    it 'should support blank lines'
      assert('newlines')
    end
    
    describe '.class'
      it 'should output a div with the given class'
        assert('class')
      end
      
      it 'should work with several classes'
        assert('classes')
      end
    end
    
    describe '#id'
      it 'should output a div with the given id'
        assert('id')
      end
    end
    
    describe '%tag'
      it 'should work with no text or block'
        assert('tag.simple')
      end
      
      it 'should work with text'
        assert('tag.text')
      end
      
      it 'should work with block text'
        assert('tag.text.block')
      end
      
      it 'should work with blocks of text and tags'
        assert('tag.text.block.complex')
      end
      
      it 'should work with many classes / ids / attrs'
        assert('tag.complex')
      end
      
      it 'should allow empty tags'
        assert('tag.empty')
      end
    end
    
    describe '%tag.class'
      it 'should output tag with a class'
        assert('tag.class')
      end
      
      it 'should work with several classes'
        assert('tag.classes')
      end
      
      it 'should support self-closing tags'
        assert('tag.self-close')
      end
    end
    
    describe '%tag!='
      it 'should output the evaluated code'
        assert('tag.code')
      end
      
      it 'should not escape output'
        assert('tag.code.no-escape')
      end
    end
    
    describe '%tag='
      it 'should escape the evaluated code'
        assert('tag.escape')
      end
    end
    
    describe '%namespace:tag'
      it 'should output a tag with a namespace prefix'
        assert('namespace.tag')
      end
    end
    
    describe '{...}'
      it 'should be mapped as html attributes'
        assert('tag.attrs')
      end
      
      it 'should escape values'
        assert('tag.attrs.escape')
      end
      
      it 'should allow booleans'
        assert('tag.attrs.bools')
      end
    end
    
    describe '!!!'
      it 'should default the doctype to 1.0 transitional'
        assert('doctype')
      end
    end
    
    describe '!!! NAME'
      it 'should output a specific doctype'
        assert('doctype.xml')
      end
      
      it 'should be case-insensitive'
        assert('doctype.xml.case')
      end
    end
    
    describe 'nesting'
      it 'should work when nested downwards'
        assert('nesting.simple')
      end
      
      it 'should work when blocks outdent'
        assert('nesting.complex')
      end
    end
    
    describe '- code'
      it 'should work with if statements'
        assert('code.if')
      end
      
      it 'should work when nested'
        assert('code.nested')
      end
    end
    
    describe '- each'
      it 'should iterate'
        assert('code.each', { locals: { items: ['one', 'two', 'three'] }})
        assert('code.each.non-enumerable', { locals: { items: null }})
      end
      
      it 'should iterate objects'
        assert('code.each', { locals: { items: { 0: 'one', 1: 'two', 2: 'three' }}})
        assert('code.each.index', { locals: { items: { 0: 'one', 1: 'two', 2: 'three' }}})
      end
      
      it 'should iterate with index'
        assert('code.each.index', { locals: { items: ['one', 'two', 'three'] }})
      end
    end
    
    describe '= code'
      it 'should output evaluation'
        assert('code')
      end
    end
    
    describe '&= code'
      it 'should output evaluation while escaping html entities'
        assert('code.escape')
      end
    end
    
    describe '