From 6d4a6d3c38f8cc213cf41baf8cf12ea0eebbc143 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 7 Jun 2024 12:58:34 -0300 Subject: language: formatString: report valueless (null/undefined) options --- src/data/things/language.js | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/data/things/language.js b/src/data/things/language.js index 0725ff10..3cc2cce3 100644 --- a/src/data/things/language.js +++ b/src/data/things/language.js @@ -222,6 +222,10 @@ export class Language extends Thing { // each option (if it's present). const missingOptionNames = new Set(); + // These will also be filled. It's a bit different of an error, indicating + // a provided option was *expected,* but its value was null or undefined. + const valuelessOptionNames = new Set(); + // And this will have entries deleted as they're encountered in the // template. Leftover entries are misplaced. const optionsMap = @@ -250,21 +254,24 @@ export class Language extends Thing { return undefined; } - let optionValue; - - // We'll only need the option's value if we're going to use it as - // part of the formed output (see below). But, we have to do this get - // call now, since we'll be deleting it from optionsMap next! - if (!canceledForming) { - optionValue = optionsMap.get(optionName); - } + // Even if we're not actually forming the output anymore, we'll still + // have to access this option's value to check if it is invalid. + const optionValue = optionsMap.get(optionName); // We always have to delete expected options off the provided option // map, since the leftovers are what will be used to tell which are - // misplaced - information you want even (or doubly so) if the string - // is already invalid thanks to missing options. + // misplaced - information you want even (or doubly so) if we've + // already stopped forming the output thanks to missing options. optionsMap.delete(optionName); + // Null and undefined aren't valid option values! These are considered + // valueless. Just like if an option is missing, this cancels forming + // the rest of the output. + if (optionValue === null || optionValue === undefined) { + valuelessOptionNames.add(optionName); + return undefined; + } + if (canceledForming) { return undefined; } @@ -277,14 +284,21 @@ export class Language extends Thing { Array.from(optionsMap.keys()); withAggregate({message: `Errors in options for string "${key}"`}, ({push}) => { + const names = set => Array.from(set).join(', '); + if (!empty(missingOptionNames)) { - const names = Array.from(missingOptionNames).join(`, `); - push(new Error(`Missing options: ${names}`)); + push(new Error( + `Missing options: ${names(missingOptionNames)}`)); + } + + if (!empty(valuelessOptionNames)) { + push(new Error( + `Valueless options: ${names(valuelessOptionNames)}`)); } if (!empty(misplacedOptionNames)) { - const names = Array.from(misplacedOptionNames).join(`, `); - push(new Error(`Unexpected options: ${names}`)); + push(new Error( + `Unexpected options: ${names(misplacedOptionNames)}`)); } }); -- cgit 1.3.0-6-gf8a5