diff --git a/src/language/ASTNodeFunctionExpressionBuilder.cpp b/src/language/ASTNodeFunctionExpressionBuilder.cpp
index 11183dbadb1395f3cfcde06017e57d6c8db5f9aa..4a7e095284b79227b344c4e8593596505ae5bca6 100644
--- a/src/language/ASTNodeFunctionExpressionBuilder.cpp
+++ b/src/language/ASTNodeFunctionExpressionBuilder.cpp
@@ -26,9 +26,11 @@ ASTNodeFunctionExpressionBuilder::_getArgumentProcessor(ASTNode& argument_node,
     case ASTNodeDataType::double_t: {
       return std::make_unique<FunctionArgumentProcessor<ArgumentT, double>>(argument_node, parameter_symbol);
     }
+      // LCOV_EXCL_START
     default: {
       throw parse_error("unexpected error: undefined parameter type for function", std::vector{argument_node.begin()});
     }
+      // LCOV_EXCL_STOP
     }
   };
 
@@ -46,9 +48,11 @@ ASTNodeFunctionExpressionBuilder::_getArgumentProcessor(ASTNode& argument_node,
     case ASTNodeDataType::double_t: {
       return get_function_argument_processor_for_parameter_type(double{});
     }
+      // LCOV_EXCL_START
     default: {
       throw parse_error("unexpected error: undefined argument type for function", std::vector{argument_node.begin()});
     }
+      // LCOV_EXCL_STOP
     }
   };
 
@@ -125,10 +129,12 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType ex
     case ASTNodeDataType::double_t: {
       return std::make_unique<FunctionExpressionProcessor<ReturnT, double>>(node);
     }
+      // LCOV_EXCL_START
     default: {
       throw parse_error("unexpected error: undefined expression value type for function",
                         std::vector{node.children[1]->begin()});
     }
+      // LCOV_EXCL_STOP
     }
   };
 
@@ -146,9 +152,11 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType ex
     case ASTNodeDataType::double_t: {
       return get_function_processor_for_expression_value(double{});
     }
+      // LCOV_EXCL_START
     default: {
       throw parse_error("unexpected error: undefined return type for function", std::vector{node.begin()});
     }
+      // LCOV_EXCL_STOP
     }
   };
 
@@ -166,8 +174,10 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node
   FunctionDescriptor& function_descriptor = node.m_symbol_table->functionTable()[function_id];
 
   if (function_descriptor.definitionNode().children[1]->is_type<language::expression_list>()) {
+    // LCOV_EXCL_START
     throw parse_error("unexpected error: function expression list is not implemented yet",
                       std::vector{function_descriptor.definitionNode().children[1]->begin()});
+    // LCOV_EXCL_STOP
   }
 
   std::unique_ptr function_processor = std::make_unique<FunctionProcessor>();
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 084dd96eeb1fecbdac00abe7117602d801da8329..952e599ed03ff33588978ee9b2fb7d84df092b61 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -20,6 +20,7 @@ add_executable (unit_tests
   test_ASTNodeEmptyBlockCleaner.cpp
   test_ASTNodeExpressionBuilder.cpp
   test_ASTNodeFunctionEvaluationExpressionBuilder.cpp
+  test_ASTNodeFunctionExpressionBuilder.cpp
   test_ASTNodeIncDecExpressionBuilder.cpp
   test_ASTNodeJumpPlacementChecker.cpp
   test_ASTNodeListProcessor.cpp
diff --git a/tests/test_ASTNodeFunctionExpressionBuilder.cpp b/tests/test_ASTNodeFunctionExpressionBuilder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3512e213353305e392f90fbc600fe09ce91af5bc
--- /dev/null
+++ b/tests/test_ASTNodeFunctionExpressionBuilder.cpp
@@ -0,0 +1,293 @@
+#include <catch2/catch.hpp>
+
+#include <ASTNodeValueBuilder.hpp>
+
+#include <ASTBuilder.hpp>
+#include <ASTNodeDataTypeBuilder.hpp>
+
+#include <ASTModulesImporter.hpp>
+
+#include <ASTNodeExpressionBuilder.hpp>
+#include <ASTNodeFunctionEvaluationExpressionBuilder.hpp>
+#include <ASTNodeFunctionExpressionBuilder.hpp>
+#include <ASTNodeTypeCleaner.hpp>
+
+#include <ASTSymbolTableBuilder.hpp>
+
+#include <ASTPrinter.hpp>
+
+#include <PEGGrammar.hpp>
+
+#include <Demangle.hpp>
+
+#define CHECK_AST(data, expected_output)                                                            \
+  {                                                                                                 \
+    static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>);                  \
+    static_assert((std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view>) or    \
+                  (std::is_same_v<std::decay_t<decltype(expected_output)>, std::string>));          \
+                                                                                                    \
+    string_input input{data, "test.pgs"};                                                           \
+    auto ast = ASTBuilder::build(input);                                                            \
+                                                                                                    \
+    ASTModulesImporter{*ast};                                                                       \
+    ASTNodeTypeCleaner<language::import_instruction>{*ast};                                         \
+                                                                                                    \
+    ASTSymbolTableBuilder{*ast};                                                                    \
+    ASTNodeDataTypeBuilder{*ast};                                                                   \
+    ASTNodeValueBuilder{*ast};                                                                      \
+                                                                                                    \
+    ASTNodeTypeCleaner<language::declaration>{*ast};                                                \
+    ASTNodeTypeCleaner<language::let_declaration>{*ast};                                            \
+    ASTNodeExpressionBuilder{*ast};                                                                 \
+                                                                                                    \
+    std::stringstream ast_output;                                                                   \
+    ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::exec_type}}; \
+                                                                                                    \
+    REQUIRE(ast_output.str() == expected_output);                                                   \
+  }
+
+#define CHECK_AST_THROWS(data)                                                     \
+  {                                                                                \
+    static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>); \
+                                                                                   \
+    string_input input{data, "test.pgs"};                                          \
+    auto ast = ASTBuilder::build(input);                                           \
+                                                                                   \
+    ASTModulesImporter{*ast};                                                      \
+    ASTNodeTypeCleaner<language::import_instruction>{*ast};                        \
+                                                                                   \
+    ASTSymbolTableBuilder{*ast};                                                   \
+    ASTNodeDataTypeBuilder{*ast};                                                  \
+    ASTNodeValueBuilder{*ast};                                                     \
+                                                                                   \
+    ASTNodeTypeCleaner<language::declaration>{*ast};                               \
+    ASTNodeTypeCleaner<language::let_declaration>{*ast};                           \
+    REQUIRE_THROWS_AS(ASTNodeExpressionBuilder{*ast}, parse_error);                \
+  }
+
+TEST_CASE("ASTNodeFunctionExpressionBuilder", "[language]")
+{
+  SECTION("return a B")
+  {
+    SECTION("B argument")
+    {
+      SECTION("B parameter")
+      {
+        std::string_view data = R"(
+let not_v : B -> B, a -> not a;
+not_v(true);
+)";
+
+        std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:not_v:NameProcessor)
+     `-(language::true_kw:FakeProcessor)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("N parameter")
+      {
+        std::string_view data = R"(
+let not_v : B -> B, a -> not a;
+N n = 1;
+not_v(n);
+)";
+
+        std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:not_v:NameProcessor)
+     `-(language::name:n:NameProcessor)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("Z parameter")
+      {
+        std::string_view data = R"(
+let not_v : B -> B, a -> not a;
+not_v(-1);
+)";
+
+        std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:not_v:NameProcessor)
+     `-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
+         `-(language::integer:1:FakeProcessor)
+)";
+
+        CHECK_AST(data, result);
+      }
+
+      SECTION("R parameter")
+      {
+        std::string_view data = R"(
+let not_v : B -> B, a -> not a;
+not_v(1.3);
+)";
+
+        std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:not_v:NameProcessor)
+     `-(language::real:1.3:FakeProcessor)
+)";
+
+        CHECK_AST(data, result);
+      }
+    }
+
+    SECTION("N argument")
+    {
+      std::string_view data = R"(
+let test : N -> B, n -> n<10;
+test(2);
+)";
+
+      std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:test:NameProcessor)
+     `-(language::integer:2:FakeProcessor)
+)";
+
+      CHECK_AST(data, result);
+    }
+
+    SECTION("Z argument")
+    {
+      std::string_view data = R"(
+let test : Z -> B, z -> z>3;
+test(2);
+)";
+
+      std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:test:NameProcessor)
+     `-(language::integer:2:FakeProcessor)
+)";
+
+      CHECK_AST(data, result);
+    }
+
+    SECTION("R argument")
+    {
+      std::string_view data = R"(
+let test : R -> B, x -> x>2.3;
+test(2.1);
+)";
+
+      std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:test:NameProcessor)
+     `-(language::real:2.1:FakeProcessor)
+)";
+
+      CHECK_AST(data, result);
+    }
+  }
+
+  SECTION("return a N")
+  {
+    SECTION("N argument")
+    {
+      std::string_view data = R"(
+let test : N -> N, n -> n+2;
+test(2.1);
+)";
+
+      std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:test:NameProcessor)
+     `-(language::real:2.1:FakeProcessor)
+)";
+
+      CHECK_AST(data, result);
+    }
+
+    SECTION("Z argument")
+    {
+      std::string_view data = R"(
+let absolute : Z -> N, z -> (z>0)*z -(z<=0)*z;
+absolute(-2);
+)";
+
+      std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:absolute:NameProcessor)
+     `-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
+         `-(language::integer:2:FakeProcessor)
+)";
+
+      CHECK_AST(data, result);
+    }
+  }
+
+  SECTION("return a Z")
+  {
+    SECTION("N argument")
+    {
+      std::string_view data = R"(
+let minus : N -> Z, n -> -n;
+minus(true);
+)";
+
+      std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:minus:NameProcessor)
+     `-(language::true_kw:FakeProcessor)
+)";
+
+      CHECK_AST(data, result);
+    }
+
+    SECTION("Z argument")
+    {
+      std::string_view data = R"(
+let times_2_3 : Z -> Z, z -> z*2.3;
+times_2_3(-2);
+)";
+
+      std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::function_evaluation:FunctionProcessor)
+     +-(language::name:times_2_3:NameProcessor)
+     `-(language::unary_minus:UnaryExpressionProcessor<language::unary_minus, long, long>)
+         `-(language::integer:2:FakeProcessor)
+)";
+
+      CHECK_AST(data, result);
+    }
+  }
+
+  SECTION("errors")
+  {
+    SECTION("wrong argument number")
+    {
+      std::string_view data = R"(
+let Id : Z -> Z, z -> z;
+Id(2,3);
+)";
+      CHECK_AST_THROWS(data);
+    }
+
+    SECTION("wrong argument number 2")
+    {
+      std::string_view data = R"(
+let sum : R*R -> R, (x,y) -> x+y;
+sum(2);
+)";
+      CHECK_AST_THROWS(data);
+    }
+  }
+}