Merge pull request #3247 from matrix-org/bwindels/editortests

Unit tests for new editor
This commit is contained in:
Bruno Windels
2019-07-30 14:46:33 +00:00
committed by GitHub
11 changed files with 1018 additions and 44 deletions

View File

@@ -26,7 +26,7 @@ import {htmlSerializeIfNeeded, textSerialize} from '../../../editor/serialize';
import {findEditableEvent} from '../../../utils/EventUtils';
import {parseEvent} from '../../../editor/deserialize';
import Autocomplete from '../rooms/Autocomplete';
import {PartCreator} from '../../../editor/parts';
import {PartCreator, autoCompleteCreator} from '../../../editor/parts';
import {renderModel} from '../../../editor/render';
import EditorStateTransfer from '../../../utils/EditorStateTransfer';
import {MatrixClient} from 'matrix-js-sdk';
@@ -303,8 +303,7 @@ export default class MessageEditor extends React.Component {
const {editState} = this.props;
const room = this._getRoom();
const partCreator = new PartCreator(
() => this._autocompleteRef,
query => this.setState({query}),
autoCompleteCreator(() => this._autocompleteRef, query => this.setState({query})),
room,
this.context.matrixClient,
);

View File

@@ -40,7 +40,7 @@ export function setCaretPosition(editor, model, caretPosition) {
sel.addRange(range);
}
function getLineAndNodePosition(model, caretPosition) {
export function getLineAndNodePosition(model, caretPosition) {
const {parts} = model;
const partIndex = caretPosition.index;
const lineResult = findNodeInLineForPart(parts, partIndex);

View File

@@ -25,16 +25,6 @@ function firstDiff(a, b) {
return compareLen;
}
function lastDiff(a, b) {
const compareLen = Math.min(a.length, b.length);
for (let i = 0; i < compareLen; ++i) {
if (a[a.length - i] !== b[b.length - i]) {
return i;
}
}
return compareLen;
}
function diffStringsAtEnd(oldStr, newStr) {
const len = Math.min(oldStr.length, newStr.length);
const startInCommon = oldStr.substr(0, len) === newStr.substr(0, len);
@@ -52,24 +42,25 @@ function diffStringsAtEnd(oldStr, newStr) {
}
}
// assumes only characters have been deleted at one location in the string, and none added
export function diffDeletion(oldStr, newStr) {
if (oldStr === newStr) {
return {};
}
const firstDiffIdx = firstDiff(oldStr, newStr);
const lastDiffIdx = oldStr.length - lastDiff(oldStr, newStr) + 1;
return {at: firstDiffIdx, removed: oldStr.substring(firstDiffIdx, lastDiffIdx)};
}
export function diffInsertion(oldStr, newStr) {
const diff = diffDeletion(newStr, oldStr);
if (diff.removed) {
return {at: diff.at, added: diff.removed};
} else {
return diff;
}
const amount = oldStr.length - newStr.length;
return {at: firstDiffIdx, removed: oldStr.substr(firstDiffIdx, amount)};
}
/**
* Calculates which string was added and removed around the caret position
* @param {String} oldValue the previous value
* @param {String} newValue the new value
* @param {Number} caretPosition the position of the caret after `newValue` was applied.
* @return {object} an object with `at` as the offset where characters were removed and/or added,
* `added` with the added string (if any), and
* `removed` with the removed string (if any)
*/
export function diffAtCaret(oldValue, newValue, caretPosition) {
const diffLen = newValue.length - oldValue.length;
const caretPositionBeforeInput = caretPosition - diffLen;

View File

@@ -117,7 +117,8 @@ class BasePart {
}
}
class PlainPart extends BasePart {
// exported for unit tests, should otherwise only be used through PartCreator
export class PlainPart extends BasePart {
acceptsInsertion(chr) {
return chr !== "@" && chr !== "#" && chr !== ":" && chr !== "\n";
}
@@ -348,18 +349,24 @@ class PillCandidatePart extends PlainPart {
}
}
export class PartCreator {
constructor(getAutocompleterComponent, updateQuery, room, client) {
this._room = room;
this._client = client;
this._autoCompleteCreator = (updateCallback) => {
export function autoCompleteCreator(updateQuery, getAutocompleterComponent) {
return (partCreator) => {
return (updateCallback) => {
return new AutocompleteWrapperModel(
updateCallback,
getAutocompleterComponent,
updateQuery,
this,
partCreator,
);
};
};
}
export class PartCreator {
constructor(autoCompleteCreator, room, client) {
this._room = room;
this._client = client;
this._autoCompleteCreator = autoCompleteCreator(this);
}
createPartForInput(input) {

View File

@@ -56,15 +56,3 @@ export function textSerialize(model) {
}
}, "");
}
export function requiresHtml(model) {
return model.parts.some(part => {
switch (part.type) {
case "room-pill":
case "user-pill":
return true;
default:
return false;
}
});
}