Skip to content

Commit

Permalink
C API: add tests for external values
Browse files Browse the repository at this point in the history
  • Loading branch information
jlesquembre committed Feb 24, 2024
1 parent cca0542 commit 6bc5088
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 17 deletions.
2 changes: 1 addition & 1 deletion doc/external-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
}
Expand Down
15 changes: 15 additions & 0 deletions src/libexpr/c/nix_api_expr_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
15 changes: 0 additions & 15 deletions src/libexpr/c/nix_api_external.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/c/nix_api_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
83 changes: 83 additions & 0 deletions tests/unit/libexpr/nix_api_external.cc
Original file line number Diff line number Diff line change
@@ -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 <string>
#include <gtest/gtest.h>

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<MyExternalValueDesc *>(self);

std::string type_string = "nix-external<MyExternalValueDesc( ";
type_string += std::to_string(obj->_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<MyExternalValueDesc( 42 )>", nix_get_string(nullptr, valueResult));
}
}

0 comments on commit 6bc5088

Please sign in to comment.