From 135683795bcf10b5f88af4335e48b66551d7c8a7 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Sat, 25 Jun 2022 21:33:26 +0430 Subject: [PATCH] Spreadsheet: Throw if lookup value doesn't exist and no default is given And explicitly state which value wasn't found and where in the error. --- Base/res/js/Spreadsheet/runtime.js | 25 +++++++++---------- .../Spreadsheet/Tests/free-functions.js | 4 +-- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Base/res/js/Spreadsheet/runtime.js b/Base/res/js/Spreadsheet/runtime.js index 68053d6306..c1040d4bd1 100644 --- a/Base/res/js/Spreadsheet/runtime.js +++ b/Base/res/js/Spreadsheet/runtime.js @@ -635,6 +635,12 @@ function internal_lookup( reference ) { if_missing = if_missing ?? undefined; + const missing = () => { + if (if_missing !== undefined) return if_missing; + + throw new Error(`Failed to find ${req_lookup_value} in ${lookup_inputs}`); + }; + mode = mode ?? "exact"; const lookup_value = req_lookup_value; let matches = null; @@ -661,7 +667,7 @@ function internal_lookup( ++i; }); - if (found_input == null) return if_missing; + if (found_input == null) return missing(); if (lookup_outputs === undefined) { if (reference) return found_input; @@ -691,14 +697,7 @@ function lookup(req_lookup_value, lookup_inputs, lookup_outputs, if_missing, mod } function reflookup(req_lookup_value, lookup_inputs, lookup_outputs, if_missing, mode) { - return internal_lookup( - req_lookup_value, - lookup_inputs, - lookup_outputs, - if_missing ?? here(), - mode, - true - ); + return internal_lookup(req_lookup_value, lookup_inputs, lookup_outputs, if_missing, mode, true); } // Cheat the system and add documentation @@ -1223,8 +1222,8 @@ lookup.__documentation = JSON.stringify({ "Allows for finding things in a table or tabular data, by looking for matches in one range, and " + "grabbing the corresponding output value from another range.\n" + "if `lookup target` is not specified or is nullish, it is assumed to be the same as the `lookup source`\n." + - "if nothing matches, the value `value if no match`" + - " is returned, which is `undefined` by default.\nBy setting the `match method`, the function can be altered to return " + + "if nothing matches, either the value `value if no match` (if not `undefined`) is returned, or " + + "an error is thrown.\nBy setting the `match method`, the function can be altered to return " + "the closest ordered value (above or below) instead of an exact match. The valid choices for `match method` are:\n" + "- `'exact'`: The default method. Uses strict equality to match values.\n" + "- `'nextlargest'`: Uses the greater-or-equal operator to match values.\n" + @@ -1251,8 +1250,8 @@ reflookup.__documentation = JSON.stringify({ "Allows for finding references to things in a table or tabular data, by looking for matches in one range, and " + "grabbing the corresponding output value from another range.\n" + "if `lookup target` is not specified or is nullish, it is assumed to be the same as the `lookup source`\n." + - "if nothing matches, the value `value if no match`" + - " is returned, which is `undefined` by default.\nBy setting the `match method`, the function can be altered to return " + + "if nothing matches, either the value `value if no match` (if not `undefined`) is returned, or " + + "an error is thrown.\nBy setting the `match method`, the function can be altered to return " + "the closest ordered value (above or below) instead of an exact match. The valid choices for `match method` are:\n" + "- `'exact'`: The default method. Uses strict equality to match values.\n" + "- `'nextlargest'`: Uses the greater-or-equal operator to match values.\n" + diff --git a/Userland/Applications/Spreadsheet/Tests/free-functions.js b/Userland/Applications/Spreadsheet/Tests/free-functions.js index 9a55046075..fb416a68fd 100644 --- a/Userland/Applications/Spreadsheet/Tests/free-functions.js +++ b/Userland/Applications/Spreadsheet/Tests/free-functions.js @@ -191,7 +191,7 @@ describe("Lookup", () => { expect(lookup).toBeDefined(); // Note: String ordering. expect(lookup("2", R`A0:A9`, R`B0:B9`)).toEqual("B2"); - expect(lookup("20", R`A0:A9`, R`B0:B9`)).toBeUndefined(); + expect(() => lookup("20", R`A0:A9`, R`B0:B9`)).toThrow(); expect(lookup("80", R`A0:A9`, R`B0:B9`, undefined, "nextlargest")).toEqual("B9"); }); @@ -199,7 +199,7 @@ describe("Lookup", () => { expect(reflookup).toBeDefined(); // Note: String ordering. expect(reflookup("2", R`A0:A9`, R`B0:B9`).name).toEqual("B2"); - expect(reflookup("20", R`A0:A9`, R`B0:B9`)).toEqual(here()); + expect(() => reflookup("20", R`A0:A9`, R`B0:B9`)).toThrow(); expect(reflookup("80", R`A0:A9`, R`B0:B9`, undefined, "nextlargest").name).toEqual("B9"); }); });