Skip to content

Commit 442ddb4

Browse files
committed
yeet correcred
1 parent c9fa677 commit 442ddb4

8 files changed

Lines changed: 376 additions & 60 deletions

File tree

frontend/__tests__/test/events/stats.spec.ts

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import {
5555
getChars,
5656
getWpmHistory,
5757
forceReleaseAllKeys,
58+
getCorrectedWords,
5859
__testing as statsTesting,
5960
} from "../../../src/ts/test/events/stats";
6061
import type {
@@ -677,6 +678,284 @@ describe("stats.ts", () => {
677678
});
678679
});
679680

681+
describe("getCorrectedWords", () => {
682+
it("returns input as-is when no corrections made", () => {
683+
logTestEvent("timer", 1000, timer("start", 0));
684+
logTestEvent(
685+
"input",
686+
1100,
687+
input({ charIndex: 0, wordIndex: 0, data: "t" }),
688+
);
689+
logTestEvent(
690+
"input",
691+
1150,
692+
input({ charIndex: 1, wordIndex: 0, data: "e" }),
693+
);
694+
logTestEvent(
695+
"input",
696+
1200,
697+
input({ charIndex: 2, wordIndex: 0, data: "s" }),
698+
);
699+
logTestEvent(
700+
"input",
701+
1250,
702+
input({ charIndex: 3, wordIndex: 0, data: "t" }),
703+
);
704+
705+
expect(getCorrectedWords()).toEqual(["test"]);
706+
});
707+
708+
it("returns last deleted char per position (xact -> fact)", () => {
709+
logTestEvent("timer", 1000, timer("start", 0));
710+
// type "xact"
711+
logTestEvent(
712+
"input",
713+
1100,
714+
input({ charIndex: 0, wordIndex: 0, data: "x" }),
715+
);
716+
logTestEvent(
717+
"input",
718+
1150,
719+
input({ charIndex: 1, wordIndex: 0, data: "a" }),
720+
);
721+
logTestEvent(
722+
"input",
723+
1200,
724+
input({ charIndex: 2, wordIndex: 0, data: "c" }),
725+
);
726+
logTestEvent(
727+
"input",
728+
1250,
729+
input({ charIndex: 3, wordIndex: 0, data: "t" }),
730+
);
731+
// delete all
732+
logTestEvent("input", 1300, {
733+
charIndex: 3,
734+
wordIndex: 0,
735+
inputType: "deleteContentBackward",
736+
} as InputEventData);
737+
logTestEvent("input", 1350, {
738+
charIndex: 2,
739+
wordIndex: 0,
740+
inputType: "deleteContentBackward",
741+
} as InputEventData);
742+
logTestEvent("input", 1400, {
743+
charIndex: 1,
744+
wordIndex: 0,
745+
inputType: "deleteContentBackward",
746+
} as InputEventData);
747+
logTestEvent("input", 1450, {
748+
charIndex: 0,
749+
wordIndex: 0,
750+
inputType: "deleteContentBackward",
751+
} as InputEventData);
752+
// type "fact"
753+
logTestEvent(
754+
"input",
755+
1500,
756+
input({ charIndex: 0, wordIndex: 0, data: "f" }),
757+
);
758+
logTestEvent(
759+
"input",
760+
1550,
761+
input({ charIndex: 1, wordIndex: 0, data: "a" }),
762+
);
763+
logTestEvent(
764+
"input",
765+
1600,
766+
input({ charIndex: 2, wordIndex: 0, data: "c" }),
767+
);
768+
logTestEvent(
769+
"input",
770+
1650,
771+
input({ charIndex: 3, wordIndex: 0, data: "t" }),
772+
);
773+
774+
expect(getCorrectedWords()).toEqual(["xact"]);
775+
});
776+
777+
it("returns last deleted char per position across multiple corrections (xest -> west -> test)", () => {
778+
logTestEvent("timer", 1000, timer("start", 0));
779+
// type "xest"
780+
logTestEvent(
781+
"input",
782+
1100,
783+
input({ charIndex: 0, wordIndex: 0, data: "x" }),
784+
);
785+
logTestEvent(
786+
"input",
787+
1150,
788+
input({ charIndex: 1, wordIndex: 0, data: "e" }),
789+
);
790+
logTestEvent(
791+
"input",
792+
1200,
793+
input({ charIndex: 2, wordIndex: 0, data: "s" }),
794+
);
795+
logTestEvent(
796+
"input",
797+
1250,
798+
input({ charIndex: 3, wordIndex: 0, data: "t" }),
799+
);
800+
// delete all
801+
logTestEvent("input", 1300, {
802+
charIndex: 3,
803+
wordIndex: 0,
804+
inputType: "deleteWordBackward",
805+
} as InputEventData);
806+
// type "west"
807+
logTestEvent(
808+
"input",
809+
1400,
810+
input({ charIndex: 0, wordIndex: 0, data: "w" }),
811+
);
812+
logTestEvent(
813+
"input",
814+
1450,
815+
input({ charIndex: 1, wordIndex: 0, data: "e" }),
816+
);
817+
logTestEvent(
818+
"input",
819+
1500,
820+
input({ charIndex: 2, wordIndex: 0, data: "s" }),
821+
);
822+
logTestEvent(
823+
"input",
824+
1550,
825+
input({ charIndex: 3, wordIndex: 0, data: "t" }),
826+
);
827+
// delete all
828+
logTestEvent("input", 1600, {
829+
charIndex: 3,
830+
wordIndex: 0,
831+
inputType: "deleteWordBackward",
832+
} as InputEventData);
833+
// type "test"
834+
logTestEvent(
835+
"input",
836+
1700,
837+
input({ charIndex: 0, wordIndex: 0, data: "t" }),
838+
);
839+
logTestEvent(
840+
"input",
841+
1750,
842+
input({ charIndex: 1, wordIndex: 0, data: "e" }),
843+
);
844+
logTestEvent(
845+
"input",
846+
1800,
847+
input({ charIndex: 2, wordIndex: 0, data: "s" }),
848+
);
849+
logTestEvent(
850+
"input",
851+
1850,
852+
input({ charIndex: 3, wordIndex: 0, data: "t" }),
853+
);
854+
855+
expect(getCorrectedWords()).toEqual(["west"]);
856+
});
857+
858+
it("handles partial correction (tset -> delete last 2 -> st)", () => {
859+
logTestEvent("timer", 1000, timer("start", 0));
860+
// type "tset"
861+
logTestEvent(
862+
"input",
863+
1100,
864+
input({ charIndex: 0, wordIndex: 0, data: "t" }),
865+
);
866+
logTestEvent(
867+
"input",
868+
1150,
869+
input({ charIndex: 1, wordIndex: 0, data: "s" }),
870+
);
871+
logTestEvent(
872+
"input",
873+
1200,
874+
input({ charIndex: 2, wordIndex: 0, data: "e" }),
875+
);
876+
logTestEvent(
877+
"input",
878+
1250,
879+
input({ charIndex: 3, wordIndex: 0, data: "t" }),
880+
);
881+
// delete last 2
882+
logTestEvent("input", 1300, {
883+
charIndex: 3,
884+
wordIndex: 0,
885+
inputType: "deleteContentBackward",
886+
} as InputEventData);
887+
logTestEvent("input", 1350, {
888+
charIndex: 2,
889+
wordIndex: 0,
890+
inputType: "deleteContentBackward",
891+
} as InputEventData);
892+
// type "st"
893+
logTestEvent(
894+
"input",
895+
1400,
896+
input({ charIndex: 2, wordIndex: 0, data: "s" }),
897+
);
898+
logTestEvent(
899+
"input",
900+
1450,
901+
input({ charIndex: 3, wordIndex: 0, data: "t" }),
902+
);
903+
904+
// pos 0: "t" never deleted, pos 1: "s" never deleted, pos 2: "e" deleted, pos 3: "t" deleted
905+
expect(getCorrectedWords()).toEqual(["tset"]);
906+
});
907+
908+
it("handles multiple words", () => {
909+
logTestEvent("timer", 1000, timer("start", 0));
910+
// word 0: type "ab" correctly
911+
logTestEvent(
912+
"input",
913+
1100,
914+
input({ charIndex: 0, wordIndex: 0, data: "a" }),
915+
);
916+
logTestEvent(
917+
"input",
918+
1150,
919+
input({ charIndex: 1, wordIndex: 0, data: "b" }),
920+
);
921+
// word 1: type "xy", delete both, type "zw"
922+
logTestEvent(
923+
"input",
924+
1200,
925+
input({ charIndex: 0, wordIndex: 1, data: "x" }),
926+
);
927+
logTestEvent(
928+
"input",
929+
1250,
930+
input({ charIndex: 1, wordIndex: 1, data: "y" }),
931+
);
932+
logTestEvent("input", 1300, {
933+
charIndex: 1,
934+
wordIndex: 1,
935+
inputType: "deleteContentBackward",
936+
} as InputEventData);
937+
logTestEvent("input", 1350, {
938+
charIndex: 1,
939+
wordIndex: 1,
940+
inputType: "deleteContentBackward",
941+
} as InputEventData);
942+
logTestEvent(
943+
"input",
944+
1400,
945+
input({ charIndex: 0, wordIndex: 1, data: "z" }),
946+
);
947+
logTestEvent(
948+
"input",
949+
1450,
950+
input({ charIndex: 1, wordIndex: 1, data: "w" }),
951+
);
952+
953+
const result = getCorrectedWords();
954+
expect(result[0]).toEqual("ab");
955+
expect(result[1]).toEqual("xy");
956+
});
957+
});
958+
680959
describe("forceReleaseAllKeys", () => {
681960
it("creates synthetic keyup events for pressed keys", () => {
682961
logTestEvent("timer", 1000, timer("start", 0));

frontend/src/ts/input/handlers/insert-text.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,6 @@ export async function onInsertText(options: OnInsertTextParams): Promise<void> {
167167
if (Config.keymapMode === "react") {
168168
flash(data, correct);
169169
}
170-
if (!shouldGoToNextWord) {
171-
TestInput.corrected.update(data, correct);
172-
}
173170

174171
// handing cases where last char needs to be removed
175172
// this is here and not in beforeInsertText because we want to penalize for incorrect spaces

frontend/src/ts/input/helpers/word-navigation.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ export async function goToNextWord({
6666
Funbox.toggleScript(TestWords.words.getText(TestState.activeWordIndex + 1));
6767

6868
TestInput.input.pushHistory();
69-
TestInput.corrected.pushHistory();
7069

7170
const lastWord = TestState.activeWordIndex >= TestWords.words.length - 1;
7271
if (lastWord) {
@@ -110,7 +109,6 @@ export function goToPreviousWord(
110109

111110
const word = TestInput.input.popHistory();
112111
TestState.decreaseActiveWordIndex();
113-
TestInput.corrected.popHistory();
114112

115113
Funbox.toggleScript(TestWords.words.getText(TestState.activeWordIndex));
116114

frontend/src/ts/test/events/stats.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,46 @@ export function getMissedWords(): Record<string, number> {
776776
return missedWords;
777777
}
778778

779+
export function getCorrectedWords(): string[] {
780+
const ev = getInputEventsPerWord();
781+
const correctedWords: string[] = [];
782+
783+
for (const [, events] of ev.entries()) {
784+
const correctedChars: string[] = [];
785+
const currentChars: string[] = [];
786+
let cursorPos = 0;
787+
788+
for (const event of events) {
789+
if (
790+
event.data.inputType === "insertText" ||
791+
event.data.inputType === "insertCompositionText"
792+
) {
793+
if (event.data.inputStopped || event.data.data === " ") continue;
794+
currentChars[cursorPos] = event.data.data;
795+
cursorPos++;
796+
} else if (event.data.inputType === "deleteContentBackward") {
797+
if (cursorPos > 0) {
798+
cursorPos--;
799+
correctedChars[cursorPos] = currentChars[cursorPos] ?? "";
800+
}
801+
} else if (event.data.inputType === "deleteWordBackward") {
802+
while (cursorPos > 0) {
803+
cursorPos--;
804+
correctedChars[cursorPos] = currentChars[cursorPos] ?? "";
805+
}
806+
}
807+
}
808+
809+
const result: string[] = [];
810+
for (let i = 0; i < currentChars.length; i++) {
811+
result.push(correctedChars[i] ?? currentChars[i] ?? "");
812+
}
813+
correctedWords.push(result.join(""));
814+
}
815+
816+
return correctedWords;
817+
}
818+
779819
export const __testing = {
780820
getTimerBoundaries,
781821
};

0 commit comments

Comments
 (0)