From 6bc50885162249a5466d6c2229a6776dd54ffe44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Lafuente?= Date: Sun, 25 Feb 2024 00:28:04 +0100 Subject: [PATCH] C API: add tests for external values --- doc/external-api/README.md | 2 +- src/libexpr/c/nix_api_expr_internal.h | 15 +++++ src/libexpr/c/nix_api_external.cc | 15 ----- src/libexpr/c/nix_api_value.h | 2 +- tests/unit/libexpr/nix_api_external.cc | 83 ++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 tests/unit/libexpr/nix_api_external.cc diff --git a/doc/external-api/README.md b/doc/external-api/README.md index e9ca25ab6d08..24118f9f05eb 100644 --- a/doc/external-api/README.md +++ b/doc/external-api/README.md @@ -82,7 +82,7 @@ will increment the argument if it is an integer and throw an error otherwise. void increment(void* user_data, nix_c_context* ctx, EvalState* state, Value** args, Value* v) { nix_value_force(NULL, state, args[0]); if (nix_get_type(NULL, args[0]) == NIX_TYPE_INT) { - nix_set_int(NULL, v, nix_get_int(NULL, args[0]) + 1); + nix_init_int(NULL, v, nix_get_int(NULL, args[0]) + 1); } else { nix_set_err_msg(ctx, NIX_ERR_UNKNOWN, "First argument should be an integer."); } diff --git a/src/libexpr/c/nix_api_expr_internal.h b/src/libexpr/c/nix_api_expr_internal.h index e116af165cf6..352ac496f1b1 100644 --- a/src/libexpr/c/nix_api_expr_internal.h +++ b/src/libexpr/c/nix_api_expr_internal.h @@ -14,4 +14,19 @@ struct BindingsBuilder nix::BindingsBuilder builder; }; +struct nix_string_return +{ + std::string str; +}; + +struct nix_printer +{ + std::ostream & s; +}; + +struct nix_string_context +{ + nix::NixStringContext & ctx; +}; + #endif // NIX_API_EXPR_INTERNAL_H diff --git a/src/libexpr/c/nix_api_external.cc b/src/libexpr/c/nix_api_external.cc index 3af4af4d4611..c237cfb708b8 100644 --- a/src/libexpr/c/nix_api_external.cc +++ b/src/libexpr/c/nix_api_external.cc @@ -20,21 +20,6 @@ #include "gc_cpp.h" #endif -struct nix_string_return -{ - std::string str; -}; - -struct nix_printer -{ - std::ostream & s; -}; - -struct nix_string_context -{ - nix::NixStringContext & ctx; -}; - void nix_set_string_return(nix_string_return * str, const char * c) { str->str = c; diff --git a/src/libexpr/c/nix_api_value.h b/src/libexpr/c/nix_api_value.h index 27027caf0d30..a9a640231fbd 100644 --- a/src/libexpr/c/nix_api_value.h +++ b/src/libexpr/c/nix_api_value.h @@ -52,7 +52,7 @@ typedef class ListBuilder ListBuilder; * @ingroup primops * * Owned by the GC - * @see nix_alloc_primop, nix_set_primop + * @see nix_alloc_primop, nix_init_primop */ typedef struct PrimOp PrimOp; /** @brief External Value diff --git a/tests/unit/libexpr/nix_api_external.cc b/tests/unit/libexpr/nix_api_external.cc new file mode 100644 index 000000000000..5f5353b049b1 --- /dev/null +++ b/tests/unit/libexpr/nix_api_external.cc @@ -0,0 +1,83 @@ +#include "nix_api_store.h" +#include "nix_api_store_internal.h" +#include "nix_api_util.h" +#include "nix_api_util_internal.h" +#include "nix_api_expr.h" +#include "nix_api_expr_internal.h" +#include "nix_api_value.h" +#include "nix_api_external.h" +#include "tests/nix_api_store.hh" + +#include +#include + +namespace nixC { + +class MyExternalValueDesc : public NixCExternalValueDesc +{ +public: + MyExternalValueDesc(int x) + : _x(x) + { + print = print_function; + showType = show_type_function; + typeOf = type_of_function; + } + +private: + int _x; + static void print_function(void * self, nix_printer * printer) {} + + static void show_type_function(void * self, nix_string_return * res) {} + + static void type_of_function(void * self, nix_string_return * res) + { + std::cout << self << std::endl; + MyExternalValueDesc * obj = static_cast(self); + + std::string type_string = "nix-external_x); + type_string += " )>"; + res->str = &*type_string.begin(); + } +}; + +class nix_api_external_test : public nix_api_store_test +{ +public: + nix_api_external_test() + { + state = nix_state_create(nullptr, nullptr, store); + value = nix_alloc_value(nullptr, state); + } + ~nix_api_external_test() + { + nix_gc_decref(nullptr, value); + nix_state_free(state); + } + + EvalState * state; + Value * value; +}; + +TEST_F(nix_api_external_test, nix_expr_eval_from_string) +{ + MyExternalValueDesc * external = new MyExternalValueDesc(42); + ExternalValue * val = nix_create_external_value(ctx, external, external); + nix_init_external(nullptr, value, val); + + EvalState * stateResult = nix_state_create(nullptr, nullptr, store); + Value * valueResult = nix_alloc_value(nullptr, stateResult); + + EvalState * stateFn = nix_state_create(nullptr, nullptr, store); + Value * valueFn = nix_alloc_value(nullptr, stateFn); + + nix_expr_eval_from_string(nullptr, state, "builtins.typeOf", ".", valueFn); + + ASSERT_EQ(NIX_TYPE_EXTERNAL, nix_get_type(nullptr, value)); + + nix_value_call(ctx, state, valueFn, value, valueResult); + + ASSERT_STREQ("nix-external", nix_get_string(nullptr, valueResult)); +} +}