Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Unit test typescriptification - editor utils (#8226)
Browse files Browse the repository at this point in the history
* editor/mock ts

Signed-off-by: Kerry Archibald <[email protected]>

* test/editor/serialize-test.js -> test/editor/serialize-test.ts

Signed-off-by: Kerry Archibald <[email protected]>

* fix ts in serialize-test

Signed-off-by: Kerry Archibald <[email protected]>

* test/editor/range-test.js -> test/editor/range-test.ts

Signed-off-by: Kerry Archibald <[email protected]>

* test/editor/position-test.js -> test/editor/position-test.ts

Signed-off-by: Kerry Archibald <[email protected]>

* fix position-test

Signed-off-by: Kerry Archibald <[email protected]>

* test/editor/operations-test.js -> test/editor/operations-test.ts

Signed-off-by: Kerry Archibald <[email protected]>

* test/editor/model-test.js -> test/editor/model-test.ts

Signed-off-by: Kerry Archibald <[email protected]>

* fix ts in model-test

Signed-off-by: Kerry Archibald <[email protected]>

* test/editor/history-test.js -> test/editor/history-test.ts

Signed-off-by: Kerry Archibald <[email protected]>

* fix ts in history-test

Signed-off-by: Kerry Archibald <[email protected]>

* test/editor/diff-test.js -> test/editor/diff-test.ts

Signed-off-by: Kerry Archibald <[email protected]>

* test/editor/deserialize-test.js -> test/editor/deserialize-test.ts

Signed-off-by: Kerry Archibald <[email protected]>

* ts in deserialize-test

Signed-off-by: Kerry Archibald <[email protected]>

* test/editor/caret-test.js -> test/editor/caret-test.ts

Signed-off-by: Kerry Archibald <[email protected]>

* ts caret-test

Signed-off-by: Kerry Archibald <[email protected]>
  • Loading branch information
Kerry authored Apr 6, 2022
1 parent efb44e1 commit b9da225
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 90 deletions.
28 changes: 14 additions & 14 deletions test/editor/caret-test.js → test/editor/caret-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('editor/caret: DOM position for caret', function() {
const pc = createPartCreator();
const model = new EditorModel([
pc.plain("hello"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 0, offset: 5 });
expect(lineIndex).toBe(0);
Expand All @@ -35,7 +35,7 @@ describe('editor/caret: DOM position for caret', function() {
const pc = createPartCreator();
const model = new EditorModel([
pc.plain("hello"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 0, offset: 0 });
expect(lineIndex).toBe(0);
Expand All @@ -46,7 +46,7 @@ describe('editor/caret: DOM position for caret', function() {
const pc = createPartCreator();
const model = new EditorModel([
pc.plain("hello"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 0, offset: 2 });
expect(lineIndex).toBe(0);
Expand All @@ -61,7 +61,7 @@ describe('editor/caret: DOM position for caret', function() {
pc.plain("hello"),
pc.newline(),
pc.plain("world"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 2, offset: 5 });
expect(lineIndex).toBe(1);
Expand All @@ -74,7 +74,7 @@ describe('editor/caret: DOM position for caret', function() {
pc.plain("hello"),
pc.newline(),
pc.plain("world"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 2, offset: 0 });
expect(lineIndex).toBe(1);
Expand All @@ -88,7 +88,7 @@ describe('editor/caret: DOM position for caret', function() {
pc.newline(),
pc.newline(),
pc.plain("world"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 1, offset: 1 });
expect(lineIndex).toBe(1);
Expand All @@ -102,7 +102,7 @@ describe('editor/caret: DOM position for caret', function() {
pc.newline(),
pc.newline(),
pc.plain("world"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 3, offset: 0 });
expect(lineIndex).toBe(2);
Expand All @@ -117,7 +117,7 @@ describe('editor/caret: DOM position for caret', function() {
pc.plain("hello"),
pc.userPill("Alice", "@alice:hs.tld"),
pc.plain("!"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 1, offset: 0 });
expect(lineIndex).toBe(0);
Expand All @@ -130,7 +130,7 @@ describe('editor/caret: DOM position for caret', function() {
pc.plain("hello"),
pc.userPill("Alice", "@alice:hs.tld"),
pc.plain("!"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 1, offset: 2 });
expect(lineIndex).toBe(0);
Expand All @@ -141,7 +141,7 @@ describe('editor/caret: DOM position for caret', function() {
const pc = createPartCreator();
const model = new EditorModel([
pc.userPill("Alice", "@alice:hs.tld"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 0, offset: 0 });
expect(lineIndex).toBe(0);
Expand All @@ -153,7 +153,7 @@ describe('editor/caret: DOM position for caret', function() {
const pc = createPartCreator();
const model = new EditorModel([
pc.userPill("Alice", "@alice:hs.tld"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 0, offset: 1 });
expect(lineIndex).toBe(0);
Expand All @@ -166,7 +166,7 @@ describe('editor/caret: DOM position for caret', function() {
const model = new EditorModel([
pc.userPill("Alice", "@alice:hs.tld"),
pc.userPill("Bob", "@bob:hs.tld"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 0, offset: 1 });
expect(lineIndex).toBe(0);
Expand All @@ -179,7 +179,7 @@ describe('editor/caret: DOM position for caret', function() {
const model = new EditorModel([
pc.userPill("Alice", "@alice:hs.tld"),
pc.userPill("Bob", "@bob:hs.tld"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 1, offset: 0 });
expect(lineIndex).toBe(0);
Expand All @@ -192,7 +192,7 @@ describe('editor/caret: DOM position for caret', function() {
const model = new EditorModel([
pc.userPill("Alice", "@alice:hs.tld"),
pc.userPill("Bob", "@bob:hs.tld"),
]);
], pc);
const { offset, lineIndex, nodeIndex } =
getLineAndNodePosition(model, { index: 1, offset: 1 });
expect(lineIndex).toBe(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixEvent } from 'matrix-js-sdk/src/matrix';

import { parseEvent } from "../../src/editor/deserialize";
import { createPartCreator } from "./mock";
Expand All @@ -28,7 +29,7 @@ function htmlMessage(formattedBody, msgtype = "m.text") {
formatted_body: formattedBody,
};
},
};
} as unknown as MatrixEvent;
}

function textMessage(body, msgtype = "m.text") {
Expand All @@ -39,7 +40,7 @@ function textMessage(body, msgtype = "m.text") {
body,
};
},
};
} as unknown as MatrixEvent;
}

function mergeAdjacentParts(parts) {
Expand Down
File renamed without changes.
79 changes: 42 additions & 37 deletions test/editor/history-test.js → test/editor/history-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,88 +15,91 @@ limitations under the License.
*/

import HistoryManager, { MAX_STEP_LENGTH } from "../../src/editor/history";
import EditorModel from "../../src/editor/model";
import DocumentPosition from "../../src/editor/position";

describe('editor/history', function() {
it('push, then undo', function() {
const history = new HistoryManager();
const parts = ["hello"];
const model = { serializeParts: () => parts.slice() };
const caret1 = {};
const result1 = history.tryPush(model, caret1);
const model = { serializeParts: () => parts.slice() } as unknown as EditorModel;
const caret1 = new DocumentPosition(0, 0);
const result1 = history.tryPush(model, caret1, 'insertText', {});
expect(result1).toEqual(true);
parts[0] = "hello world";
history.tryPush(model, {});
history.tryPush(model, new DocumentPosition(0, 0), 'insertText', {});
expect(history.canUndo()).toEqual(true);
const undoState = history.undo(model);
expect(undoState.caret).toEqual(caret1);
expect(undoState.caret).toBe(caret1);
expect(undoState.parts).toEqual(["hello"]);
expect(history.canUndo()).toEqual(false);
});
it('push, undo, then redo', function() {
const history = new HistoryManager();
const parts = ["hello"];
const model = { serializeParts: () => parts.slice() };
history.tryPush(model, {});
const model = { serializeParts: () => parts.slice() } as unknown as EditorModel;
history.tryPush(model, new DocumentPosition(0, 0), 'insertText', {});
parts[0] = "hello world";
const caret2 = {};
history.tryPush(model, caret2);
const caret2 = new DocumentPosition(0, 0);
history.tryPush(model, caret2, 'insertText', {});
history.undo(model);
expect(history.canRedo()).toEqual(true);
const redoState = history.redo();
expect(redoState.caret).toEqual(caret2);
expect(redoState.caret).toBe(caret2);
expect(redoState.parts).toEqual(["hello world"]);
expect(history.canRedo()).toEqual(false);
expect(history.canUndo()).toEqual(true);
});
it('push, undo, push, ensure you can`t redo', function() {
const history = new HistoryManager();
const parts = ["hello"];
const model = { serializeParts: () => parts.slice() };
history.tryPush(model, {});
const model = { serializeParts: () => parts.slice() } as unknown as EditorModel;
history.tryPush(model, new DocumentPosition(0, 0), "insertText", {});
parts[0] = "hello world";
history.tryPush(model, {});
history.tryPush(model, new DocumentPosition(0, 0), "insertText", {});
history.undo(model);
parts[0] = "hello world!!";
history.tryPush(model, {});
history.tryPush(model, new DocumentPosition(0, 0), "insertText", {});
expect(history.canRedo()).toEqual(false);
});
it('not every keystroke stores a history step', function() {
const history = new HistoryManager();
const parts = ["hello"];
const model = { serializeParts: () => parts.slice() };
const firstCaret = {};
history.tryPush(model, firstCaret);
const model = { serializeParts: () => parts.slice() } as unknown as EditorModel;
const firstCaret = new DocumentPosition(0, 0);
history.tryPush(model, firstCaret, "insertText", {});
const diff = { added: "o" };
let keystrokeCount = 0;
do {
parts[0] = parts[0] + diff.added;
keystrokeCount += 1;
} while (!history.tryPush(model, {}, "insertText", diff));
} while (!history.tryPush(model, new DocumentPosition(0, 0), "insertText", diff));
const undoState = history.undo(model);
expect(undoState.caret).toEqual(firstCaret);
expect(undoState.caret).toBe(firstCaret);
expect(undoState.parts).toEqual(["hello"]);
expect(history.canUndo()).toEqual(false);
expect(keystrokeCount).toEqual(MAX_STEP_LENGTH + 1); // +1 before we type before checking
});
it('history step is added at word boundary', function() {
const history = new HistoryManager();
const model = { serializeParts: () => parts.slice() };
const model = { serializeParts: () => parts.slice() } as unknown as EditorModel;
const parts = ["h"];
let diff = { added: "h" };
expect(history.tryPush(model, {}, "insertText", diff)).toEqual(false);
const blankCaret = new DocumentPosition(0, 0);
expect(history.tryPush(model, blankCaret, "insertText", diff)).toEqual(false);
diff = { added: "i" };
parts[0] = "hi";
expect(history.tryPush(model, {}, "insertText", diff)).toEqual(false);
expect(history.tryPush(model, blankCaret, "insertText", diff)).toEqual(false);
diff = { added: " " };
parts[0] = "hi ";
const spaceCaret = {};
const spaceCaret = new DocumentPosition(1, 1);
expect(history.tryPush(model, spaceCaret, "insertText", diff)).toEqual(true);
diff = { added: "y" };
parts[0] = "hi y";
expect(history.tryPush(model, {}, "insertText", diff)).toEqual(false);
expect(history.tryPush(model, blankCaret, "insertText", diff)).toEqual(false);
diff = { added: "o" };
parts[0] = "hi yo";
expect(history.tryPush(model, {}, "insertText", diff)).toEqual(false);
expect(history.tryPush(model, blankCaret, "insertText", diff)).toEqual(false);
diff = { added: "u" };
parts[0] = "hi you";

Expand All @@ -108,11 +111,11 @@ describe('editor/history', function() {
it('keystroke that didn\'t add a step can undo', function() {
const history = new HistoryManager();
const parts = ["hello"];
const model = { serializeParts: () => parts.slice() };
const firstCaret = {};
history.tryPush(model, {});
const model = { serializeParts: () => parts.slice() } as unknown as EditorModel;
const firstCaret = new DocumentPosition(0, 0);
history.tryPush(model, firstCaret, "insertText", {});
parts[0] = "helloo";
const result = history.tryPush(model, {}, "insertText", { added: "o" });
const result = history.tryPush(model, new DocumentPosition(0, 0), "insertText", { added: "o" });
expect(result).toEqual(false);
expect(history.canUndo()).toEqual(true);
const undoState = history.undo(model);
Expand All @@ -122,25 +125,27 @@ describe('editor/history', function() {
it('undo after keystroke that didn\'t add a step is able to redo', function() {
const history = new HistoryManager();
const parts = ["hello"];
const model = { serializeParts: () => parts.slice() };
history.tryPush(model, {});
const model = { serializeParts: () => parts.slice() } as unknown as EditorModel;
history.tryPush(model, new DocumentPosition(0, 0), "insertText", {});
parts[0] = "helloo";
const caret = { last: true };
const caret = new DocumentPosition(1, 1);
history.tryPush(model, caret, "insertText", { added: "o" });
history.undo(model);
expect(history.canRedo()).toEqual(true);
const redoState = history.redo();
expect(redoState.caret).toEqual(caret);
expect(redoState.caret).toBe(caret);
expect(redoState.parts).toEqual(["helloo"]);
});

it('overwriting text always stores a step', function() {
const history = new HistoryManager();
const parts = ["hello"];
const model = { serializeParts: () => parts.slice() };
const firstCaret = {};
history.tryPush(model, firstCaret);
const model = { serializeParts: () => parts.slice() } as unknown as EditorModel;
const firstCaret = new DocumentPosition(0, 0);
history.tryPush(model, firstCaret, 'insertText', {});
const diff = { at: 1, added: "a", removed: "e" };
const result = history.tryPush(model, {}, "insertText", diff);
const secondCaret = new DocumentPosition(1, 1);
const result = history.tryPush(model, secondCaret, "insertText", diff);
expect(result).toEqual(true);
});
});
25 changes: 17 additions & 8 deletions test/editor/mock.js → test/editor/mock.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Copyright 2019, 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -14,9 +14,17 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { Room, MatrixClient } from "matrix-js-sdk/src/matrix";

import AutocompleteWrapperModel from "../../src/editor/autocomplete";
import { PartCreator } from "../../src/editor/parts";

class MockAutoComplete {
public _updateCallback;
public _partCreator;
public _completions;
public _part;

constructor(updateCallback, partCreator, completions) {
this._updateCallback = updateCallback;
this._partCreator = partCreator;
Expand Down Expand Up @@ -52,20 +60,21 @@ class MockAutoComplete {

// MockClient & MockRoom are only used for avatars in room and user pills,
// which is not tested
class MockClient {
getRooms() { return []; }
getRoom() { return null; }
}

class MockRoom {
getMember() { return null; }
}

export function createPartCreator(completions = []) {
const autoCompleteCreator = (partCreator) => {
return (updateCallback) => new MockAutoComplete(updateCallback, partCreator, completions);
return (updateCallback) =>
new MockAutoComplete(updateCallback, partCreator, completions) as unknown as AutocompleteWrapperModel;
};
return new PartCreator(new MockRoom(), new MockClient(), autoCompleteCreator);
const room = new MockRoom() as unknown as Room;
const client = {
getRooms: jest.fn().mockReturnValue([]),
getRoom: jest.fn().mockReturnValue(null),
} as unknown as MatrixClient;
return new PartCreator(room, client, autoCompleteCreator);
}

export function createRenderer() {
Expand Down
Loading

0 comments on commit b9da225

Please sign in to comment.