import * as assert from 'assert'; import { ModeName } from '../src/mode/mode' import { Position } from '../src/motion/position'; import { ModeHandler } from '../src/mode/modeHandler'; import { TextEditor } from '../src/textEditor'; import { assertEqualLines } from './testUtils'; interface TestObject { start: string[], keysPressed: string, end: string[], endMode?: ModeName } class TestObjectHelper { startPosition = new Position(0, 0); endPosition = new Position(0, 0); private _isValid = false; constructor(private _testObject: TestObject) { this._parse(_testObject); } public get isValid(): boolean { return this._isValid; } private _setStartCursorPosition(lines: string[]): boolean { let result = this._getCursorPosition(lines); this.startPosition = result.position; return result.success; } private _setEndCursorPosition(lines: string[]): boolean { let result = this._getCursorPosition(lines); this.endPosition = result.position; return result.success; } private _getCursorPosition(lines: string[]): { success: boolean; position: Position} { let ret = { success: false, position: new Position(0, 0) }; for (let i = 0; i < lines.length; i++) { let columnIdx = lines[i].indexOf('|'); if (columnIdx >= 0) { ret.position = ret.position.setLocation(i, columnIdx); ret.success = true; } } return ret; } private _parse(t: TestObject): void { if (!this._setStartCursorPosition(t.start)) { this._isValid = false; return; } if (!this._setEndCursorPosition(t.end)) { this._isValid = false; return; } this._isValid = true; } public asVimInputText(): string[] { let ret = 'i' + this._testObject.start.join('\n').replace('|', ''); return ret.split(''); } public asVimOutputText(): string[] { let ret = this._testObject.end.slice(0); ret[this.endPosition.line] = ret[this.endPosition.line].replace('|', ''); return ret; } /** Returns a sequence of Vim movement characters 'hjkl' as a string array * which will move the cursor to the start position given in the test. */ public getKeyPressesToMoveToStartPosition(): string[] { let ret = ''; let h = 0, j = 0, k = 0, l = 0; let linesToMove = this.startPosition.line - (this._testObject.start.length - 1); let cursorPosAfterEsc = this._testObject.start[this._testObject.start.length - 1].replace('|', '').length - 1; let numCharsInCursorStartLine = this._testObject.start[this.startPosition.line].replace('|', '').length - 1; let columnOnStartLine = Math.min(cursorPosAfterEsc, numCharsInCursorStartLine); let charactersToMove = this.startPosition.character - columnOnStartLine; if (linesToMove > 0) { ret += Array(linesToMove + 1).join('j'); } else if (linesToMove < 0) { ret += Array(Math.abs(linesToMove) + 1).join('k'); } if (charactersToMove > 0) { ret += Array(charactersToMove + 1).join('l'); } else if (charactersToMove < 0) { ret += Array(Math.abs(charactersToMove) + 1).join('h'); } //console.log("ret is " + ret); return ret.split(''); } } async function testIt(modeHandler: ModeHandler, testObj: TestObject): Promise { let helper = new TestObjectHelper(testObj); // start: // await modeHandler.handleMultipleKeyEvents(helper.asVimInputText()); // keysPressed: // await modeHandler.handleKeyEvent(''); // move cursor to start position using 'hjkl' await modeHandler.handleMultipleKeyEvents(helper.getKeyPressesToMoveToStartPosition()); // assumes key presses are single characters for now await modeHandler.handleMultipleKeyEvents(testObj.keysPressed.split('')); // Check valid test object input assert(helper.isValid, "Missing '|' in test object."); // Check final cursor position // let actualPosition = Position.FromVSCodePosition(TextEditor.getSelection().start); let expectedPosition = helper.endPosition; assert.equal(actualPosition.line, expectedPosition.line, "Cursor LINE position is wrong."); assert.equal(actualPosition.character, expectedPosition.character, "Cursor CHARACTER position is wrong."); // end: check given end output is correct // assertEqualLines(helper.asVimOutputText()); // endMode: check end mode is correct if given if (typeof testObj.endMode !== 'undefined') { let actualMode = ModeName[modeHandler.currentMode.name].toUpperCase(); let expectedMode = ModeName[testObj.endMode].toUpperCase(); assert.equal(actualMode, expectedMode, "Didn't enter correct mode."); } } export { TestObject, testIt }