text: /* ***** BEGIN LICENSE BLOCK *****
   * Distributed under the BSD license:
   *
   * Copyright (c) 2010, Ajax.org B.V.
   * All rights reserved.
   * 
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *     * Redistributions of source code must retain the above copyright
   *       notice, this list of conditions and the following disclaimer.
   *     * Redistributions in binary form must reproduce the above copyright
   *       notice, this list of conditions and the following disclaimer in the
   *       documentation and/or other materials provided with the distribution.
   *     * Neither the name of Ajax.org B.V. nor the
   *       names of its contributors may be used to endorse or promote products
   *       derived from this software without specific prior written permission.
   * 
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
   * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * ***** END LICENSE BLOCK ***** */
  
  if (typeof process !== "undefined") {
      require("amd-loader");
  }
  
  define(function(require, exports, module) {
  "use strict";
  
  var EditSession = require("../edit_session").EditSession;
  var Tokenizer = require("../tokenizer").Tokenizer;
  var JavaScriptMode = require("./javascript").Mode;
  var assert = require("../test/assertions");
  
  module.exports = {
      setUp : function() {    
          this.mode = new JavaScriptMode();
      },
  
      "test: getTokenizer() (smoke test)" : function() {
          var tokenizer = this.mode.getTokenizer();
  
          assert.ok(tokenizer instanceof Tokenizer);
  
          var tokens = tokenizer.getLineTokens("'juhu'", "start").tokens;
          assert.equal("string", tokens[0].type);
      },
  
      "test: toggle comment lines should prepend '//' to each line" : function() {
          var session = new EditSession(["  abc", "cde", "fg"]);
          session.setTabSize(1);
  
          this.mode.toggleCommentLines("start", session, 0, 1);
          assert.equal(["//   abc", "// cde", "fg"].join("\n"), session.toString());
      },
  
      "test: toggle comment on commented lines should remove leading '//' chars" : function() {
          var session = new EditSession(["//  abc", "//cde", "fg"]);
          session.setTabSize(1);
  
          this.mode.toggleCommentLines("start", session, 0, 1);
          assert.equal([" abc", "cde", "fg"].join("\n"), session.toString());
      },
  	
  	"test: toggle comment on all empty lines" : function() {
          var session = new EditSession(["  ", " ", "  "]);
          session.setTabSize(1);
  
          this.mode.toggleCommentLines("start", session, 0, 1);
          assert.equal([" //  ", " // ", "  "].join("\n"), session.toString());
      },
  	
  	"test: toggle comment with empty lines" : function() {
          var session = new EditSession([
  			"        abc",
  			"",
  			"    cde", 
  			"    fg"]);
  		
  		var initial = session.toString();
          this.mode.toggleCommentLines("start", session, 0, 3);
          assert.equal([
  		    "    //     abc",
  			"",
  			"    // cde", 
  			"    // fg"].join("\n"),
  			session.toString()
  		);
  		this.mode.toggleCommentLines("start", session, 0, 3);
  		assert.equal(initial, session.toString());
      },
  
      "test: toggle comment lines twice should return the original text" : function() {
          var session = new EditSession(["  abc", "cde", "fg"]);
  
          this.mode.toggleCommentLines("start", session, 0, 2);
          this.mode.toggleCommentLines("start", session, 0, 2);
          assert.equal(["  abc", "cde", "fg"].join("\n"), session.toString());
      },
  
      "test: toggle comment on multiple lines with one commented line prepend '//' to each line" : function() {
          var session = new EditSession(["  //  abc", "  //cde", "    fg"]);
          session.setTabSize(1);
          this.mode.toggleCommentLines("start", session, 0, 2);
          assert.equal(["  // //  abc", "  // //cde", "  //   fg"].join("\n"), session.toString());
      },
  
      "test: toggle comment on a comment line with leading white space": function() {
          var session = new EditSession(["//cde", "  //fg"]);
  
          this.mode.toggleCommentLines("start", session, 0, 1);
          assert.equal(["cde", "  fg"].join("\n"), session.toString());
      },
  
      "test: toggle comment lines should take tabsize into account" : function() {
          var session = new EditSession(["  //  abc", "  // cde", "//    fg"]);
          session.setTabSize(2);
          this.mode.toggleCommentLines("start", session, 0, 2);
          assert.equal(["    abc", "  cde", "    fg"].join("\n"), session.toString());
          session.setTabSize(4);
          this.mode.toggleCommentLines("start", session, 0, 2);
          assert.equal(["//     abc", "//   cde", "//     fg"].join("\n"), session.toString());
          this.mode.toggleCommentLines("start", session, 0, 2);
          assert.equal(["    abc", "  cde", "    fg"].join("\n"), session.toString());
          
          session.insert({row: 0, column: 0}, " ");
          this.mode.toggleCommentLines("start", session, 0, 2);
          assert.equal(["//      abc", "//   cde", "//     fg"].join("\n"), session.toString());        
      },
      //there doesn't seem to be any way to make this work
      "!test: togglecomment on line with one space" : function() {
          var session = new EditSession([" abc", "  // cde", "//    fg"]);
          var initialValue = session + "";
          session.setTabSize(4);
          this.mode.toggleCommentLines("start", session, 0, 0);
          this.mode.toggleCommentLines("start", session, 0, 0);
          assert.equal(initialValue, session.toString());
      },
  
      "test: auto indent after opening brace" : function() {
          assert.equal("  ", this.mode.getNextLineIndent("start", "if () {", "  "));
      },
      
      "test: auto indent after case" : function() {
          assert.equal("  ", this.mode.getNextLineIndent("start", "case 'juhu':", "  "));
      },
  
      "test: no auto indent in object literal" : function() {
          assert.equal("", this.mode.getNextLineIndent("start", "{ 'juhu':", "  "));
      },
  
      "test: no auto indent after opening brace in multi line comment" : function() {
          assert.equal("", this.mode.getNextLineIndent("start", "/*if () {", "  "));
          assert.equal("  ", this.mode.getNextLineIndent("comment", "  abcd", "  "));
      },
  
      "test: no auto indent after opening brace in single line comment" : function() {
          assert.equal("", this.mode.getNextLineIndent("start", "//if () {", "  "));
          assert.equal("  ", this.mode.getNextLineIndent("start", "  //if () {", "  "));
      },
  
      "test: no auto indent should add to existing indent" : function() {
          assert.equal("      ", this.mode.getNextLineIndent("start", "    if () {", "  "));
          assert.equal("    ", this.mode.getNextLineIndent("start", "    cde", "  "));
          assert.equal("    ", this.mode.getNextLineIndent("start", "function foo(items) {", "    "));
      },
  
      "test: special indent in doc comments" : function() {
          assert.equal(" * ", this.mode.getNextLineIndent("doc-start", "/**", " "));
          assert.equal("   * ", this.mode.getNextLineIndent("doc-start", "  /**", " "));
          assert.equal(" * ", this.mode.getNextLineIndent("doc-start", " *", " "));
          assert.equal("    * ", this.mode.getNextLineIndent("doc-start", "    *", " "));
          assert.equal("  ", this.mode.getNextLineIndent("doc-start", "  abc", " "));
      },
  
      "test: no indent after doc comments" : function() {
          assert.equal("", this.mode.getNextLineIndent("doc-start", "   */", "  "));
      },
  
      "test: trigger outdent if line is space and new text starts with closing brace" : function() {
          assert.ok(this.mode.checkOutdent("start", "   ", " }"));
          assert.ok(!this.mode.checkOutdent("start", " a  ", " }"));
          assert.ok(!this.mode.checkOutdent("start", "", "}"));
          assert.ok(!this.mode.checkOutdent("start", "   ", "a }"));
          assert.ok(!this.mode.checkOutdent("start", "   }", "}"));
      },
  
      "test: auto outdent should indent the line with the same indent as the line with the matching opening brace" : function() {
          var session = new EditSession(["  function foo() {", "    bla", "    }"], new JavaScriptMode());
          this.mode.autoOutdent("start", session, 2);
          assert.equal("  }", session.getLine(2));
      },
  
      "test: no auto outdent if no matching brace is found" : function() {
          var session = new EditSession(["  function foo()", "    bla", "    }"]);
          this.mode.autoOutdent("start", session, 2);
          assert.equal("    }", session.getLine(2));
      }
  };
  
  });
  
  if (typeof module !== "undefined" && module === require.main) {
      require("asyncjs").test.testcase(module.exports).exec()
  }
  