diff --git a/.gitignore b/.gitignore
index ae6b742951..da632fc918 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,6 @@
.DS_Store
_Resharper.DefinitelyTyped
+bin
+obj
+Properties
diff --git a/ace/ace.d.ts b/ace/ace.d.ts
index 75b597ba2c..0a945f27f2 100644
--- a/ace/ace.d.ts
+++ b/ace/ace.d.ts
@@ -5,18 +5,96 @@
module AceAjax {
- interface CommandManager {
- addCommand(command);
+ export interface Delta {
+ action: string;
+ range: Range;
+ text: string;
+ lines: string[];
}
- interface TextMode {
+ export interface EditorCommand {
+
+ name:string;
+
+ bindKey:any;
+
+ exec:Function;
+ }
+
+ export interface CommandManager {
+
+ byName;
+
+ commands;
+
+ platform: string;
+
+ addCommands(commands:EditorCommand[]);
+
+ addCommand(command:EditorCommand);
+
+ exec(name: string, editor: Editor, args: any);
+ }
+
+ export interface Annotation {
+
+ row: number;
+
+ column: number;
+
+ text: string;
+
+ type: string;
+ }
+
+ export interface TokenInfo {
+
+ value: string;
+ }
+
+ export interface Position {
+
+ row: number;
+
+ column: number;
+ }
+
+ export interface KeyBinding {
+
+ setDefaultHandler(kb);
+
+ setKeyboardHandler(kb);
+
+ addKeyboardHandler(kb, pos);
+
+ removeKeyboardHandler(kb): bool;
+
+ getKeyboardHandler(): any;
+
+ onCommandKey(e, hashId, keyCode);
+
+ onTextInput(text);
+ }
+ declare var KeyBinding: {
+ new(editor: Editor): KeyBinding;
+ }
+
+ export interface TextMode {
+
getTokenizer(): any;
+
toggleCommentLines(state, doc, startRow, endRow);
+
getNextLineIndent (state, line, tab): string;
+
checkOutdent(state, line, input): bool;
+
autoOutdent(state, doc, row);
+
createWorker(session): any;
+
createModeDelegates (mapping);
+
transformAction(state, action, editor, session, param): any;
}
@@ -27,7 +105,7 @@ module AceAjax {
/**
* The main class required to set up an Ace instance in the browser.
**/
- interface Ace {
+ export interface Ace {
/**
* Provides access to require in packed noconflict mode
@@ -52,14 +130,14 @@ module AceAjax {
* @param text {:textParam}
* @param mode {:modeParam}
**/
- createEditSession(text: Document, mode: TextMode): EditSession;
+ createEditSession(text: Document, mode: TextMode): IEditSession;
/**
* Creates a new [[EditSession]], and returns the associated [[Document]].
* @param text {:textParam}
* @param mode {:modeParam}
**/
- createEditSession(text: string, mode: TextMode): EditSession;
+ createEditSession(text: string, mode: TextMode): IEditSession;
}
////////////////
@@ -69,14 +147,14 @@ module AceAjax {
/**
* Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated.
**/
- interface Anchor {
+ export interface Anchor {
on(event: string, fn: (e) => any);
/**
* Returns an object identifying the `row` and `column` position of the current anchor.
**/
- getPosition(): any;
+ getPosition(): Position;
/**
* Returns the current document.
@@ -124,7 +202,9 @@ module AceAjax {
* Tokenizes the current [[Document `Document`]] in the background, and caches the tokenized rows for future use.
* If a certain row is changed, everything below that row is re-tokenized.
**/
- interface BackgroundTokenizer {
+ export interface BackgroundTokenizer {
+
+ states: any[];
/**
* Sets a new tokenizer for this object.
@@ -185,7 +265,9 @@ module AceAjax {
* Contains the text of the document. Document can be attached to several [[EditSession `EditSession`]]s.
* At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index.
**/
- interface Document {
+ export interface Document {
+
+ on(event: string, fn: (e) => any);
/**
* Replaces all the lines in the current `Document` with the value of `text`.
@@ -261,20 +343,20 @@ module AceAjax {
* @param position The position to start inserting at
* @param text A chunk of text to insert
**/
- insert(position: any, text: string): any;
+ insert(position: Position, text: string): any;
/**
* Inserts the elements in `lines` into the document, starting at the row index given by `row`. This method also triggers the `'change'` event.
* @param row The index of the row to insert at
* @param lines An array of strings
**/
- insertLines(row: number, lines: Array): any;
+ insertLines(row: number, lines: string[]): any;
/**
* Inserts a new line into the document at the current row's `position`. This method also triggers the `'change'` event.
* @param position The position to insert at
**/
- insertNewLine(position: any): any;
+ insertNewLine(position: Position): any;
/**
* Inserts `text` into the `position` at the current row. This method also triggers the `'change'` event.
@@ -320,12 +402,12 @@ module AceAjax {
/**
* Applies all the changes previously accumulated. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
**/
- applyDeltas();
+ applyDeltas(deltas: Delta[]);
/**
* Reverts any changes previously applied. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
**/
- revertDeltas();
+ revertDeltas(deltas: Delta[]);
/**
* Converts an index position in a document to a `{row, column}` object.
@@ -338,7 +420,7 @@ module AceAjax {
* @param index An index to convert
* @param startRow=0 The row from which to start the conversion
**/
- indexToPosition(index: number, startRow: number): any;
+ indexToPosition(index: number, startRow: number): Position;
/**
* Converts the `{row, column}` position in a document to the character's index.
@@ -351,7 +433,7 @@ module AceAjax {
* @param pos The `{row, column}` to convert
* @param startRow=0 The row from which to start the conversion
**/
- positionToIndex(pos: any, startRow: number): number;
+ positionToIndex(pos: Position, startRow: number): number;
}
declare var Document: {
/**
@@ -374,11 +456,35 @@ module AceAjax {
* Stores all the data about [[Editor `Editor`]] state providing easy way to change editors state.
* `EditSession` can be attached to only one [[Document `Document`]]. Same `Document` can be attached to several `EditSession`s.
**/
- interface EditSession {
+ export interface IEditSession {
+
+ selection: Selection;
+
+ bgTokenizer: BackgroundTokenizer;
+
+ doc: Document;
on(event: string, fn: (e) => any);
- selection: Selection;
+ findMatchingBracket(position: Position);
+
+ addFold(text: string, range: Range);
+
+ getFoldAt(row: number, column: number): any;
+
+ removeFold(arg: any);
+
+ expandFold(arg: any);
+
+ unfold(arg1: any, arg2: bool);
+
+ screenToDocumentColumn(row: number, column: number);
+
+ getFoldDisplayLine(foldLine: any, docRow: number, docColumn: number): any;
+
+ getFoldsInRange(range: Range): any;
+
+ highlight(text: string);
/**
* Sets the `EditSession` to point to a new `Document`. If a `BackgroundTokenizer` exists, it also points to `doc`.
@@ -432,7 +538,7 @@ module AceAjax {
* @param row The row number to retrieve from
* @param column The column number to retrieve from
**/
- getTokenAt(row: number, column: number): any;
+ getTokenAt(row: number, column: number): TokenInfo;
/**
* Sets the undo manager.
@@ -579,7 +685,7 @@ module AceAjax {
* Sets annotations for the `EditSession`. This functions emits the `'changeAnnotation'` event.
* @param annotations A list of annotations
**/
- setAnnotations(annotations: Array);
+ setAnnotations(annotations: Annotation[]);
/**
* Returns the annotations for the `EditSession`.
@@ -704,7 +810,7 @@ module AceAjax {
* @param position The position {row, column} to start inserting at
* @param text A chunk of text to insert
**/
- insert(position: any, text: string): any;
+ insert(position: Position, text: string): any;
/**
* Removes the `range` from the document.
@@ -911,9 +1017,11 @@ module AceAjax {
* @param text [If `text` is a `Document`, it associates the `EditSession` with it. Otherwise, a new `Document` is created, with the initial text]{: #textParam}
* @param mode [The inital language mode to use for the document]{: #modeParam}
**/
- new(text: string, mode?: TextMode): EditSession;
+ new(text: string, mode?: TextMode): IEditSession;
- new(text: string[]): EditSession;
+ new(content: string, mode?: string): IEditSession;
+
+ new (text: string[], mode?: string): IEditSession;
}
////////////////////////////////
@@ -925,7 +1033,11 @@ module AceAjax {
* The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.
* Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.
**/
- interface Editor {
+ export interface Editor {
+
+ inMultiSelectMode: bool;
+
+ selectMoreLines(n: number);
onTextInput(text: string);
@@ -933,10 +1045,22 @@ module AceAjax {
commands: CommandManager;
- session: EditSession;
+ session: IEditSession;
selection: Selection;
+ renderer: VirtualRenderer;
+
+ keyBinding: KeyBinding;
+
+ container: HTMLElement;
+
+ onSelectionChange(e);
+
+ onChangeMode(e?);
+
+ execCommand(command:string, args?: any);
+
/**
* Sets a new key handler, such as "vim" or "windows".
* @param keyboardHandler The new key handler
@@ -952,12 +1076,12 @@ module AceAjax {
* Sets a new editsession to use. This method also emits the `'changeSession'` event.
* @param session The new session to use
**/
- setSession(session: EditSession);
+ setSession(session: IEditSession);
/**
* Returns the current session being used.
**/
- getSession(): EditSession;
+ getSession(): IEditSession;
/**
* Sets the current document to `val`.
@@ -1411,7 +1535,7 @@ module AceAjax {
/**
* Gets the current position of the cursor.
**/
- getCursorPosition(): any;
+ getCursorPosition(): Position;
/**
* Returns the screen position of the cursor.
@@ -1438,13 +1562,13 @@ module AceAjax {
* @param row The new row number
* @param column The new column number
**/
- moveCursorTo(row: number, column: number);
+ moveCursorTo(row: number, column?: number, animate?:bool);
/**
* Moves the cursor to the position indicated by `pos.row` and `pos.column`.
- * @param pos An object with two properties, row and column
+ * @param position An object with two properties, row and column
**/
- moveCursorToPosition(pos: any);
+ moveCursorToPosition(position: Position);
/**
* Moves the cursor's row and column to the next matching bracket.
@@ -1470,19 +1594,19 @@ module AceAjax {
* Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.
* @param times The number of times to change navigation
**/
- navigateUp(times: number);
+ navigateUp(times?: number);
/**
* Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.
* @param times The number of times to change navigation
**/
- navigateDown(times: number);
+ navigateDown(times?: number);
/**
* Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.
* @param times The number of times to change navigation
**/
- navigateLeft(times: number);
+ navigateLeft(times?: number);
/**
* Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.
@@ -1584,14 +1708,16 @@ module AceAjax {
* @param renderer Associated `VirtualRenderer` that draws everything
* @param session The `EditSession` to refer to
**/
- new(renderer: VirtualRenderer, session: EditSession): Editor;
+ new(renderer: VirtualRenderer, session?: IEditSession): Editor;
}
////////////////////////////////
/// PlaceHolder
////////////////////////////////
- interface PlaceHolder {
+ export interface PlaceHolder {
+
+ on(event: string, fn: (e) => any);
/**
* PlaceHolder.setup()
@@ -1637,16 +1763,39 @@ module AceAjax {
}
declare var PlaceHolder: {
/**
- * - session (Document): The document to associate with the anchor
- * - length (Number): The starting row position
- * - pos (Number): The starting column position
- * - others (String):
- * - mainClass (String):
- * - othersClass (String):
+ * - @param session (Document): The document to associate with the anchor
+ * - @param length (Number): The starting row position
+ * - @param pos (Number): The starting column position
+ * - @param others (String):
+ * - @param mainClass (String):
+ * - @param othersClass (String):
**/
- new(): PlaceHolder;
+ new (session: Document, length: number, pos: number, others: string, mainClass: string, othersClass: string): PlaceHolder;
+
+ new (session: IEditSession, length: number, pos: Position, positions: Position[]): PlaceHolder;
}
+ ////////////////
+ /// RangeList
+ ////////////////
+
+ export interface IRangeList {
+ ranges: Range[];
+
+ pointIndex(pos: Position, startIndex?: number);
+
+ addList(ranges: Range[]);
+
+ add(ranges: Range);
+
+ merge(): Range[];
+
+ substractPoint(pos: Position);
+ }
+ export var RangeList: {
+ new (): IRangeList;
+ }
+
////////////////
/// Range
////////////////
@@ -1654,11 +1803,19 @@ module AceAjax {
/**
* This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
**/
- interface Range {
+ export interface Range {
- start: number;
+ startRow:number;
- end: number;
+ startColumn:number;
+
+ endRow:number;
+
+ endColumn:number;
+
+ start: Position;
+
+ end: Position;
/**
* Returns `true` if and only if the starting row and column, and ending row and column, are equivalent to those given by `range`.
@@ -1819,7 +1976,7 @@ module AceAjax {
* Given the current `Range`, this function converts those starting and ending points into screen positions, and then returns a new `Range` object.
* @param session The `EditSession` to retrieve coordinates from
**/
- toScreenRange(session: EditSession): Range;
+ toScreenRange(session: IEditSession): Range;
/**
* Creates and returns a new `Range` based on the row and column of the given parameters.
@@ -1844,7 +2001,7 @@ module AceAjax {
/// RenderLoop
////////////////
- interface RenderLoop { }
+ export interface RenderLoop { }
declare var RenderLoop: {
new(): RenderLoop;
}
@@ -1856,7 +2013,7 @@ module AceAjax {
/**
* A set of methods for setting and retrieving the editor's scrollbar.
**/
- interface ScrollBar {
+ export interface ScrollBar {
/**
* Emitted when the scroll bar, well, scrolls.
@@ -1902,7 +2059,7 @@ module AceAjax {
/**
* A class designed to handle all sorts of text searches within a [[Document `Document`]].
**/
- interface Search {
+ export interface Search {
/**
* Sets the search options via the `options` parameter.
@@ -1925,13 +2082,13 @@ module AceAjax {
* Searches for `options.needle`. If found, this method returns the [[Range `Range`]] where the text first occurs. If `options.backwards` is `true`, the search goes backwards in the session.
* @param session The session to search with
**/
- find(session: EditSession): Range;
+ find(session: IEditSession): Range;
/**
* Searches for all occurances `options.needle`. If found, this method returns an array of [[Range `Range`s]] where the text first occurs. If `options.backwards` is `true`, the search goes backwards in the session.
* @param session The session to search with
**/
- findAll(session: EditSession): Range[];
+ findAll(session: IEditSession): Range[];
/**
* Searches for `options.needle` in `input`, and, if found, replaces it with `replacement`.
@@ -1966,10 +2123,18 @@ module AceAjax {
* Contains the cursor position and the text selection of an edit session.
* The row/columns used in the selection are in document coordinates representing ths coordinates as thez appear in the document before applying soft wrap and folding.
**/
- interface Selection {
+ export interface Selection {
+
+ fromOrientedRange(range: Range);
+
+ setSelectionRange(match);
+
+ getAllRanges(): Range[];
on(event: string, fn: (e) => any);
+ addRange(range: Range);
+
/**
* Returns `true` if the selection is empty.
**/
@@ -2187,7 +2352,7 @@ module AceAjax {
* @param column The column to move to
* @param keepDesiredColumn [If `true`, the cursor move does not respect the previous column]{: #preventUpdateBool}
**/
- moveCursorTo(row: number, column: number, keepDesiredColumn: bool);
+ moveCursorTo(row: number, column: number, keepDesiredColumn?: bool);
/**
* Moves the cursor to the screen position indicated by row and column. {:preventUpdateBoolDesc}
@@ -2202,14 +2367,14 @@ module AceAjax {
* Creates a new `Selection` object.
* @param session The session to use
**/
- new(session: EditSession): Selection;
+ new(session: IEditSession): Selection;
}
////////////////
/// Split
////////////////
- interface Split {
+ export interface Split {
/**
* Returns the number of splits.
@@ -2267,7 +2432,7 @@ module AceAjax {
* @param session The new edit session
* @param idx The editor's index you're interested in
**/
- setSession(session: EditSession, idx: number);
+ setSession(session: IEditSession, idx: number);
/**
* Returns the orientation.
@@ -2296,7 +2461,7 @@ module AceAjax {
/**
* This class provides an essay way to treat the document as a stream of tokens, and provides methods to iterate over these tokens.
**/
- interface TokenIterator {
+ export interface TokenIterator {
/**
* Tokenizes all the items from the current point to the row prior in the document.
@@ -2330,7 +2495,7 @@ module AceAjax {
* @param initialRow The row to start the tokenizing at
* @param initialColumn The column to start the tokenizing at
**/
- new(session: EditSession, initialRow: number, initialColumn: number): TokenIterator;
+ new(session: IEditSession, initialRow: number, initialColumn: number): TokenIterator;
}
//////////////////
@@ -2341,7 +2506,7 @@ module AceAjax {
/**
* This class takes a set of highlighting rules, and creates a tokenizer out of them. For more information, see [the wiki on extending highlighters](https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#wiki-extendingTheHighlighter).
**/
- interface Tokenizer {
+ export interface Tokenizer {
/**
* Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state.
@@ -2364,7 +2529,7 @@ module AceAjax {
/**
* This object maintains the undo stack for an [[EditSession `EditSession`]].
**/
- interface UndoManager {
+ export interface UndoManager {
/**
* Provides a means for implementing your own undo manager. `options` has one property, `args`, an [[Array `Array`]], with two elements:
@@ -2416,7 +2581,7 @@ module AceAjax {
/**
* The class that is responsible for drawing everything you see on the screen!
**/
- interface VirtualRenderer {
+ export interface VirtualRenderer {
/**
* Associates the renderer with an [[EditSession `EditSession`]].
diff --git a/ace/all-tests.ts b/ace/all-tests.ts
new file mode 100644
index 0000000000..163d973ea2
--- /dev/null
+++ b/ace/all-tests.ts
@@ -0,0 +1,21 @@
+///
+
+var exports: any;
+var assert: any;
+var MockRenderer = null;
+var JavaScriptMode = null;
+
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+///
+
+
+
diff --git a/ace/tests/ace-anchor-tests.ts b/ace/tests/ace-anchor-tests.ts
new file mode 100644
index 0000000000..40e81600ab
--- /dev/null
+++ b/ace/tests/ace-anchor-tests.ts
@@ -0,0 +1,131 @@
+///
+
+exports = {
+
+ "test create anchor" : function() {
+ var doc = new AceAjax.Document("juhu");
+ var anchor = new AceAjax.Anchor(doc, 0, 0);
+
+ assert.position(anchor.getPosition(), 0, 0);
+ assert.equal(anchor.getDocument(), doc);
+ },
+
+ "test insert text in same row before cursor should move anchor column": function() {
+ var doc = new AceAjax.Document("juhu\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 1, 4);
+
+ doc.insert({row: 1, column: 1}, "123");
+ assert.position(anchor.getPosition(), 1, 7);
+ },
+
+ "test insert lines before cursor should move anchor row": function() {
+ var doc = new AceAjax.Document("juhu\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 1, 4);
+
+ doc.insertLines(1, ["123", "456"]);
+ assert.position(anchor.getPosition(), 3, 4);
+ },
+
+ "test insert new line before cursor should move anchor column": function() {
+ var doc = new AceAjax.Document("juhu\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 1, 4);
+
+ doc.insertNewLine({row: 0, column: 0});
+ assert.position(anchor.getPosition(), 2, 4);
+ },
+
+ "test insert new line in anchor line before anchor should move anchor column and row": function() {
+ var doc = new AceAjax.Document("juhu\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 1, 4);
+
+ doc.insertNewLine({row: 1, column: 2});
+ assert.position(anchor.getPosition(), 2, 2);
+ },
+
+ "test delete text in anchor line before anchor should move anchor column": function() {
+ var doc = new AceAjax.Document("juhu\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 1, 4);
+
+ doc.remove(new AceAjax.Range(1, 1, 1, 3));
+ assert.position(anchor.getPosition(), 1, 2);
+ },
+
+ "test remove range which contains the anchor should move the anchor to the start of the range": function() {
+ var doc = new AceAjax.Document("juhu\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 0, 3);
+
+ doc.remove(new AceAjax.Range(0, 1, 1, 3));
+ assert.position(anchor.getPosition(), 0, 1);
+ },
+
+ "test delete character before the anchor should have no effect": function() {
+ var doc = new AceAjax.Document("juhu\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 1, 4);
+
+ doc.remove(new AceAjax.Range(1, 4, 1, 5));
+ assert.position(anchor.getPosition(), 1, 4);
+ },
+
+ "test delete lines in anchor line before anchor should move anchor row": function() {
+ var doc = new AceAjax.Document("juhu\n1\n2\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 3, 4);
+
+ doc.removeLines(1, 2);
+ assert.position(anchor.getPosition(), 1, 4);
+ },
+
+ "test remove new line before the cursor": function() {
+ var doc = new AceAjax.Document("juhu\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 1, 4);
+
+ doc.removeNewLine(0);
+ assert.position(anchor.getPosition(), 0, 8);
+ },
+
+ "test delete range which contains the anchor should move anchor to the end of the range": function() {
+ var doc = new AceAjax.Document("juhu\nkinners");
+ var anchor = new AceAjax.Anchor(doc, 1, 4);
+
+ doc.remove(new AceAjax.Range(0, 2, 1, 2));
+ assert.position(anchor.getPosition(), 0, 4);
+ },
+
+ "test delete line which contains the anchor should move anchor to the end of the range": function() {
+ var doc = new AceAjax.Document("juhu\nkinners\n123");
+ var anchor = new AceAjax.Anchor(doc, 1, 5);
+
+ doc.removeLines(1, 1);
+ assert.position(anchor.getPosition(), 1, 0);
+ },
+
+ "test remove after the anchor should have no effect": function() {
+ var doc = new AceAjax.Document("juhu\nkinners\n123");
+ var anchor = new AceAjax.Anchor(doc, 1, 2);
+
+ doc.remove(new AceAjax.Range(1, 4, 2, 2));
+ assert.position(anchor.getPosition(), 1, 2);
+ },
+
+ "test anchor changes triggered by document changes should emit change event": function(next) {
+ var doc = new AceAjax.Document("juhu\nkinners\n123");
+ var anchor = new AceAjax.Anchor(doc, 1, 5);
+
+ anchor.on("change", function(e) {
+ assert.position(anchor.getPosition(), 0, 0);
+ next();
+ });
+
+ doc.remove(new AceAjax.Range(0, 0, 2, 1));
+ },
+
+ "test only fire change event if position changes": function() {
+ var doc = new AceAjax.Document("juhu\nkinners\n123");
+ var anchor = new AceAjax.Anchor(doc, 1, 5);
+
+ anchor.on("change", function(e) {
+ assert.fail();
+ });
+
+ doc.remove(new AceAjax.Range(2, 0, 2, 1));
+ }
+};
diff --git a/ace/tests/ace-background_tokenizer-tests.ts b/ace/tests/ace-background_tokenizer-tests.ts
new file mode 100644
index 0000000000..8c29358a40
--- /dev/null
+++ b/ace/tests/ace-background_tokenizer-tests.ts
@@ -0,0 +1,39 @@
+///
+
+function forceTokenize(session) {
+ for (var i = 0, l = session.getLength(); i < l; i++)
+ session.getTokens(i)
+}
+
+function testStates(session, states) {
+ for (var i = 0, l = session.getLength(); i < l; i++)
+ assert.equal(session.bgTokenizer.states[i], states[i])
+ assert.ok(l == states.length)
+}
+
+exports = {
+
+ "test background tokenizer update on session change": function() {
+ var doc = new AceAjax.EditSession([
+ "/*",
+ "*/",
+ "var juhu"
+ ]);
+ doc.setMode("./mode/javascript")
+
+ forceTokenize(doc)
+ testStates(doc, ["comment", "start", "start"])
+
+ doc.remove(new AceAjax.Range(0, 2, 1, 2))
+ testStates(doc, [null, "start"])
+
+ forceTokenize(doc)
+ testStates(doc, ["comment", "comment"])
+
+ doc.insert({ row: 0, column: 2 }, "\n*/")
+ testStates(doc, [undefined, undefined, "comment"])
+
+ forceTokenize(doc)
+ testStates(doc, ["comment", "start", "start"])
+ }
+};
diff --git a/ace/ace-tests.ts b/ace/tests/ace-default-tests.ts
similarity index 99%
rename from ace/ace-tests.ts
rename to ace/tests/ace-default-tests.ts
index 43556fb831..dcd1ab1033 100644
--- a/ace/ace-tests.ts
+++ b/ace/tests/ace-default-tests.ts
@@ -1,6 +1,4 @@
-///
-
-var assert: any;
+///
var editor = ace.edit("editor");
editor.setTheme("ace/theme/monokai");
@@ -450,4 +448,3 @@ editor.moveCursorTo(1, 0);
editor.toLowerCase()
assert.equal(session.getValue(), ["AJAX", "dot", "ORG"].join("\n"));
assert.position(editor.getCursorPosition(), 1, 0);
-
diff --git a/ace/tests/ace-document-tests.ts b/ace/tests/ace-document-tests.ts
new file mode 100644
index 0000000000..1f3e0a9a24
--- /dev/null
+++ b/ace/tests/ace-document-tests.ts
@@ -0,0 +1,254 @@
+///
+
+exports = {
+ "test: insert text in line": function() {
+ var doc = new AceAjax.Document(["12", "34"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.insert({ row: 0, column: 1 }, "juhu");
+ assert.equal(doc.getValue(), ["1juhu2", "34"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["12", "34"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["1juhu2", "34"].join("\n"));
+ } ,
+
+ "test: insert new line": function() {
+ var doc = new AceAjax.Document(["12", "34"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.insertNewLine({ row: 0, column: 1 });
+ assert.equal(doc.getValue(), ["1", "2", "34"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["12", "34"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["1", "2", "34"].join("\n"));
+ } ,
+
+ "test: insert lines at the beginning": function() {
+ var doc = new AceAjax.Document(["12", "34"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.insertLines(0, ["aa", "bb"]);
+ assert.equal(doc.getValue(), ["aa", "bb", "12", "34"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["12", "34"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["aa", "bb", "12", "34"].join("\n"));
+ } ,
+
+ "test: insert lines at the end": function() {
+ var doc = new AceAjax.Document(["12", "34"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.insertLines(2, ["aa", "bb"]);
+ assert.equal(doc.getValue(), ["12", "34", "aa", "bb"].join("\n"));
+ } ,
+
+ "test: insert lines in the middle": function() {
+ var doc = new AceAjax.Document(["12", "34"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.insertLines(1, ["aa", "bb"]);
+ assert.equal(doc.getValue(), ["12", "aa", "bb", "34"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["12", "34"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["12", "aa", "bb", "34"].join("\n"));
+ } ,
+
+ "test: insert multi line string at the start": function() {
+ var doc = new AceAjax.Document(["12", "34"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.insert({ row: 0, column: 0 }, "aa\nbb\ncc");
+ assert.equal(doc.getValue(), ["aa", "bb", "cc12", "34"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["12", "34"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["aa", "bb", "cc12", "34"].join("\n"));
+ } ,
+
+ "test: insert multi line string at the end": function() {
+ var doc = new AceAjax.Document(["12", "34"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.insert({ row: 2, column: 0 }, "aa\nbb\ncc");
+ assert.equal(doc.getValue(), ["12", "34aa", "bb", "cc"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["12", "34"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["12", "34aa", "bb", "cc"].join("\n"));
+ } ,
+
+ "test: insert multi line string in the middle": function() {
+ var doc = new AceAjax.Document(["12", "34"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.insert({ row: 0, column: 1 }, "aa\nbb\ncc");
+ assert.equal(doc.getValue(), ["1aa", "bb", "cc2", "34"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["12", "34"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["1aa", "bb", "cc2", "34"].join("\n"));
+ } ,
+
+ "test: delete in line": function() {
+ var doc = new AceAjax.Document(["1234", "5678"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.remove(new AceAjax.Range(0, 1, 0, 3));
+ assert.equal(doc.getValue(), ["14", "5678"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["1234", "5678"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["14", "5678"].join("\n"));
+ } ,
+
+ "test: delete new line": function() {
+ var doc = new AceAjax.Document(["1234", "5678"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.remove(new AceAjax.Range(0, 4, 1, 0));
+ assert.equal(doc.getValue(), ["12345678"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["1234", "5678"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["12345678"].join("\n"));
+ } ,
+
+ "test: delete multi line range line": function() {
+ var doc = new AceAjax.Document(["1234", "5678", "abcd"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.remove(new AceAjax.Range(0, 2, 2, 2));
+ assert.equal(doc.getValue(), ["12cd"].join("\n"));
+
+ var d = deltas.concat();
+ doc.revertDeltas(d);
+ assert.equal(doc.getValue(), ["1234", "5678", "abcd"].join("\n"));
+
+ doc.applyDeltas(d);
+ assert.equal(doc.getValue(), ["12cd"].join("\n"));
+ } ,
+
+ "test: delete full lines": function() {
+ var doc = new AceAjax.Document(["1234", "5678", "abcd"]);
+
+ var deltas = [];
+ doc.on("change", function (e) { deltas.push(e.data); });
+
+ doc.remove(new AceAjax.Range(1, 0, 3, 0));
+ assert.equal(doc.getValue(), ["1234", ""].join("\n"));
+ } ,
+
+ "test: remove lines should return the removed lines": function() {
+ var doc = new AceAjax.Document(["1234", "5678", "abcd"]);
+
+ var removed = doc.removeLines(1, 2);
+ assert.equal(removed.join("\n"), ["5678", "abcd"].join("\n"));
+ } ,
+
+ "test: should handle unix style new lines": function() {
+ var doc = new AceAjax.Document(["1", "2", "3"]);
+ assert.equal(doc.getValue(), ["1", "2", "3"].join("\n"));
+ } ,
+
+ "test: should handle windows style new lines": function() {
+ var doc = new AceAjax.Document(["1", "2", "3"].join("\r\n"));
+
+ doc.setNewLineMode("unix");
+ assert.equal(doc.getValue(), ["1", "2", "3"].join("\n"));
+ } ,
+
+ "test: set new line mode to 'windows' should use '\\r\\n' as new lines": function() {
+ var doc = new AceAjax.Document(["1", "2", "3"].join("\n"));
+ doc.setNewLineMode("windows");
+ assert.equal(doc.getValue(), ["1", "2", "3"].join("\r\n"));
+ } ,
+
+ "test: set new line mode to 'unix' should use '\\n' as new lines": function() {
+ var doc = new AceAjax.Document(["1", "2", "3"].join("\r\n"));
+
+ doc.setNewLineMode("unix");
+ assert.equal(doc.getValue(), ["1", "2", "3"].join("\n"));
+ } ,
+
+ "test: set new line mode to 'auto' should detect the incoming nl type": function() {
+ var doc = new AceAjax.Document(["1", "2", "3"].join("\n"));
+
+ doc.setNewLineMode("auto");
+ assert.equal(doc.getValue(), ["1", "2", "3"].join("\n"));
+
+ var doc = new AceAjax.Document(["1", "2", "3"].join("\r\n"));
+
+ doc.setNewLineMode("auto");
+ assert.equal(doc.getValue(), ["1", "2", "3"].join("\r\n"));
+
+ doc.replace(new AceAjax.Range(0, 0, 2, 1), ["4", "5", "6"].join("\n"));
+ assert.equal(["4", "5", "6"].join("\n"), doc.getValue());
+ } ,
+
+ "test: set value": function() {
+ var doc = new AceAjax.Document("1");
+ assert.equal("1", doc.getValue());
+
+ doc.setValue(doc.getValue());
+ assert.equal("1", doc.getValue());
+
+ var doc = new AceAjax.Document("1\n2");
+ assert.equal("1\n2", doc.getValue());
+
+ doc.setValue(doc.getValue());
+ assert.equal("1\n2", doc.getValue());
+ }
+};
\ No newline at end of file
diff --git a/ace/tests/ace-edit_session-tests.ts b/ace/tests/ace-edit_session-tests.ts
new file mode 100644
index 0000000000..12a3ce5bf3
--- /dev/null
+++ b/ace/tests/ace-edit_session-tests.ts
@@ -0,0 +1,919 @@
+///
+
+var lang: any;
+
+function createFoldTestSession() {
+ var lines = [
+ "function foo(items) {",
+ " for (var i=0; i>", [1, 2], 1);
+ } ,
+
+ "test get longest line": function() {
+ var session = new AceAjax.EditSession(["12"]);
+ session.setTabSize(4);
+ assert.equal(session.getScreenWidth(), 2);
+
+ session.doc.insertNewLine({ row: 0, column: Infinity });
+ session.doc.insertLines(1, ["123"]);
+ assert.equal(session.getScreenWidth(), 3);
+
+ session.doc.insertNewLine({ row: 0, column: Infinity });
+ session.doc.insertLines(1, ["\t\t"]);
+
+ assert.equal(session.getScreenWidth(), 8);
+
+ session.setTabSize(2);
+ assert.equal(session.getScreenWidth(), 4);
+ } ,
+
+ "test issue 83": function() {
+ var session = new AceAjax.EditSession("");
+ var editor = new AceAjax.Editor(null, session);
+ var document = session.getDocument();
+
+ session.setUseWrapMode(true);
+
+ document.insertLines(0, ["a", "b"]);
+ document.insertLines(2, ["c", "d"]);
+ document.removeLines(1, 2);
+ } ,
+
+ "test wrapMode init has to create wrapData array": function() {
+ var session = new AceAjax.EditSession("foo bar\nfoo bar");
+ var editor = new AceAjax.Editor(null, session);
+ var document = session.getDocument();
+
+ session.setUseWrapMode(true);
+ session.setWrapLimitRange(3, 3);
+ session.adjustWrapLimit(80);
+ } ,
+
+ "test first line blank with wrap": function() {
+ var session = new AceAjax.EditSession("\nfoo");
+ session.setUseWrapMode(true);
+ assert.equal(session.doc.getValue(), ["", "foo"].join("\n"));
+ } ,
+
+ "test first line blank with wrap 2": function() {
+ var session = new AceAjax.EditSession("");
+ session.setUseWrapMode(true);
+ session.setValue("\nfoo");
+
+ assert.equal(session.doc.getValue(), ["", "foo"].join("\n"));
+ } ,
+
+ "test fold getFoldDisplayLine": function() {
+ var session = createFoldTestSession();
+ function assertDisplayLine(foldLine, str) {
+ var line = session.getLine(foldLine.end.row);
+ var displayLine =
+ session.getFoldDisplayLine(foldLine, foldLine.end.row, line.length);
+ assert.equal(displayLine, str);
+ }
+ } ,
+
+ "test foldLine idxToPosition": function() {
+ var session = createFoldTestSession();
+
+ function assertIdx2Pos(foldLineIdx, idx, row, column) {
+ var foldLine = null;
+ assert.position(foldLine.idxToPosition(idx), row, column);
+ }
+
+ // "function foo(items) {",
+ // " for (var i=0; i
+
+exports = {
+
+ setUp: function(next) {
+ this.session1 = new AceAjax.EditSession(["abc", "def"]);
+ this.session2 = new AceAjax.EditSession(["ghi", "jkl"]);
+
+
+ var editor = new AceAjax.Editor(null);
+ next();
+ } ,
+
+ "test: change document": function() {
+ var editor = new AceAjax.Editor(null);
+
+ editor.setSession(this.session1);
+ assert.equal(editor.getSession(), this.session1);
+
+ editor.setSession(this.session2);
+ assert.equal(editor.getSession(), this.session2);
+ } ,
+
+ "test: only changes to the new document should have effect": function () {
+ var editor = new AceAjax.Editor(null);
+
+ var called = false;
+ editor.onDocumentChange = function () {
+ called = true;
+ };
+
+ editor.setSession(this.session1);
+ editor.setSession(this.session2);
+
+ this.session1.duplicateLines(0, 0);
+ assert.notOk(called);
+
+ this.session2.duplicateLines(0, 0);
+ assert.ok(called);
+ } ,
+
+ "test: should use cursor of new document": function () {
+ var editor = new AceAjax.Editor(null);
+
+ this.session1.getSelection().moveCursorTo(0, 1);
+ this.session2.getSelection().moveCursorTo(1, 0);
+
+ editor.setSession(this.session1);
+ assert.position(editor.getCursorPosition(), 0, 1);
+
+ editor.setSession(this.session2);
+ assert.position(editor.getCursorPosition(), 1, 0);
+ } ,
+
+ "test: only changing the cursor of the new doc should not have an effect": function () {
+ var editor = new AceAjax.Editor(null);
+
+ editor.onCursorChange = function () {
+ called = true;
+ };
+
+ editor.setSession(this.session1);
+ editor.setSession(this.session2);
+ assert.position(editor.getCursorPosition(), 0, 0);
+
+ var called = false;
+ this.session1.getSelection().moveCursorTo(0, 1);
+ assert.position(editor.getCursorPosition(), 0, 0);
+ assert.notOk(called);
+
+ this.session2.getSelection().moveCursorTo(1, 1);
+ assert.position(editor.getCursorPosition(), 1, 1);
+ assert.ok(called);
+ } ,
+
+ "test: should use selection of new document": function () {
+ var editor = new AceAjax.Editor(null);
+
+ this.session1.getSelection().selectTo(0, 1);
+ this.session2.getSelection().selectTo(1, 0);
+
+ editor.setSession(this.session1);
+ assert.position(editor.getSelection().getSelectionLead(), 0, 1);
+
+ editor.setSession(this.session2);
+ assert.position(editor.getSelection().getSelectionLead(), 1, 0);
+ } ,
+
+ "test: only changing the selection of the new doc should not have an effect": function () {
+ var editor = new AceAjax.Editor(null);
+
+ editor.onSelectionChange = function () {
+ called = true;
+ };
+
+ editor.setSession(this.session1);
+ editor.setSession(this.session2);
+ assert.position(editor.getSelection().getSelectionLead(), 0, 0);
+
+ var called = false;
+ this.session1.getSelection().selectTo(0, 1);
+ assert.position(editor.getSelection().getSelectionLead(), 0, 0);
+ assert.notOk(called);
+
+ this.session2.getSelection().selectTo(1, 1);
+ assert.position(editor.getSelection().getSelectionLead(), 1, 1);
+ assert.ok(called);
+ } ,
+
+ "test: should use mode of new document": function () {
+ var editor = new AceAjax.Editor(null);
+
+ editor.onChangeMode = function () {
+ called = true;
+ };
+ editor.setSession(this.session1);
+ editor.setSession(this.session2);
+
+ var called = false;
+ this.session1.setMode(new Text());
+ assert.notOk(called);
+
+ this.session2.setMode(null);
+ assert.ok(called);
+ } ,
+
+ "test: should use stop worker of old document": function (next) {
+ var editor = new AceAjax.Editor(null);
+
+ var self = this;
+
+ // 1. Open an editor and set the session to CssMode
+ self.editor.setSession(self.session1);
+ self.session1.setMode(null);
+
+ // 2. Add a line or two of valid CSS.
+ self.session1.setValue("DIV { color: red; }");
+
+ // 3. Clear the session value.
+ self.session1.setValue("");
+
+ // 4. Set the session to HtmlMode
+ self.session1.setMode(null);
+
+ // 5. Try to type valid HTML
+ self.session1.insert({ row: 0, column: 0 }, "");
+
+ setTimeout(function () {
+ assert.equal(Object.keys(self.session1.getAnnotations()).length, 0);
+ next();
+ }, 600);
+ }
+};
\ No newline at end of file
diff --git a/ace/tests/ace-editor_highlight_selected_word-tests.ts b/ace/tests/ace-editor_highlight_selected_word-tests.ts
new file mode 100644
index 0000000000..7e06c8c50c
--- /dev/null
+++ b/ace/tests/ace-editor_highlight_selected_word-tests.ts
@@ -0,0 +1,214 @@
+///
+
+var lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
+ "Mauris at arcu mi, eu lobortis mauris. Quisque ut libero eget " +
+ "diam congue vehicula. Quisque ut odio ut mi aliquam tincidunt. " +
+ "Duis lacinia aliquam lorem eget eleifend. Morbi eget felis mi. " +
+ "Duis quam ligula, consequat vitae convallis volutpat, blandit " +
+ "nec neque. Nulla facilisi. Etiam suscipit lorem ac justo " +
+ "sollicitudin tristique. Phasellus ut posuere nunc. Aliquam " +
+ "scelerisque mollis felis non gravida. Vestibulum lacus sem, " +
+ "posuere non bibendum id, luctus non dolor. Aenean id metus " +
+ "lorem, vel dapibus est. Donec gravida feugiat augue nec " +
+ "accumsan.Lorem ipsum dolor sit amet, consectetur adipiscing " +
+ "elit. Nulla vulputate, velit vitae tincidunt congue, nunc " +
+ "augue accumsan velit, eu consequat turpis lectus ac orci. " +
+ "Pellentesque ornare dolor feugiat dui auctor eu varius nulla " +
+ "fermentum. Sed aliquam odio at velit lacinia vel fermentum " +
+ "felis sodales. In dignissim magna eget nunc lobortis non " +
+ "fringilla nibh ullamcorper. Donec facilisis malesuada elit " +
+ "at egestas. Etiam bibendum, diam vitae tempor aliquet, dui " +
+ "libero vehicula odio, eget bibendum mauris velit eu lorem.\n" +
+ "consectetur";
+
+function callHighlighterUpdate(session: AceAjax.IEditSession, firstRow: number, lastRow: number) {
+ var rangeCount = 0;
+ var mockMarkerLayer = { drawSingleLineMarker: function () { rangeCount++; } }
+ return rangeCount;
+}
+
+exports = {
+ setUp: function(next) {
+ var session = new AceAjax.EditSession(lipsum);
+ editor = new AceAjax.Editor(new MockRenderer(), session);
+ var selection = session.getSelection();
+ next();
+ } ,
+
+ "test: highlight selected words by default": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ assert.equal(editor.getHighlightSelectedWord(), true);
+ } ,
+
+ "test: highlight a word": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 9);
+ selection.selectWord();
+
+ var highlighter = null;
+ assert.ok(highlighter != null);
+
+ var range = selection.getRange();
+ assert.equal(session.getTextRange(range), "ipsum");
+ assert.equal(highlighter.cache.length, 0);
+ assert.equal(callHighlighterUpdate(session, 0, 0), 2);
+ } ,
+
+ "test: highlight a word and clear highlight": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 8);
+ selection.selectWord();
+
+ var range = selection.getRange();
+ assert.equal(session.getTextRange(range), "ipsum");
+ assert.equal(callHighlighterUpdate(session, 0, 0), 2);
+
+ session.highlight("");
+ assert.equal(callHighlighterUpdate(session, 0, 0), 0);
+ } ,
+
+ "test: highlight another word": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ selection.moveCursorTo(0, 14);
+ selection.selectWord();
+
+ var range = selection.getRange();
+ assert.equal(session.getTextRange(range), "dolor");
+ assert.equal(callHighlighterUpdate(session, 0, 0), 4);
+ } ,
+
+ "test: no selection, no highlight": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ selection.clearSelection();
+ assert.equal(callHighlighterUpdate(session, 0, 0), 0);
+ } ,
+
+ "test: select a word, no highlight": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ selection.moveCursorTo(0, 14);
+ selection.selectWord();
+
+ editor.setHighlightSelectedWord(false);
+
+ var range = selection.getRange();
+ assert.equal(session.getTextRange(range), "dolor");
+ assert.equal(callHighlighterUpdate(session, 0, 0), 0);
+ } ,
+
+ "test: select a word with no matches": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.setHighlightSelectedWord(true);
+
+ var currentOptions = this.search.getOptions();
+ var newOptions = {
+ wrap: true,
+ wholeWord: true,
+ caseSensitive: true,
+ needle: "Mauris"
+ };
+ this.search.set(newOptions);
+
+ var match = this.search.find(session);
+ assert.notEqual(match, null, "found a match for 'Mauris'");
+
+ this.search.set(currentOptions);
+
+ selection.setSelectionRange(match);
+
+ assert.equal(session.getTextRange(match), "Mauris");
+ assert.equal(callHighlighterUpdate(session, 0, 0), 1);
+ } ,
+
+ "test: partial word selection 1": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ selection.moveCursorTo(0, 14);
+ selection.selectWord();
+ selection.selectLeft();
+
+ var range = selection.getRange();
+ assert.equal(session.getTextRange(range), "dolo");
+ assert.equal(callHighlighterUpdate(session, 0, 0), 0);
+ } ,
+
+ "test: partial word selection 2": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ selection.moveCursorTo(0, 13);
+ selection.selectWord();
+ selection.selectRight();
+
+ var range = selection.getRange();
+ assert.equal(session.getTextRange(range), "dolor ");
+ assert.equal(callHighlighterUpdate(session, 0, 0), 0);
+ } ,
+
+ "test: partial word selection 3": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ selection.moveCursorTo(0, 14);
+ selection.selectWord();
+ selection.selectLeft();
+ selection.shiftSelection(1);
+
+ var range = selection.getRange();
+ assert.equal(session.getTextRange(range), "olor");
+ assert.equal(callHighlighterUpdate(session, 0, 0), 0);
+ } ,
+
+ "test: select last word": function () {
+ var selection = session.getSelection();
+ var session = new AceAjax.EditSession(lipsum);
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ selection.moveCursorTo(0, 1);
+
+ var currentOptions = this.search.getOptions();
+ var newOptions = {
+ wrap: true,
+ wholeWord: true,
+ caseSensitive: true,
+ backwards: true,
+ needle: "consectetur"
+ };
+ this.search.set(newOptions);
+
+ var match = this.search.find(session);
+ assert.notEqual(match, null, "found a match for 'consectetur'");
+ assert.position(match.start, 1, 0);
+
+ this.search.set(currentOptions);
+
+ selection.setSelectionRange(match);
+
+ assert.equal(session.getTextRange(match), "consectetur");
+ assert.equal(callHighlighterUpdate(session, 0, 1), 3);
+ }
+};
diff --git a/ace/tests/ace-editor_navigation-tests.ts b/ace/tests/ace-editor_navigation-tests.ts
new file mode 100644
index 0000000000..c97ee0cd21
--- /dev/null
+++ b/ace/tests/ace-editor_navigation-tests.ts
@@ -0,0 +1,117 @@
+///
+
+exports = {
+ createEditSession: function (rows, cols) {
+ var line = new Array(cols + 1).join("a");
+ var text = new Array(rows).join(line + "\n") + line;
+ return new AceAjax.EditSession(text);
+ },
+
+ "test: navigate to end of file should scroll the last line into view": function () {
+ var doc = this.createEditSession(200, 10);
+ var editor = new AceAjax.Editor(new MockRenderer(), doc);
+
+ editor.navigateFileEnd();
+ var cursor = editor.getCursorPosition();
+
+ assert.ok(editor.getFirstVisibleRow() <= cursor.row);
+ assert.ok(editor.getLastVisibleRow() >= cursor.row);
+ },
+
+ "test: navigate to start of file should scroll the first row into view": function () {
+ var doc = this.createEditSession(200, 10);
+ var editor = new AceAjax.Editor(new MockRenderer(), doc);
+
+ editor.moveCursorTo(editor.getLastVisibleRow() + 20);
+ editor.navigateFileStart();
+
+ assert.equal(editor.getFirstVisibleRow(), 0);
+ },
+
+ "test: goto hidden line should scroll the line into the middle of the viewport": function () {
+ var editor = new AceAjax.Editor(new MockRenderer(), this.createEditSession(200, 5));
+
+ editor.navigateTo(0, 0);
+ editor.gotoLine(101);
+ assert.position(editor.getCursorPosition(), 100, 0);
+ assert.equal(editor.getFirstVisibleRow(), 89);
+
+ editor.navigateTo(100, 0);
+ editor.gotoLine(11);
+ assert.position(editor.getCursorPosition(), 10, 0);
+ assert.equal(editor.getFirstVisibleRow(), 0);
+
+ editor.navigateTo(100, 0);
+ editor.gotoLine(6);
+ assert.position(editor.getCursorPosition(), 5, 0);
+ assert.equal(0, editor.getFirstVisibleRow(), 0);
+
+ editor.navigateTo(100, 0);
+ editor.gotoLine(1);
+ assert.position(editor.getCursorPosition(), 0, 0);
+ assert.equal(editor.getFirstVisibleRow(), 0);
+
+ editor.navigateTo(0, 0);
+ editor.gotoLine(191);
+ assert.position(editor.getCursorPosition(), 190, 0);
+ assert.equal(editor.getFirstVisibleRow(), 179);
+
+ editor.navigateTo(0, 0);
+ editor.gotoLine(196);
+ assert.position(editor.getCursorPosition(), 195, 0);
+ assert.equal(editor.getFirstVisibleRow(), 180);
+ },
+
+ "test: goto visible line should only move the cursor and not scroll": function () {
+ var editor = new AceAjax.Editor(new MockRenderer(), this.createEditSession(200, 5));
+
+ editor.navigateTo(0, 0);
+ editor.gotoLine(12);
+ assert.position(editor.getCursorPosition(), 11, 0);
+ assert.equal(editor.getFirstVisibleRow(), 0);
+
+ editor.navigateTo(30, 0);
+ editor.gotoLine(33);
+ assert.position(editor.getCursorPosition(), 32, 0);
+ assert.equal(editor.getFirstVisibleRow(), 30);
+ },
+
+ "test: navigate from the end of a long line down to a short line and back should maintain the curser column": function () {
+ var editor = new AceAjax.Editor(new MockRenderer(), new AceAjax.EditSession(["123456", "1"]));
+
+ editor.navigateTo(0, 6);
+ assert.position(editor.getCursorPosition(), 0, 6);
+
+ editor.navigateDown();
+ assert.position(editor.getCursorPosition(), 1, 1);
+
+ editor.navigateUp();
+ assert.position(editor.getCursorPosition(), 0, 6);
+ },
+
+ "test: reset desired column on navigate left or right": function () {
+ var editor = new AceAjax.Editor(new MockRenderer(), new AceAjax.EditSession(["123456", "12"]));
+
+ editor.navigateTo(0, 6);
+ assert.position(editor.getCursorPosition(), 0, 6);
+
+ editor.navigateDown();
+ assert.position(editor.getCursorPosition(), 1, 2);
+
+ editor.navigateLeft();
+ assert.position(editor.getCursorPosition(), 1, 1);
+
+ editor.navigateUp();
+ assert.position(editor.getCursorPosition(), 0, 1);
+ },
+
+ "test: typing text should update the desired column": function () {
+ var editor = new AceAjax.Editor(new MockRenderer(), new AceAjax.EditSession(["1234", "1234567890"]));
+
+ editor.navigateTo(0, 3);
+ editor.insert("juhu");
+
+ editor.navigateDown();
+ assert.position(editor.getCursorPosition(), 1, 7);
+ }
+};
\ No newline at end of file
diff --git a/ace/tests/ace-editor_text_edit-tests.ts b/ace/tests/ace-editor_text_edit-tests.ts
new file mode 100644
index 0000000000..9d618acc67
--- /dev/null
+++ b/ace/tests/ace-editor_text_edit-tests.ts
@@ -0,0 +1,498 @@
+///
+
+exports = {
+ "test: delete line from the middle": function () {
+ var session = new AceAjax.EditSession(["a", "b", "c", "d"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(1, 1);
+ editor.removeLines();
+
+ assert.equal(session.toString(), "a\nc\nd");
+ assert.position(editor.getCursorPosition(), 1, 0);
+
+ editor.removeLines();
+
+ assert.equal(session.toString(), "a\nd");
+ assert.position(editor.getCursorPosition(), 1, 0);
+
+ editor.removeLines();
+
+ assert.equal(session.toString(), "a");
+ assert.position(editor.getCursorPosition(), 0, 1);
+
+ editor.removeLines();
+
+ assert.equal(session.toString(), "");
+ assert.position(editor.getCursorPosition(), 0, 0);
+ },
+
+ "test: delete multiple selected lines": function () {
+ var session = new AceAjax.EditSession(["a", "b", "c", "d"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(1, 1);
+ editor.getSelection().selectDown();
+
+ editor.removeLines();
+ assert.equal(session.toString(), "a\nd");
+ assert.position(editor.getCursorPosition(), 1, 0);
+ },
+
+ "test: delete first line": function () {
+ var session = new AceAjax.EditSession(["a", "b", "c"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.removeLines();
+
+ assert.equal(session.toString(), "b\nc");
+ assert.position(editor.getCursorPosition(), 0, 0);
+ },
+
+ "test: delete last should also delete the new line of the previous line": function () {
+ var session = new AceAjax.EditSession(["a", "b", "c", ""].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(3, 0);
+
+ editor.removeLines();
+ assert.equal(session.toString(), "a\nb\nc");
+ assert.position(editor.getCursorPosition(), 2, 1);
+
+ editor.removeLines();
+ assert.equal(session.toString(), "a\nb");
+ assert.position(editor.getCursorPosition(), 1, 1);
+ },
+
+ "test: indent block": function () {
+ var session = new AceAjax.EditSession(["a12345", "b12345", "c12345"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(1, 3);
+ editor.getSelection().selectDown();
+
+ editor.indent();
+
+ assert.equal(["a12345", " b12345", " c12345"].join("\n"), session.toString());
+
+ assert.position(editor.getCursorPosition(), 2, 7);
+
+ var range = editor.getSelectionRange();
+ assert.position(range.start, 1, 7);
+ assert.position(range.end, 2, 7);
+ },
+
+ "test: indent selected lines": function () {
+ var session = new AceAjax.EditSession(["a12345", "b12345", "c12345"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(1, 0);
+ editor.getSelection().selectDown();
+
+ editor.indent();
+ assert.equal(["a12345", " b12345", "c12345"].join("\n"), session.toString());
+ },
+
+ "test: no auto indent if cursor is before the {": function () {
+ var session = new AceAjax.EditSession("{", new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 0);
+ editor.onTextInput("\n");
+ assert.equal(["", "{"].join("\n"), session.toString());
+ },
+
+ "test: outdent block": function () {
+ var session = new AceAjax.EditSession([" a12345", " b12345", " c12345"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 5);
+ editor.getSelection().selectDown();
+ editor.getSelection().selectDown();
+
+ editor.blockOutdent();
+ assert.equal(session.toString(), [" a12345", "b12345", " c12345"].join("\n"));
+
+ assert.position(editor.getCursorPosition(), 2, 1);
+
+ var range = editor.getSelectionRange();
+ assert.position(range.start, 0, 1);
+ assert.position(range.end, 2, 1);
+
+ editor.blockOutdent();
+ assert.equal(session.toString(), ["a12345", "b12345", "c12345"].join("\n"));
+
+ var range = editor.getSelectionRange();
+ assert.position(range.start, 0, 0);
+ assert.position(range.end, 2, 0);
+ },
+
+ "test: outent without a selection should update cursor": function () {
+ var session = new AceAjax.EditSession(" 12");
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 3);
+ editor.blockOutdent(" ");
+
+ assert.equal(session.toString(), " 12");
+ assert.position(editor.getCursorPosition(), 0, 0);
+ },
+
+ "test: comment lines should perserve selection": function () {
+ var session = new AceAjax.EditSession([" abc", "cde"].join("\n"), new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 2);
+ editor.getSelection().selectDown();
+ editor.toggleCommentLines();
+
+ assert.equal(["// abc", "//cde"].join("\n"), session.toString());
+
+ var selection = editor.getSelectionRange();
+ assert.position(selection.start, 0, 4);
+ assert.position(selection.end, 1, 4);
+ },
+
+ "test: uncomment lines should perserve selection": function () {
+ var session = new AceAjax.EditSession(["// abc", "//cde"].join("\n"), new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 1);
+ editor.getSelection().selectDown();
+ editor.getSelection().selectRight();
+ editor.getSelection().selectRight();
+
+ editor.toggleCommentLines();
+
+ assert.equal([" abc", "cde"].join("\n"), session.toString());
+ assert.range(editor.getSelectionRange(), 0, 0, 1, 1);
+ },
+
+ "test: toggle comment lines twice should return the original text": function () {
+ var session = new AceAjax.EditSession([" abc", "cde", "fg"], new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 0);
+ editor.getSelection().selectDown();
+ editor.getSelection().selectDown();
+
+ editor.toggleCommentLines();
+ editor.toggleCommentLines();
+
+ assert.equal([" abc", "cde", "fg"].join("\n"), session.toString());
+ },
+
+
+ "test: comment lines - if the selection end is at the line start it should stay there": function () {
+ //select down
+ var session = new AceAjax.EditSession(["abc", "cde"].join("\n"), new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 0);
+ editor.getSelection().selectDown();
+
+ editor.toggleCommentLines();
+ assert.range(editor.getSelectionRange(), 0, 2, 1, 0);
+
+ // select up
+ var session = new AceAjax.EditSession(["abc", "cde"].join("\n"), new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(1, 0);
+ editor.getSelection().selectUp();
+
+ editor.toggleCommentLines();
+ assert.range(editor.getSelectionRange(), 0, 2, 1, 0);
+ },
+
+ "test: move lines down should select moved lines": function () {
+ var session = new AceAjax.EditSession(["11", "22", "33", "44"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(0, 1);
+ editor.getSelection().selectDown();
+
+ editor.moveLinesDown();
+ assert.equal(["33", "11", "22", "44"].join("\n"), session.toString());
+ assert.position(editor.getCursorPosition(), 1, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 1, 0);
+
+ editor.moveLinesDown();
+ assert.equal(["33", "44", "11", "22"].join("\n"), session.toString());
+ assert.position(editor.getCursorPosition(), 2, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 2);
+ assert.position(editor.getSelection().getSelectionLead(), 2, 0);
+
+ // moving again should have no effect
+ editor.moveLinesDown();
+ assert.equal(["33", "44", "11", "22"].join("\n"), session.toString());
+ assert.position(editor.getCursorPosition(), 2, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 2);
+ assert.position(editor.getSelection().getSelectionLead(), 2, 0);
+ },
+
+ "test: move lines up should select moved lines": function () {
+ var session = new AceAjax.EditSession(["11", "22", "33", "44"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(2, 1);
+ editor.getSelection().selectDown();
+
+ editor.moveLinesUp();
+ assert.equal(session.toString(), ["11", "33", "44", "22"].join("\n"));
+ assert.position(editor.getCursorPosition(), 1, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 1, 0);
+
+ editor.moveLinesUp();
+ assert.equal(session.toString(), ["33", "44", "11", "22"].join("\n"));
+ assert.position(editor.getCursorPosition(), 0, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 2, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 0, 0);
+ },
+
+ "test: move line without active selection should not move cursor relative to the moved line": function () {
+ var session = new AceAjax.EditSession(["11", "22", "33", "44"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(1, 1);
+ editor.clearSelection();
+
+ editor.moveLinesDown();
+ assert.equal(["11", "33", "22", "44"].join("\n"), session.toString());
+ assert.position(editor.getCursorPosition(), 2, 1);
+
+ editor.clearSelection();
+
+ editor.moveLinesUp();
+ assert.equal(["11", "22", "33", "44"].join("\n"), session.toString());
+ assert.position(editor.getCursorPosition(), 1, 1);
+ },
+
+ "test: copy lines down should select lines and place cursor at the selection start": function () {
+ var session = new AceAjax.EditSession(["11", "22", "33", "44"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(1, 1);
+ editor.getSelection().selectDown();
+
+ editor.copyLinesDown();
+ assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString());
+
+ assert.position(editor.getCursorPosition(), 3, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 5, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 3, 0);
+ },
+
+ "test: copy lines up should select lines and place cursor at the selection start": function () {
+ var session = new AceAjax.EditSession(["11", "22", "33", "44"].join("\n"));
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.moveCursorTo(1, 1);
+ editor.getSelection().selectDown();
+
+ editor.copyLinesUp();
+ assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString());
+
+ assert.position(editor.getCursorPosition(), 1, 0);
+ assert.position(editor.getSelection().getSelectionAnchor(), 3, 0);
+ assert.position(editor.getSelection().getSelectionLead(), 1, 0);
+ },
+
+ "test: input a tab with soft tab should convert it to spaces": function () {
+ var session = new AceAjax.EditSession("");
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ session.setTabSize(2);
+ session.setUseSoftTabs(true);
+
+ editor.onTextInput("\t");
+ assert.equal(session.toString(), " ");
+
+ session.setTabSize(5);
+ editor.onTextInput("\t");
+ assert.equal(session.toString(), " ");
+ },
+
+ "test: input tab without soft tabs should keep the tab character": function () {
+ var session = new AceAjax.EditSession("");
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ session.setUseSoftTabs(false);
+
+ editor.onTextInput("\t");
+ assert.equal(session.toString(), "\t");
+ },
+
+ "test: undo/redo for delete line": function () {
+ var session = new AceAjax.EditSession(["111", "222", "333"]);
+ var undoManager = new AceAjax.UndoManager();
+ session.setUndoManager(undoManager);
+
+ var initialText = session.toString();
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ editor.removeLines();
+ var step1 = session.toString();
+ assert.equal(step1, "222\n333");
+
+ editor.removeLines();
+ var step2 = session.toString();
+ assert.equal(step2, "333");
+
+ editor.removeLines();
+ var step3 = session.toString();
+ assert.equal(step3, "");
+
+ undoManager.undo();
+ assert.equal(session.toString(), step2);
+
+ undoManager.undo();
+ assert.equal(session.toString(), step1);
+
+ undoManager.undo();
+ assert.equal(session.toString(), initialText);
+
+ undoManager.undo();
+ assert.equal(session.toString(), initialText);
+ },
+
+ "test: remove left should remove character left of the cursor": function () {
+ var session = new AceAjax.EditSession(["123", "456"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 1);
+ editor.remove("left");
+ assert.equal(session.toString(), "123\n56");
+ },
+
+ "test: remove left should remove line break if cursor is at line start": function () {
+ var session = new AceAjax.EditSession(["123", "456"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 0);
+ editor.remove("left");
+ assert.equal(session.toString(), "123456");
+ },
+
+ "test: remove left should remove tabsize spaces if cursor is on a tab stop and preceeded by spaces": function () {
+ var session = new AceAjax.EditSession(["123", " 456"]);
+ session.setUseSoftTabs(true);
+ session.setTabSize(4);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 8);
+ editor.remove("left");
+ assert.equal(session.toString(), "123\n 456");
+ },
+
+ "test: transpose at line start should be a noop": function () {
+ var session = new AceAjax.EditSession(["123", "4567", "89"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 0);
+ editor.transposeLetters();
+
+ assert.equal(session.getValue(), ["123", "4567", "89"].join("\n"));
+ },
+
+ "test: transpose in line should swap the charaters before and after the cursor": function () {
+ var session = new AceAjax.EditSession(["123", "4567", "89"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 2);
+ editor.transposeLetters();
+
+ assert.equal(session.getValue(), ["123", "4657", "89"].join("\n"));
+ },
+
+ "test: transpose at line end should swap the last two characters": function () {
+ var session = new AceAjax.EditSession(["123", "4567", "89"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 4);
+ editor.transposeLetters();
+
+ assert.equal(session.getValue(), ["123", "4576", "89"].join("\n"));
+ },
+
+ "test: transpose with non empty selection should be a noop": function () {
+ var session = new AceAjax.EditSession(["123", "4567", "89"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 1);
+ editor.getSelection().selectRight();
+ editor.transposeLetters();
+
+ assert.equal(session.getValue(), ["123", "4567", "89"].join("\n"));
+ },
+
+ "test: transpose should move the cursor behind the last swapped character": function () {
+ var session = new AceAjax.EditSession(["123", "4567", "89"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 2);
+ editor.transposeLetters();
+ assert.position(editor.getCursorPosition(), 1, 3);
+ },
+
+ "test: remove to line end": function () {
+ var session = new AceAjax.EditSession(["123", "4567", "89"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 2);
+ editor.removeToLineEnd();
+ assert.equal(session.getValue(), ["123", "45", "89"].join("\n"));
+ },
+
+ "test: remove to line end at line end should remove the new line": function () {
+ var session = new AceAjax.EditSession(["123", "4567", "89"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 4);
+ editor.removeToLineEnd();
+ assert.position(editor.getCursorPosition(), 1, 4);
+ assert.equal(session.getValue(), ["123", "456789"].join("\n"));
+ },
+
+ "test: transform selection to uppercase": function () {
+ var session = new AceAjax.EditSession(["ajax", "dot", "org"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 0);
+ editor.getSelection().selectLineEnd();
+ editor.toUpperCase()
+ assert.equal(session.getValue(), ["ajax", "DOT", "org"].join("\n"));
+ },
+
+ "test: transform word to uppercase": function () {
+ var session = new AceAjax.EditSession(["ajax", "dot", "org"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 0);
+ editor.toUpperCase()
+ assert.equal(session.getValue(), ["ajax", "DOT", "org"].join("\n"));
+ assert.position(editor.getCursorPosition(), 1, 0);
+ },
+
+ "test: transform selection to lowercase": function () {
+ var session = new AceAjax.EditSession(["AJAX", "DOT", "ORG"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 0);
+ editor.getSelection().selectLineEnd();
+ editor.toLowerCase()
+ assert.equal(session.getValue(), ["AJAX", "dot", "ORG"].join("\n"));
+ },
+
+ "test: transform word to lowercase": function () {
+ var session = new AceAjax.EditSession(["AJAX", "DOT", "ORG"]);
+
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ editor.moveCursorTo(1, 0);
+ editor.toLowerCase()
+ assert.equal(session.getValue(), ["AJAX", "dot", "ORG"].join("\n"));
+ assert.position(editor.getCursorPosition(), 1, 0);
+ }
+};
\ No newline at end of file
diff --git a/ace/tests/ace-multi_select-tests.ts b/ace/tests/ace-multi_select-tests.ts
new file mode 100644
index 0000000000..ade1493e23
--- /dev/null
+++ b/ace/tests/ace-multi_select-tests.ts
@@ -0,0 +1,111 @@
+///
+
+var exec = function (name?, times?, args?) {
+ do {
+ editor.commands.exec(name, editor, args);
+ } while (times-- > 1)
+};
+var testRanges = function (str) {
+ assert.equal(editor.selection.getAllRanges() + "", str + "");
+}
+
+exports = {
+
+ name: "ACE multi_select.js",
+
+ "test: multiselect editing": function() {
+ var doc = new AceAjax.EditSession([
+ "w1.w2",
+ " wtt.w",
+ " wtt.w"
+ ]);
+ editor = new AceAjax.Editor(new MockRenderer(), doc);
+
+ editor.navigateFileEnd();
+ exec("selectMoreBefore", 3);
+ assert.ok(editor.inMultiSelectMode);
+ assert.equal(editor.selection.getAllRanges().length, 4);
+
+ var newLine = editor.session.getDocument().getNewLineCharacter();
+ var copyText = "wwww".split("").join(newLine);
+ assert.equal(editor.getCopyText(), copyText);
+ exec("insertstring", 1, "a");
+ exec("backspace", 2);
+ assert.equal(editor.session.getValue(), "w1.w2\ntt\ntt");
+ assert.equal(editor.selection.getAllRanges().length, 4);
+
+ exec("selectall");
+ assert.ok(!editor.inMultiSelectMode);
+ //assert.equal(editor.selection.getAllRanges().length, 1);
+ } ,
+
+ "test: multiselect navigation": function() {
+ var doc = new AceAjax.EditSession([
+ "w1.w2",
+ " wtt.w",
+ " wtt.we"
+ ]);
+ editor = new AceAjax.Editor(new MockRenderer(), doc);
+
+ editor.selectMoreLines(1);
+ testRanges("Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]");
+ assert.ok(editor.inMultiSelectMode);
+
+ exec("golinedown");
+ exec("gotolineend");
+ testRanges("Range: [1/9] -> [1/9],Range: [2/10] -> [2/10]");
+ exec("selectwordleft");
+
+ testRanges("Range: [1/8] -> [1/9],Range: [2/8] -> [2/10]");
+ exec("golinedown", 2);
+ assert.ok(!editor.inMultiSelectMode);
+ } ,
+
+ "test: multiselect session change": function() {
+ var doc = new AceAjax.EditSession([
+ "w1.w2",
+ " wtt.w",
+ " wtt.w"
+ ]);
+ editor = new AceAjax.Editor(new MockRenderer(), doc);
+
+ editor.selectMoreLines(1)
+ testRanges("Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]");
+ assert.ok(editor.inMultiSelectMode);
+
+ var doc2 = new AceAjax.EditSession(["w1"]);
+ editor.setSession(doc2);
+ assert.ok(!editor.inMultiSelectMode);
+
+ editor.setSession(doc);
+ assert.ok(editor.inMultiSelectMode);
+ } ,
+
+ "test: multiselect addRange": function() {
+ var doc = new AceAjax.EditSession([
+ "w1.w2",
+ " wtt.w",
+ " wtt.w"
+ ]);
+ editor = new AceAjax.Editor(new MockRenderer(), doc);
+
+ var selection = editor.selection;
+
+ var range1 = new AceAjax.Range(0, 2, 0, 4);
+ editor.selection.fromOrientedRange(range1);
+
+ var range2 = new AceAjax.Range(0, 3, 0, 4);
+ selection.addRange(range2);
+ assert.ok(!editor.inMultiSelectMode);
+ assert.ok(range2.isEqual(editor.selection.getRange()));
+
+ var range3 = new AceAjax.Range(0, 1, 0, 1);
+ selection.addRange(range3);
+ assert.ok(editor.inMultiSelectMode);
+ testRanges([range3, range2]);
+
+ var range4 = new AceAjax.Range(0, 0, 4, 0);
+ selection.addRange(range4);
+ assert.ok(!editor.inMultiSelectMode);
+ }
+};
diff --git a/ace/tests/ace-placeholder-tests.ts b/ace/tests/ace-placeholder-tests.ts
new file mode 100644
index 0000000000..124554cf7d
--- /dev/null
+++ b/ace/tests/ace-placeholder-tests.ts
@@ -0,0 +1,106 @@
+///
+
+exports = {
+
+ "test: simple at the end appending of text": function () {
+ var session = new AceAjax.EditSession("var a = 10;\nconsole.log(a, a);", new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ new AceAjax.PlaceHolder(session, 1, { row: 0, column: 4 }, [{ row: 1, column: 12 }, { row: 1, column: 15 }]);
+
+ editor.moveCursorTo(0, 5);
+ editor.insert('b');
+ assert.equal(session.doc.getValue(), "var ab = 10;\nconsole.log(ab, ab);");
+ editor.insert('cd');
+ assert.equal(session.doc.getValue(), "var abcd = 10;\nconsole.log(abcd, abcd);");
+ editor.remove('left');
+ editor.remove('left');
+ editor.remove('left');
+ assert.equal(session.doc.getValue(), "var a = 10;\nconsole.log(a, a);");
+ },
+
+ "test: inserting text outside placeholder": function () {
+ var session = new AceAjax.EditSession("var a = 10;\nconsole.log(a, a);\n", new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ new AceAjax.PlaceHolder(session, 1, { row: 0, column: 4 }, [{ row: 1, column: 12 }, { row: 1, column: 15 }]);
+
+ editor.moveCursorTo(2, 0);
+ editor.insert('b');
+ assert.equal(session.doc.getValue(), "var a = 10;\nconsole.log(a, a);\nb");
+ },
+
+ "test: insertion at the beginning": function (next) {
+ var session = new AceAjax.EditSession("var a = 10;\nconsole.log(a, a);", new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ var p = new AceAjax.PlaceHolder(session, 1, { row: 0, column: 4 }, [{ row: 1, column: 12 }, { row: 1, column: 15 }]);
+
+ editor.moveCursorTo(0, 4);
+ editor.insert('$');
+ assert.equal(session.doc.getValue(), "var $a = 10;\nconsole.log($a, $a);");
+ editor.moveCursorTo(0, 4);
+ // Have to put this in a setTimeout because the anchor is only fixed later.
+ setTimeout(function () {
+ editor.insert('v');
+ assert.equal(session.doc.getValue(), "var v$a = 10;\nconsole.log(v$a, v$a);");
+ next();
+ }, 10);
+ },
+
+ "test: detaching placeholder": function () {
+ var session = new AceAjax.EditSession("var a = 10;\nconsole.log(a, a);", new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ var p = new AceAjax.PlaceHolder(session, 1, { row: 0, column: 4 }, [{ row: 1, column: 12 }, { row: 1, column: 15 }]);
+
+ editor.moveCursorTo(0, 5);
+ editor.insert('b');
+ assert.equal(session.doc.getValue(), "var ab = 10;\nconsole.log(ab, ab);");
+ p.detach();
+ editor.insert('cd');
+ assert.equal(session.doc.getValue(), "var abcd = 10;\nconsole.log(ab, ab);");
+ },
+
+ "test: events": function () {
+ var session = new AceAjax.EditSession("var a = 10;\nconsole.log(a, a);", new JavaScriptMode());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+
+ var p = new AceAjax.PlaceHolder(session, 1, { row: 0, column: 4 }, [{ row: 1, column: 12 }, { row: 1, column: 15 }]);
+ var entered = false;
+ var left = false;
+ p.on("cursorEnter", function () {
+ entered = true;
+ });
+ p.on("cursorLeave", function () {
+ left = true;
+ });
+
+ editor.moveCursorTo(0, 0);
+ editor.moveCursorTo(0, 4);
+ p.onCursorChange(); // Have to do this by hand because moveCursorTo doesn't trigger the event
+ assert.ok(entered);
+ editor.moveCursorTo(1, 0);
+ p.onCursorChange(); // Have to do this by hand because moveCursorTo doesn't trigger the event
+ assert.ok(left);
+ },
+
+ "test: cancel": function (next) {
+ var session = new AceAjax.EditSession("var a = 10;\nconsole.log(a, a);", new JavaScriptMode());
+ session.setUndoManager(new AceAjax.UndoManager());
+ var editor = new AceAjax.Editor(new MockRenderer(), session);
+ var p = new AceAjax.PlaceHolder(session, 1, { row: 0, column: 4 }, [{ row: 1, column: 12 }, { row: 1, column: 15 }]);
+
+ editor.moveCursorTo(0, 5);
+ editor.insert('b');
+ editor.insert('cd');
+ editor.remove('left');
+ assert.equal(session.doc.getValue(), "var abc = 10;\nconsole.log(abc, abc);");
+ // Wait a little for the changes to enter the undo stack
+ setTimeout(function () {
+ p.cancel();
+ assert.equal(session.doc.getValue(), "var a = 10;\nconsole.log(a, a);");
+ next();
+ }, 80);
+ }
+};
diff --git a/ace/tests/ace-range_list-tests.ts b/ace/tests/ace-range_list-tests.ts
new file mode 100644
index 0000000000..83f3c8a91c
--- /dev/null
+++ b/ace/tests/ace-range_list-tests.ts
@@ -0,0 +1,117 @@
+///
+
+function flatten(rangeList) {
+ var points = [];
+ rangeList.ranges.forEach(function (r) {
+ points.push(r.start.row, r.start.column, r.end.row, r.end.column)
+ })
+ return points;
+}
+function testRangeList(rangeList, points) {
+ assert.equal("" + flatten(rangeList), "" + points);
+}
+
+exports = {
+
+ name: "ACE range_list.js",
+
+ "test: rangeList pointIndex": function() {
+ var rangeList = new AceAjax.RangeList();
+ rangeList.ranges = [
+ new AceAjax.Range(1, 2, 3, 4),
+ new AceAjax.Range(4, 2, 5, 4),
+ new AceAjax.Range(8, 8, 9, 9)
+ ];
+
+ assert.equal(rangeList.pointIndex({ row: 0, column: 1 }), -1);
+ assert.equal(rangeList.pointIndex({ row: 1, column: 2 }), 0);
+ assert.equal(rangeList.pointIndex({ row: 1, column: 3 }), 0);
+ assert.equal(rangeList.pointIndex({ row: 3, column: 4 }), 0);
+ assert.equal(rangeList.pointIndex({ row: 4, column: 1 }), -2);
+ assert.equal(rangeList.pointIndex({ row: 5, column: 1 }), 1);
+ assert.equal(rangeList.pointIndex({ row: 8, column: 9 }), 2);
+ assert.equal(rangeList.pointIndex({ row: 18, column: 9 }), -4);
+ } ,
+
+ "test: rangeList add": function() {
+ var rangeList = new AceAjax.RangeList();
+ rangeList.addList([
+ new AceAjax.Range(9, 0, 9, 1),
+ new AceAjax.Range(1, 2, 3, 4),
+ new AceAjax.Range(8, 8, 9, 9),
+ new AceAjax.Range(4, 2, 5, 4),
+ new AceAjax.Range(3, 20, 3, 24),
+ new AceAjax.Range(6, 6, 7, 7)
+ ]);
+ assert.equal(rangeList.ranges.length, 5);
+
+ rangeList.add(new AceAjax.Range(1, 2, 3, 5));
+ assert.range(rangeList.ranges[0], 1, 2, 3, 5);
+ assert.equal(rangeList.ranges.length, 5);
+
+ rangeList.add(new AceAjax.Range(7, 7, 7, 7));
+ assert.range(rangeList.ranges[3], 7, 7, 7, 7);
+ rangeList.add(new AceAjax.Range(7, 8, 7, 8));
+ assert.range(rangeList.ranges[4], 7, 8, 7, 8);
+ } ,
+
+ "test: rangeList add empty": function() {
+ var rangeList = new AceAjax.RangeList();
+ rangeList.addList([
+ new AceAjax.Range(7, 10, 7, 10),
+ new AceAjax.Range(9, 10, 9, 10),
+ new AceAjax.Range(8, 10, 8, 10)
+ ]);
+ assert.equal(rangeList.ranges.length, 3);
+
+ rangeList.add(new AceAjax.Range(9, 10, 9, 10));
+ testRangeList(rangeList, [7, 10, 7, 10, 8, 10, 8, 10, 9, 10, 9, 10]);
+ } ,
+
+ "test: rangeList merge": function() {
+ var rangeList = new AceAjax.RangeList();
+ rangeList.addList([
+ new AceAjax.Range(1, 2, 3, 4),
+ new AceAjax.Range(4, 2, 5, 4),
+ new AceAjax.Range(6, 6, 7, 7),
+ new AceAjax.Range(8, 8, 9, 9)
+ ]);
+ var removed = [];
+
+ assert.equal(rangeList.ranges.length, 4);
+
+ rangeList.ranges[1].end.row = 7;
+ removed = rangeList.merge();
+ assert.equal(removed.length, 1);
+ assert.range(rangeList.ranges[1], 4, 2, 7, 7);
+ assert.equal(rangeList.ranges.length, 3);
+
+ rangeList.ranges[0].end.row = 10;
+ removed = rangeList.merge();
+ assert.range(rangeList.ranges[0], 1, 2, 10, 4);
+ assert.equal(removed.length, 2);
+ assert.equal(rangeList.ranges.length, 1);
+
+ rangeList.ranges.push(new AceAjax.Range(10, 10, 10, 10));
+ rangeList.ranges.push(new AceAjax.Range(10, 10, 10, 10));
+ removed = rangeList.merge();
+ assert.equal(rangeList.ranges.length, 2);
+ } ,
+
+ "test: rangeList remove": function() {
+ var rangeList = new AceAjax.RangeList();
+ var list = [
+ new AceAjax.Range(1, 2, 3, 4),
+ new AceAjax.Range(4, 2, 5, 4),
+ new AceAjax.Range(6, 6, 7, 7),
+ new AceAjax.Range(8, 8, 9, 9)
+ ];
+ rangeList.addList(list);
+ assert.equal(rangeList.ranges.length, 4);
+ rangeList.substractPoint({ row: 1, column: 2 });
+ assert.equal(rangeList.ranges.length, 3);
+ rangeList.substractPoint({ row: 6, column: 7 });
+ assert.equal(rangeList.ranges.length, 2);
+ }
+
+};