Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reenable/refactor undo-redo test #589

Merged
merged 1 commit into from
Nov 17, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 96 additions & 82 deletions packages/codemirror-blocks/spec/undo-redo-test.ts
Original file line number Diff line number Diff line change
@@ -1,98 +1,112 @@
import wescheme from "../src/languages/wescheme";
import "codemirror/addon/search/searchcursor.js";

import {
mac,
cmd_ctrl,
teardown,
mouseDown,
keyDown,
insertText,
mountCMB,
} from "../src/toolkit/test-utils";
import { API } from "../src/CodeMirrorBlocks";
import { ASTNode } from "../src/ast";
import { fireEvent } from "@testing-library/react";

describe("when testing undo/redo,", () => {
let cmb!: API;

const currentFirstRoot = () => cmb.getAst().rootNodes[0];
const undo = (node?: ASTNode) => keyDown("Z", cmd_ctrl, node);
const redo = (node?: ASTNode) => {
if (mac) {
keyDown("Z", { metaKey: true, shiftKey: true }, node);
} else {
keyDown("Y", { ctrlKey: true }, node);
}
};

beforeEach(async () => {
cmb = mountCMB(wescheme).cmb;
});
let cmb: API;

afterEach(teardown);

// https://github.com/bootstrapworld/codemirror-blocks/issues/315
// TODO(pcardune) reenable
xit("make sure edits can be properly undone/redone from an active block", async () => {
cmb.setValue(`A\nB\n`);
cmb.clearHistory();
expect(cmb.historySize()).toEqual({ undo: 0, redo: 0 });
mouseDown(currentFirstRoot()); // focus on the 1st root
keyDown(" ", {}, currentFirstRoot());
keyDown("X", cmd_ctrl, currentFirstRoot()); // change (1): cut first root
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 0 });
cmb.setCursor({ line: 2, ch: 0 });
keyDown("Enter"); // change (2): insert empty line
expect(cmb.getValue()).toEqual("\nB\n\n");
expect(cmb.historySize()).toEqual({ undo: 2, redo: 0 });
insertText("C"); // change (3): insert C at the end
expect(cmb.getValue()).toEqual("\nB\n\nC");
expect(cmb.historySize()).toEqual({ undo: 3, redo: 0 });
undo(currentFirstRoot()); // undo (3), leaving \nB\n\n
expect(cmb.getValue()).toEqual("\nB\n\n");
expect(cmb.historySize()).toEqual({ undo: 2, redo: 1 });
undo(currentFirstRoot()); // undo (2), leaving \nB\n\n
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 2 });
undo(currentFirstRoot()); // undo (1), leaving A\nB\n
expect(cmb.getValue()).toEqual("A\nB\n");
expect(cmb.historySize()).toEqual({ undo: 0, redo: 3 });
redo(currentFirstRoot()); // redo (1), leaving \nB\n
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 2 });
redo(currentFirstRoot()); // redo (2), leaving \nB\n\n
expect(cmb.getValue()).toEqual("\nB\n\n");
expect(cmb.historySize()).toEqual({ undo: 2, redo: 1 });
redo(currentFirstRoot()); // redo (3), leaving \nB\n\nC
expect(cmb.getValue()).toEqual("\nB\n\nC");
expect(cmb.historySize()).toEqual({ undo: 3, redo: 0 });
});
const currentFirstRoot = () => cmb.getAst().rootNodes[0];
const undo = (node?: ASTNode) => keyDown("Z", cmd_ctrl, node);
const redo = (node?: ASTNode) => keyDown("Y", { ctrlKey: true }, node);

beforeEach(async () => {
cmb = mountCMB(wescheme).cmb;
});

afterEach(teardown);

it("make sure edits can be properly undone/redone from the top level", async () => {
// initialize the document
cmb.setValue(`A\nB\n`);
cmb.clearHistory();
expect(cmb.historySize()).toEqual({ undo: 0, redo: 0 });

// change (1): cut first root
mouseDown(currentFirstRoot()); // focus on the 1st root
keyDown(" ", {}, currentFirstRoot());
keyDown("X", cmd_ctrl, currentFirstRoot());
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 0 });

// initiate undo from the top-level
cmb.setCursor({ line: 1, ch: 0 });
undo();
expect(cmb.getValue()).toEqual("A\nB\n");
expect(cmb.historySize()).toEqual({ undo: 0, redo: 1 });

// initiate redo from the top-level
cmb.setCursor({ line: 1, ch: 0 });
redo();
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 0 });
// https://github.com/bootstrapworld/codemirror-blocks/issues/315
it("make sure edits can be properly undone/redone from an active block", () => {
// initialize state
cmb.setValue(`A\nB\n`);
cmb.clearHistory();
expect(cmb.historySize()).toEqual({ undo: 0, redo: 0 });

// change (1): cut first root
mouseDown(currentFirstRoot()); // focus on the 1st root
keyDown(" ", {}, currentFirstRoot());
keyDown("X", cmd_ctrl, currentFirstRoot());
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 0 });

// change (2): insert empty line
cmb.setCursor({ line: 2, ch: 0 });
keyDown("Enter");
expect(cmb.getValue()).toEqual("\nB\n\n");
expect(cmb.historySize()).toEqual({ undo: 2, redo: 0 });

// change (3): insert C at the end
fireEvent.keyPress(document.activeElement!, {
key: "C",
code: "KeyC",
charCode: 67,
});
keyDown("Enter");

expect(cmb.getValue()).toEqual("\nB\n\nC");
expect(cmb.historySize()).toEqual({ undo: 3, redo: 0 });

// undo (3), leaving \nB\n\n
undo(currentFirstRoot());
expect(cmb.getValue()).toEqual("\nB\n\n");
expect(cmb.historySize()).toEqual({ undo: 2, redo: 1 });

// undo (2), leaving \nB\n\n
undo(currentFirstRoot());
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 2 });

// undo (1), leaving A\nB\n
undo(currentFirstRoot());
expect(cmb.getValue()).toEqual("A\nB\n");
expect(cmb.historySize()).toEqual({ undo: 0, redo: 3 });

// redo (1), leaving \nB\n
redo(currentFirstRoot());
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 2 });

// redo (2), leaving \nB\n\n
redo(currentFirstRoot());
expect(cmb.getValue()).toEqual("\nB\n\n");
expect(cmb.historySize()).toEqual({ undo: 2, redo: 1 });

// redo (3), leaving \nB\n\nC
redo(currentFirstRoot());
expect(cmb.getValue()).toEqual("\nB\n\nC");
expect(cmb.historySize()).toEqual({ undo: 3, redo: 0 });
});

it("make sure edits can be properly undone/redone from the top level", () => {
// initialize the document
cmb.setValue(`A\nB\n`);
cmb.clearHistory();
expect(cmb.historySize()).toEqual({ undo: 0, redo: 0 });

// change (1): cut first root
mouseDown(currentFirstRoot()); // focus on the 1st root
keyDown(" ", {}, currentFirstRoot());
keyDown("X", cmd_ctrl, currentFirstRoot());
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 0 });

// initiate undo from the top-level
cmb.setCursor({ line: 1, ch: 0 });
undo();
expect(cmb.getValue()).toEqual("A\nB\n");
expect(cmb.historySize()).toEqual({ undo: 0, redo: 1 });

// initiate redo from the top-level
cmb.setCursor({ line: 1, ch: 0 });
redo();
expect(cmb.getValue()).toEqual("\nB\n");
expect(cmb.historySize()).toEqual({ undo: 1, redo: 0 });
});