From 636b72b9f55b1d80ff5d830f97267e12425d6abf Mon Sep 17 00:00:00 2001 From: Gokul K Date: Fri, 21 Jun 2024 11:37:39 +0530 Subject: [PATCH 1/3] fix: copy paste last value pasting a promise --- js/editor.js | 24 ++++++++++------ js/editor.test.js | 73 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/js/editor.js b/js/editor.js index c16ded5..3777181 100644 --- a/js/editor.js +++ b/js/editor.js @@ -505,13 +505,13 @@ function debounce(callback, wait) { }; } -function isNotEmptyResult(item) { +function isNumberResult(item) { return !_.isEmpty(item) && _.isNumber(item.result); } // find the last not empty value from evaluatedValues function findLastValue(values) { - let lastValue = values.findLast(isNotEmptyResult); + let lastValue = values.findLast(isNumberResult); return lastValue ? lastValue.result : null; } @@ -526,24 +526,32 @@ export async function copyLastValue(values) { } } -function onEditorKeydown(e) { +export async function copyPasteLastValue(values) { + let lastValue = await copyLastValue(values); + if (lastValue) { + insertNode(lastValue); + } +} + +async function onEditorKeydown(e) { let key = e.key; // Order of below conditions matter since there is subset condition if (key === "Enter" && e.shiftKey && (e.metaKey || e.ctrlKey)) { - let lastValue = copyLastValue(evaluatedValues); - if (lastValue) { - insertNode(lastValue); - } + // copy & paste last value + copyPasteLastValue(evaluatedValues); } else if (key === "Enter" && (e.metaKey || e.ctrlKey)) { + // copy last value copyLastValue(evaluatedValues); } else if (key === "/" && (e.metaKey || e.ctrlKey)) { + // open/close help toggleHelpOverlay(); } else if (key === "h" && (e.metaKey || e.ctrlKey)) { + // open/close history toggleHistory(); } } -function insertNode(...nodes) { +export function insertNode(...nodes) { for (let node of nodes) { document.execCommand("insertText", false, node); } diff --git a/js/editor.test.js b/js/editor.test.js index bafdc78..781800d 100644 --- a/js/editor.test.js +++ b/js/editor.test.js @@ -9,8 +9,10 @@ import { parse, init, getResultTokens, + insertNode, + copyPasteLastValue, } from "./editor"; -import { describe, it, expect, vi, test, beforeEach, afterEach } from "vitest"; +import { describe, expect, vi, test, beforeEach, afterEach } from "vitest"; import * as Sentry from "@sentry/browser"; import path from "path"; import fs from "fs"; @@ -200,21 +202,21 @@ global.editor = { global.historyData = []; describe("testing loadPlaceholderData", () => { - it("should set placeholder text when no history data is present and currency conversions are loaded", async () => { + test("should set placeholder text when no history data is present and currency conversions are loaded", async () => { editor.innerText = ""; await loadPlaceholderData(editor, historyData, true); expect(editor.innerText).toContain("10 usd to inr"); }); - it("should not set placeholder text when history data is present", async () => { + test("should not set placeholder text when history data is present", async () => { editor.innerText = ""; await loadPlaceholderData(editor, [{ mockHistoryData: 1 }], true); expect(editor.innerText).toBe(""); }); - it("should set basic placeholder text when no currency conversions are loaded", async () => { + test("should set basic placeholder text when no currency conversions are loaded", async () => { editor.innerText = ""; await loadPlaceholderData(editor, historyData, false); @@ -236,26 +238,61 @@ Object.assign(navigator, { }); describe("testing copyLastValue", () => { - it("should not attempt to copy when no numeric results are available", async () => { + test("should not attempt to copy when no numeric results are available", async () => { global.evaluatedValues = [{ result: "text" }, { result: "some text" }]; await copyLastValue(global.evaluatedValues); //arrange .not.toHaveBeenCalled tests first since all calls in the test file will be counted expect(navigator.clipboard.writeText).not.toHaveBeenCalled(); }); - it("should copy the last numeric result to the clipboard", async () => { + test("should copy the last numeric result to the clipboard", async () => { global.evaluatedValues = [{ result: "text" }, { result: 42 }]; await copyLastValue(global.evaluatedValues); expect(navigator.clipboard.writeText).toHaveBeenCalledWith(42); }); - it("should copy the recent non empty vaue if available", async () => { + test("should copy the recent non empty vaue if available", async () => { global.evaluatedValues = [{ result: 21 }, { result: "" }]; await copyLastValue(global.evaluatedValues); expect(navigator.clipboard.writeText).toHaveBeenCalled(21); }); }); +describe("testing copyPasteLastValue", () => { + Object.assign(document, { + execCommand: vi.fn(), + }); + + test("should not attempt to copy since no numeric results are available", async () => { + global.evaluatedValues = [{ result: "text" }, { result: "some text" }]; + await copyPasteLastValue(evaluatedValues); + //arrange .not.toHaveBeenCalled tests first since all calls in the test file will be counted + expect(document.execCommand).not.toHaveBeenCalled(); + }); + + test("should paste the last numeric results available", async () => { + global.evaluatedValues = [{ result: 2 }, { result: "some text" }]; + await copyPasteLastValue(evaluatedValues); + expect(document.execCommand).toHaveBeenCalledWith("insertText", false, 2); + }); +}); + +describe("Testing insertNode", () => { + Object.assign(document, { + execCommand: vi.fn(), + }); + test("should insert a new node with the given value into the editor", () => { + const value = "new value"; + insertNode(value); + + expect(document.execCommand).toHaveBeenCalledWith( + "insertText", + false, + "new value" + ); + }); +}); + describe("testing getTitle", () => { test("Return full string when length is less than or equal to 30", () => { const result = getTitle("This is a short string"); @@ -282,7 +319,7 @@ vi.mock("@sentry/browser", () => ({ })); describe("Testing initSentry", () => { - it("should initialize Sentry with the correct configuration", async () => { + test("should initialize Sentry with the correct configuration", async () => { await initSentry(); expect(Sentry.init).toHaveBeenCalledWith({ @@ -309,7 +346,7 @@ describe("testing parse", () => { global.output = document.getElementById("output"); }); - it("should update the output value to 4", async () => { + test("should update the output value to 4", async () => { editor.innerText = "2+2"; parse(editor.innerText, output); @@ -319,28 +356,28 @@ describe("testing parse", () => { }); describe("testing postProcess", () => { - it("should return outputs when inputs and outputs lengths are equal", () => { + test("should return outputs when inputs and outputs lengths are equal", () => { const inputs = ["2", "=", "3"]; const outputs = [2, "", 3]; const result = postProcess(inputs, outputs); expect(result).toEqual([2, 2, 3]); }); - it("should return outputs adding previous inputs when inputs and outputs lengths are equal", () => { + test("should return outputs adding previous inputs when inputs and outputs lengths are equal", () => { const inputs = ["2", "5", "total", "3"]; const outputs = [2, 5, "", 3]; const result = postProcess(inputs, outputs); expect(result).toEqual([2, 5, 7, 3]); }); - it("should handle different lengths of inputs and outputs", () => { + test("should handle different lengths of inputs and outputs", () => { const inputs = ["2", "sum", "3"]; const outputs = [2, 5]; const result = postProcess(inputs, outputs); expect(result).toEqual([2, 5]); }); - it("should handle empty inputs", () => { + test("should handle empty inputs", () => { const inputs = []; const outputs = [2, 5]; const result = postProcess(inputs, outputs); @@ -349,7 +386,7 @@ describe("testing postProcess", () => { }); describe("Testing getResultTokens", () => { - it("should return a result token for a valid expression", () => { + test("should return a result token for a valid expression", () => { const validExpression = "5 + 3"; const expectedResultToken = { type: "result", @@ -367,7 +404,7 @@ describe("Testing getResultTokens", () => { expect(resultTokens).toEqual([expectedResultToken]); }); - it("should return an empty array for an empty expression", () => { + test("should return an empty array for an empty expression", () => { const emptyExpression = ""; const resultTokens = getResultTokens([ @@ -381,7 +418,7 @@ describe("Testing getResultTokens", () => { expect(resultTokens[0].value).toEqual(""); }); - it("should return a null token for an invalid expression", () => { + test("should return a null token for an invalid expression", () => { const invalidExpression = "invalid"; const expectedNullToken = { type: "null", @@ -399,7 +436,7 @@ describe("Testing getResultTokens", () => { expect(resultTokens).toEqual([expectedNullToken]); }); - it("should return a null token for an expression with a null result", () => { + test("should return a null token for an expression with a null result", () => { const nullExpression = "5 + null"; const expectedNullToken = { type: "null", @@ -417,7 +454,7 @@ describe("Testing getResultTokens", () => { expect(resultTokens).toEqual([expectedNullToken]); }); - it("should return a null token for an expression with a NaN result", () => { + test("should return a null token for an expression with a NaN result", () => { const nanExpression = "5 + NaN"; const expectedNullToken = { type: "null", From 184cdc34f77ca8118bd76653c5a891f533c7b831 Mon Sep 17 00:00:00 2001 From: Gokul K Date: Fri, 21 Jun 2024 11:40:01 +0530 Subject: [PATCH 2/3] use test instead of it in all unit tests file --- js/help_page.test.js | 8 ++++---- js/utils/convert_x_to_multiply.test.js | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js/help_page.test.js b/js/help_page.test.js index 6be1679..8be5c3c 100644 --- a/js/help_page.test.js +++ b/js/help_page.test.js @@ -1,5 +1,5 @@ import { createHelpTables } from "./help_page"; -import { describe, it, expect } from "vitest"; +import { describe, test, expect } from "vitest"; import path from "path"; import fs from "fs"; @@ -10,21 +10,21 @@ describe("createHelpTables tests", () => { createHelpTables(); - it("should create shortcut tables contents", () => { + test("should create shortcut tables contents", () => { const shortcutTables = document.getElementById("shortcut-table-container"); expect(shortcutTables.querySelectorAll("td")[4].outerHTML).toEqual( "Open/Close help" ); }); - it("should create operator tables contents", () => { + test("should create operator tables contents", () => { const operatorTables = document.getElementById("operator-table-container"); expect(operatorTables.querySelectorAll("td")[2].outerHTML).toEqual( "2 + 3 = 5" ); }); - it("should create unit tables contents", () => { + test("should create unit tables contents", () => { const unitTables = document.getElementById("unit-table-container"); expect(unitTables.querySelectorAll("td")[5].outerHTML).toEqual( "m2, sqin, sqft, sqyd, sqmi, sqrd, sqch, sqmil, acre, hectare" diff --git a/js/utils/convert_x_to_multiply.test.js b/js/utils/convert_x_to_multiply.test.js index 5648df4..19aa66d 100644 --- a/js/utils/convert_x_to_multiply.test.js +++ b/js/utils/convert_x_to_multiply.test.js @@ -1,8 +1,8 @@ -import { describe, it, expect } from "vitest"; +import { describe, test, expect } from "vitest"; import { convertXToMultiplication } from "./convert_x_to_multiply"; describe("testing convertXToMultiplication", () => { - it("Convert all 'x' to multiplication operator", () => { + test("Convert all 'x' to multiplication operator", () => { const lines = [ "2x3", "2 x 3", @@ -25,7 +25,7 @@ describe("testing convertXToMultiplication", () => { ]); }); - it("Dont convert some 'x' to multiplication operator in expressions", () => { + test("Dont convert some 'x' to multiplication operator in expressions", () => { const lines = ["2xdata", "0x90 x 2", "0x90x 2", "x22e x2x4x1.7x0.41"]; const convertedLines = convertXToMultiplication(lines); From 464d3285d4c1f49a6ddf3d3a92933488023ffd31 Mon Sep 17 00:00:00 2001 From: Gokul K Date: Fri, 21 Jun 2024 12:32:49 +0530 Subject: [PATCH 3/3] round of copied values using keyboard shortcuts --- js/editor.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/editor.js b/js/editor.js index 3777181..3f3e5d8 100644 --- a/js/editor.js +++ b/js/editor.js @@ -517,8 +517,9 @@ function findLastValue(values) { export async function copyLastValue(values) { // copy the last result to clipboard - const lastValue = findLastValue(values); + let lastValue = findLastValue(values); if (_.isNumber(lastValue)) { + lastValue = parseFloat(lastValue.toFixed(5)); copyValueToClipboard(lastValue); return lastValue; } else {