diff options
| author | William Boman <william@redwill.se> | 2023-03-05 02:45:00 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-05 02:45:00 +0100 |
| commit | 5887ce1c8031fb15e5cdcf43999db01b19536d6e (patch) | |
| tree | 9cb37a72e28e61d84e5ffa7fdbef33ef394b1531 | |
| parent | feat(InstallContext): add strict_mode flag (#1055) (diff) | |
| download | mason-5887ce1c8031fb15e5cdcf43999db01b19536d6e.tar mason-5887ce1c8031fb15e5cdcf43999db01b19536d6e.tar.gz mason-5887ce1c8031fb15e5cdcf43999db01b19536d6e.tar.bz2 mason-5887ce1c8031fb15e5cdcf43999db01b19536d6e.tar.lz mason-5887ce1c8031fb15e5cdcf43999db01b19536d6e.tar.xz mason-5887ce1c8031fb15e5cdcf43999db01b19536d6e.tar.zst mason-5887ce1c8031fb15e5cdcf43999db01b19536d6e.zip | |
refactor(expr): better handling of nil values (#1056)
| -rw-r--r-- | lua/mason-core/installer/registry/expr.lua | 26 | ||||
| -rw-r--r-- | tests/mason-core/installer/registry/expr_spec.lua | 19 |
2 files changed, 21 insertions, 24 deletions
diff --git a/lua/mason-core/installer/registry/expr.lua b/lua/mason-core/installer/registry/expr.lua index c6a6aafe..1fdeeee8 100644 --- a/lua/mason-core/installer/registry/expr.lua +++ b/lua/mason-core/installer/registry/expr.lua @@ -37,36 +37,30 @@ local function shallow_clone(tbl) return res end +---@param expr string +---@param ctx table<string, any> +local function eval(expr, ctx) + return setfenv(assert(loadstring("return " .. expr), ("Failed to parse expression: %q"):format(expr)), ctx)() +end + ---@param str string ---@param ctx table<string, any> function M.interpolate(str, ctx) ctx = shallow_clone(ctx) + setmetatable(ctx, { __index = FILTERS }) return Result.pcall(function() - setmetatable(ctx, { __index = FILTERS }) return _.gsub("{{([^}]+)}}", function(expr) local components = parse_expr(expr) - local value = assert( - setfenv( - assert( - loadstring("return " .. components.value_expr), - ("Failed to parse value: %q"):format(components.value_expr) - ), - ctx - )(), - ("Value is nil: %q"):format(components.value_expr) - ) + local value = eval(components.value_expr, ctx) local filters = _.map(function(filter_expr) - local filter = setfenv( - assert(loadstring("return " .. filter_expr), ("Failed to parse filter: %q"):format(filter_expr)), - ctx - )() + local filter = eval(filter_expr, ctx) assert(type(filter) == "function", ("Invalid filter expression: %q"):format(filter_expr)) return filter end, components.filters) - return _.reduce(_.apply_to, value, filters) + return _.reduce(_.apply_to, value, filters) or "" end, str) end) end diff --git a/tests/mason-core/installer/registry/expr_spec.lua b/tests/mason-core/installer/registry/expr_spec.lua index a52ca48b..c628381a 100644 --- a/tests/mason-core/installer/registry/expr_spec.lua +++ b/tests/mason-core/installer/registry/expr_spec.lua @@ -61,12 +61,16 @@ describe("registry expressions", function() ) end) - it("should reject invalid values", function() - assert.is_true( - match.matches [[^.*Value is nil: "non_existent"]]( - expr.interpolate("Hello, {{non_existent}}", {}):err_or_nil() - ) - ) + it("should not interpolate nil values", function() + assert.same(Result.success "Hello, ", expr.interpolate("Hello, {{non_existent}}", {})) + assert.same(Result.success "", expr.interpolate("{{non_existent}}", {})) + end) + + it("should error if piping nil values to functions that require non-nil values", function() + local err = assert.has_error(function() + expr.interpolate("Hello, {{ non_existent | to_upper }}", {}):get_or_throw() + end) + assert.is_true(match.matches "attempt to index local 'str' %(a nil value%)$"(err)) end) it("should reject invalid filters", function() @@ -75,9 +79,8 @@ describe("registry expressions", function() expr.interpolate("Hello, {{ value | whut }}", { value = "value" }):err_or_nil() ) ) - assert.is_true( - match.matches [[^.*Failed to parse filter: "wh%-!uut"]]( + match.matches [[^.*Failed to parse expression: "wh%-!uut"]]( expr.interpolate("Hello, {{ value | wh-!uut }}", { value = "value" }):err_or_nil() ) ) |
