Skip to content

fix(#1632): narrow empty arg defaultValue to ADDRESS only#1631

Open
marcin-kordas-hoc wants to merge 2 commits intodevelopfrom
fix/empty-default-value
Open

fix(#1632): narrow empty arg defaultValue to ADDRESS only#1631
marcin-kordas-hoc wants to merge 2 commits intodevelopfrom
fix/empty-default-value

Conversation

@marcin-kordas-hoc
Copy link
Collaborator

@marcin-kordas-hoc marcin-kordas-hoc commented Mar 5, 2026

Problem

When a user writes =ADDRESS(1,1,) or =ADDRESS(1,1,1,), the empty argument
is coerced to 0/false instead of using the parameter's declared defaultValue.

Excel 2021 and Google Sheets treat empty args as the zero-value for the type
(0/FALSE) for all functions except ADDRESS, where empty absNum and
a1Style use their declared defaults (1 and true).

Fixes #1632

Fix

  • Add emptyAsDefault opt-in flag to FunctionArgument interface
  • In coerceArgumentsToRequiredTypes: when rawArg === EmptyValue AND
    emptyAsDefault is set AND defaultValue is declared → substitute defaultValue
  • Apply emptyAsDefault: true only to ADDRESS absNum and a1Style parameters

Tests

Regression tests in handsontable/hyperformula-tests (branch fix/empty-default-value):

  • ADDRESS: isolated tests for empty absNum, empty a1Style, both empty
  • LOG, MATCH, VLOOKUP, HLOOKUP: confirm empty → zero-value (not defaultValue)
  • optional-parameters.spec.ts: confirms empty args use zero-value coercion (not defaultValue) when emptyAsDefault is not set

Note

Medium Risk
Touches the core argument-coercion path in FunctionPlugin, so any function that opts into emptyAsDefault could change behavior; impact is otherwise scoped to parameters explicitly marked with the new flag.

Overview
Updates function-argument coercion to optionally treat an explicitly empty argument (EmptyValue, e.g. trailing comma) as missing and substitute the parameter’s defaultValue instead of coercing the empty value to 0/false.

Adds a new FunctionArgument.emptyAsDefault metadata flag to opt into this behavior, and enables it for ADDRESS’s abs and useA1Style optional parameters so ADDRESS(…, , ) uses the declared defaults.

Written by Cursor Bugbot for commit f09a219. This will update automatically on new commits. Configure here.

When a user writes an empty argument (e.g. =FUNC(a,,c)), the parser produces
AstNodeType.EMPTY which evaluates to EmptyValue (a Symbol sentinel, not undefined).
The previous guard  passed EmptyValue through,
bypassing the declared defaultValue and coercing it to 0 or false instead.

Fix: treat EmptyValue as absent only when the parameter declares an explicit
defaultValue, so functions like LOG, VLOOKUP, MATCH etc. get their correct defaults.
@marcin-kordas-hoc marcin-kordas-hoc requested a review from sequba March 5, 2026 12:56
@marcin-kordas-hoc marcin-kordas-hoc self-assigned this Mar 5, 2026
@github-actions
Copy link

github-actions bot commented Mar 5, 2026

Performance comparison of head (f09a219) vs base (4042b04)

                                     testName |   base |   head | change
------------------------------------------------------------------------
                                      Sheet A | 481.28 | 481.17 | -0.02%
                                      Sheet B | 152.97 | 153.66 | +0.45%
                                      Sheet T |  134.7 | 134.23 | -0.35%
                                Column ranges | 464.85 | 460.71 | -0.89%
Sheet A:  change value, add/remove row/column |  14.76 |  14.58 | -1.22%
 Sheet B: change value, add/remove row/column | 129.89 | 123.98 | -4.55%
                   Column ranges - add column | 142.77 | 143.21 | +0.31%
                Column ranges - without batch | 433.31 | 442.26 | +2.07%
                        Column ranges - batch | 109.17 | 109.66 | +0.45%

…ault)

Excel treats empty args as zero-value for the type (0/FALSE/"") for all
functions. ADDRESS is the only confirmed exception where empty args use
the declared defaultValue. Add opt-in emptyAsDefault flag to FunctionArgument
and apply it only to ADDRESS absNum and a1Style parameters.

Verified against Excel 2021 and Google Sheets for LOG, VLOOKUP, MATCH,
HLOOKUP, FIND, SUBSTITUTE, and ADDRESS.
@marcin-kordas-hoc marcin-kordas-hoc changed the title fix: respect defaultValue when arg is AstNodeType.EMPTY fix(#1632): narrow empty arg defaultValue to ADDRESS only Mar 10, 2026
@codecov
Copy link

codecov bot commented Mar 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.18%. Comparing base (4042b04) to head (f09a219).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #1631   +/-   ##
========================================
  Coverage    97.18%   97.18%           
========================================
  Files          172      172           
  Lines        14836    14841    +5     
  Branches      3258     3262    +4     
========================================
+ Hits         14418    14423    +5     
  Misses         418      418           
Files with missing lines Coverage Δ
src/interpreter/plugin/AddressPlugin.ts 100.00% <ø> (ø)
src/interpreter/plugin/FunctionPlugin.ts 99.04% <100.00%> (+0.02%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant