diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/Float2NrFunctionTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/Float2NrFunctionTest.kt new file mode 100644 index 000000000..6a5c313a2 --- /dev/null +++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/floatFunctions/Float2NrFunctionTest.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2003-2025 The IdeaVim authors + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE.txt file or at + * https://opensource.org/licenses/MIT. + */ + +package org.jetbrains.plugins.ideavim.ex.implementation.functions.floatFunctions + +import org.jetbrains.plugins.ideavim.VimBehaviorDiffers +import org.jetbrains.plugins.ideavim.VimTestCase +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInfo + +class Float2NrFunctionTest : VimTestCase() { + @BeforeEach + override fun setUp(testInfo: TestInfo) { + super.setUp(testInfo) + configureByText("\n") + } + + @Test + fun `test float2nr returns integer value for integer`() { + assertCommandOutput("echo float2nr(42)", "42") + } + + @VimBehaviorDiffers( + originalVimAfter = "3 -23 2147483647 -2147483647 0", + description = "The Vim docs say float2nr(-1.0e150) should return -2147483647 not -2147483648" + ) + @Test + fun `test float2nr returns integer value for float`() { + assertCommandOutput( + "echo float2nr(3.95) float2nr(-23.45) float2nr(1.0e100) float2nr(-1.0e150) float2nr(1.0e-100)", + "3 -23 2147483647 -2147483648 0" + ) + } + + @Test + fun `test float2nr with string causes errors`() { + enterCommand("echo float2nr('1.0')") + assertPluginError(true) + assertPluginErrorMessageContains("E808: Number or Float required") + } + + @Test + fun `test float2nr with invalid string causes errors`() { + enterCommand("echo float2nr('cheese')") + assertPluginError(true) + assertPluginErrorMessageContains("E808: Number or Float required") + } + + @Test + fun `test float2nr with list causes errors`() { + enterCommand("echo float2nr([1.0])") + assertPluginError(true) + assertPluginErrorMessageContains("E808: Number or Float required") + } + + @Test + fun `test float2nr with dictionary causes errors`() { + enterCommand("echo float2nr({1: 1.0})") + assertPluginError(true) + assertPluginErrorMessageContains("E808: Number or Float required") + } +} diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/Float2NrFunctionHandler.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/Float2NrFunctionHandler.kt new file mode 100644 index 000000000..d05c43df2 --- /dev/null +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/floatFunctions/Float2NrFunctionHandler.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2003-2025 The IdeaVim authors + * + * Use of this source code is governed by an MIT-style + * license that can be found in the LICENSE.txt file or at + * https://opensource.org/licenses/MIT. + */ + +package com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions + +import com.intellij.vim.annotations.VimscriptFunction +import com.maddyhome.idea.vim.api.ExecutionContext +import com.maddyhome.idea.vim.api.VimEditor +import com.maddyhome.idea.vim.ex.exExceptionMessage +import com.maddyhome.idea.vim.vimscript.model.VimLContext +import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType +import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFloat +import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt +import com.maddyhome.idea.vim.vimscript.model.expressions.Expression +import com.maddyhome.idea.vim.vimscript.model.functions.FunctionHandler + +@VimscriptFunction(name = "float2nr") +internal class Float2NrFunctionHandler : FunctionHandler() { + override val minimumNumberOfArguments = 1 + override val maximumNumberOfArguments = 1 + + override fun doFunction( + argumentValues: List<Expression>, + editor: VimEditor, + context: ExecutionContext, + vimContext: VimLContext, + ): VimDataType { + val argument = argumentValues[0].evaluate(editor, context, vimContext) + if (argument !is VimFloat && argument !is VimInt) { + throw exExceptionMessage("E808") // E808: Number or Float required + } + return VimInt(argument.asDouble().toInt()) + } +} diff --git a/vim-engine/src/main/resources/ksp-generated/engine_vimscript_functions.json b/vim-engine/src/main/resources/ksp-generated/engine_vimscript_functions.json index bb4aa8a31..ea8284eaa 100644 --- a/vim-engine/src/main/resources/ksp-generated/engine_vimscript_functions.json +++ b/vim-engine/src/main/resources/ksp-generated/engine_vimscript_functions.json @@ -13,6 +13,7 @@ "escape": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.stringFunctions.EscapeFunctionHandler", "exists": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.variousFunctions.ExistsFunctionHandler", "exp": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.ExpFunctionHandler", + "float2nr": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.Float2NrFunctionHandler", "floor": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.FloorFunctionHandler", "fmod": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.floatFunctions.FmodFunctionHandler", "funcref": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.varFunctions.FuncrefFunctionHandler",