Skip to content

fix: respect defaultValue when arg is AstNodeType.EMPTY#1631

Open
marcin-kordas-hoc wants to merge 1 commit intodevelopfrom
fix/empty-default-value
Open

fix: respect defaultValue when arg is AstNodeType.EMPTY#1631
marcin-kordas-hoc wants to merge 1 commit 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 an empty argument (e.g. =VLOOKUP(2,A1:B3,2,)), the parser
produces AstNodeType.EMPTY which evaluates to EmptyValue (a Symbol sentinel).

The guard in FunctionPlugin.coerceArgumentsToRequiredTypes checked only for
undefined, so EmptyValue passed through and was coerced to 0/false instead
of using the parameter's declared defaultValue.

Affected functions: any plugin parameter with defaultValue ≠ 0/false
(e.g. LOG base=10, VLOOKUP/HLOOKUP sorted=true, MATCH matchType=1, ADDRESS abs=1).

Fix

In FunctionPlugin.coerceArgumentsToRequiredTypes: when the runtime value is
EmptyValue and the parameter declares an explicit defaultValue, substitute
defaultValue instead of passing EmptyValue to type coercion.

Tests

Regression tests in companion PR in handsontable/hyperformula-tests
(branch fix/empty-default-value): covers VLOOKUP, HLOOKUP, MATCH, ADDRESS, LOG.


Note

Medium Risk
Touches central interpreter argument-coercion logic, which can subtly change results for many functions when users pass empty trailing arguments.

Overview
Fixes function argument handling so an explicitly empty argument (parsed as AstNodeType.EMPTY and evaluated to EmptyValue) now uses the parameter’s declared defaultValue instead of being coerced as a real value.

This updates FunctionPlugin.coerceArgumentsToRequiredTypes to substitute defaultValue when rawArg === EmptyValue (and a defaultValue is defined), aligning behavior with omitted arguments across functions like VLOOKUP/MATCH/LOG that rely on non-zero defaults.

Written by Cursor Bugbot for commit f68ecd8. 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
@codecov
Copy link

codecov bot commented Mar 5, 2026

Codecov Report

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

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/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.

@github-actions
Copy link

github-actions bot commented Mar 5, 2026

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

                                     testName |   base |   head |  change
-------------------------------------------------------------------------
                                      Sheet A | 487.97 | 510.13 |  +4.54%
                                      Sheet B | 157.51 | 165.76 |  +5.24%
                                      Sheet T | 139.65 | 142.29 |  +1.89%
                                Column ranges | 471.82 | 472.25 |  +0.09%
Sheet A:  change value, add/remove row/column |  15.76 |  17.53 | +11.23%
 Sheet B: change value, add/remove row/column | 138.56 | 138.14 |  -0.30%
                   Column ranges - add column | 152.63 | 156.85 |  +2.76%
                Column ranges - without batch | 452.06 | 471.83 |  +4.37%
                        Column ranges - batch | 113.42 | 117.22 |  +3.35%

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