Skip to content

Commit

Permalink
Add editor tests for value selection, and fix tests with reliable pos…
Browse files Browse the repository at this point in the history
…itions for value nodes when determining the selection position after applying a suggestion
  • Loading branch information
jonathonherbert committed Sep 25, 2024
1 parent 528fbc6 commit ca6f847
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 35 deletions.
110 changes: 81 additions & 29 deletions prosemirror-client/src/cqlInput/CqlInput.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ import { createCqlPlugin } from "./plugin";
import { redo, undo } from "prosemirror-history";
import { bottomOfLine, topOfLine } from "./commands";
import { keymap } from "prosemirror-keymap";
import { logNode, mapResult, tokensToDoc } from "./utils";
import {
createProseMirrorTokenToDocumentMap,
docToQueryStr,
mapResult,
tokensToDoc,
toProseMirrorTokens,
} from "./utils";
import { TextSelection } from "prosemirror-state";

const typeheadHelpers = new TestTypeaheadHelpers();
const testCqlService = new CqlClientService(typeheadHelpers.fieldResolvers);
Expand Down Expand Up @@ -41,7 +48,23 @@ const createCqlEditor = async (initialQuery: string = "") => {
return tokensToDoc(tokens);
};

const doc = await queryToProseMirrorTokens(initialQuery)
const moveCaretToQueryPos = async (pos: number) => {
const query = docToQueryStr(editor.view.state.doc);
const result = await testCqlService.fetchResult(query);
const tokens = toProseMirrorTokens(result.tokens);
const mapping = createProseMirrorTokenToDocumentMap(tokens);
return editor.command((state, dispatch) => {
dispatch?.(
state.tr.setSelection(
TextSelection.near(state.doc.resolve(mapping.map(pos)))
)
);

return true;
});
};

const doc = await queryToProseMirrorTokens(initialQuery);

const editor = createEditor(doc, {
plugins: [
Expand Down Expand Up @@ -93,7 +116,7 @@ const createCqlEditor = async (initialQuery: string = "") => {
}, timeoutMs);
});

return { editor, waitFor, container };
return { editor, waitFor, container, moveCaretToQueryPos };
};

const selectPopoverOption = async (
Expand Down Expand Up @@ -130,48 +153,77 @@ describe("CqlInput", () => {
});

describe("typeahead", () => {
it("displays a popover for chip keys at the start of a query", async () => {
const { editor, container } = await createCqlEditor();
describe("chip keys", () => {
it("displays a popover at the start of a query", async () => {
const { editor, container } = await createCqlEditor();

await editor.insertText("example +");
await editor.insertText("example +");

const popoverContainer = await findByTestId(container, typeaheadTestId);
const popoverContainer = await findByTestId(container, typeaheadTestId);

await findByText(popoverContainer, "Tag");
await findByText(popoverContainer, "Section");
});
await findByText(popoverContainer, "Tag");
await findByText(popoverContainer, "Section");
});

it("displays a popover for chip keys after search text", async () => {
const { editor, container } = await createCqlEditor();
it("displays a popover after search text", async () => {
const { editor, container } = await createCqlEditor();

await editor.insertText("+");
await editor.insertText("+");

const popoverContainer = await findByTestId(container, typeaheadTestId);
const popoverContainer = await findByTestId(container, typeaheadTestId);

await findByText(popoverContainer, "Tag");
await findByText(popoverContainer, "Section");
});
await findByText(popoverContainer, "Tag");
await findByText(popoverContainer, "Section");
});

it("displays a popover after another chip", async () => {
const { editor, container } = await createCqlEditor("+tag:a");

it("displays a popover for chip keys after another chip", async () => {
const { editor, container } = await createCqlEditor("+tag:a");
editor.insertText(" +");

editor.insertText(" +");
const popoverContainer = await findByTestId(container, typeaheadTestId);

const popoverContainer = await findByTestId(container, typeaheadTestId);
await findByText(popoverContainer, "Tag");
await findByText(popoverContainer, "Section");
});

await findByText(popoverContainer, "Tag");
await findByText(popoverContainer, "Section");
it("applies the given key when a popover option is selected", async () => {
const { editor, container, waitFor } = await createCqlEditor();
await editor.insertText("example +");

await waitFor("example +");

await selectPopoverOption(editor, container, "Tag");

await waitFor("example +tag");
});
});

it("accepts the given value when a popover appears", async () => {
const { editor, container, waitFor } = await createCqlEditor();
await editor.insertText("example +");
describe("chip values", () => {
it("displays a popover at the start of a query", async () => {
const queryStr = "example +tag";
const { editor, container, moveCaretToQueryPos } =
await createCqlEditor("example +tag");

await moveCaretToQueryPos(queryStr.length);
await editor.insertText("t");

const popoverContainer = await findByTestId(container, typeaheadTestId);

await findByText(popoverContainer, "Tags are magic");
});

await waitFor("example +");
it("applies the given key when a popover option is selected", async () => {
const queryStr = "example +tag";
const { editor, container, waitFor, moveCaretToQueryPos } =
await createCqlEditor("example +tag");

await selectPopoverOption(editor, container, "Tag");
await moveCaretToQueryPos(queryStr.length);
await editor.insertText("t");
await selectPopoverOption(editor, container, "Tags are magic");

await waitFor("example +tag");
await waitFor("example +tag:tags-are-magic ");
});
});
});

Expand Down
9 changes: 3 additions & 6 deletions prosemirror-client/src/cqlInput/TypeaheadPopover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,13 @@ export class TypeaheadPopover extends Popover {

tr.replaceRangeWith(from, to, schema.text(value));

let insertPos = getNextPositionAfterTypeaheadSelection(
tr.doc,
tr.selection.to
);
let insertPos = getNextPositionAfterTypeaheadSelection(tr.doc, from);

if (insertPos) {
tr.setSelection(TextSelection.create(tr.doc, insertPos));

this.view.dispatch(tr);
}

this.view.dispatch(tr);
};

private moveSelection = (by: number) => {
Expand Down

0 comments on commit ca6f847

Please sign in to comment.