Initial signature test

This commit is contained in:
Carlos Martín Nieto
2013-06-11 16:34:02 +02:00
parent f8f791296a
commit 9d222df593
8 changed files with 127 additions and 0 deletions

View File

@@ -10,6 +10,7 @@
#include "library.h" #include "library.h"
#include "revwalk.h" #include "revwalk.h"
#include "index.h" #include "index.h"
#include "signature.h"
#include "geef.h" #include "geef.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -178,6 +179,8 @@ static ErlNifFunc geef_funcs[] =
{"index_add", 2, geef_index_add}, {"index_add", 2, geef_index_add},
{"index_clear", 1, geef_index_clear}, {"index_clear", 1, geef_index_clear},
{"index_read_tree", 2, geef_index_read_tree}, {"index_read_tree", 2, geef_index_read_tree},
{"signature_new", 2, geef_signature_new},
{"signature_new", 3, geef_signature_new},
}; };
ERL_NIF_INIT(geef_nif, geef_funcs, load, NULL, upgrade, unload) ERL_NIF_INIT(geef_nif, geef_funcs, load, NULL, upgrade, unload)

65
c_src/signature.c Normal file
View File

@@ -0,0 +1,65 @@
#include "geef.h"
#include <string.h>
#include <git2.h>
ERL_NIF_TERM
geef_signature_new(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary name, email;
git_signature *sig;
size_t len;
int error;
unsigned int at;
if (!enif_inspect_iolist_as_binary(env, argv[0], &name))
return enif_make_badarg(env);
if (!enif_inspect_iolist_as_binary(env, argv[1], &email))
return enif_make_badarg(env);
if (argc == 3 && !enif_get_uint(env, argv[2], &at))
return enif_make_badarg(env);
if (!geef_terminate_binary(&name))
return atoms.error;
if (!geef_terminate_binary(&email)) {
enif_release_binary(&name);
return atoms.error;
}
if (argc == 3)
error = git_signature_now(&sig, (char *)name.data, (char *)email.data);
else
error = git_signature_new(&sig, (char *)name.data, (char *)email.data, at, 0);
if (error < 0)
return geef_error(env);
len = strlen(sig->name);
if (!enif_realloc_binary(&name, len))
goto on_error;
memcpy(name.data, sig->name, len);
len = strlen(sig->email);
if (!enif_realloc_binary(&email, len))
goto on_error;
memcpy(email.data, sig->email, len);
git_signature_free(sig);
if (argc == 3)
return enif_make_tuple3(env, atoms.ok, enif_make_binary(env, &name), enif_make_binary(env, &email));
return enif_make_tuple5(env, atoms.ok,
enif_make_binary(env, &name), enif_make_binary(env, &email),
enif_make_ulong(env, sig->when.time), enif_make_uint(env, sig->when.offset));
on_error:
git_signature_free(sig);
enif_release_binary(&name);
enif_release_binary(&email);
return atoms.error;
}

3
c_src/signature.h Normal file
View File

@@ -0,0 +1,3 @@
#include "geef.h"
ERL_NIF_TERM geef_signature_new(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);

9
lib/geef/signature.ex Normal file
View File

@@ -0,0 +1,9 @@
defrecord Geef.Signature, Record.extract(:geef_signature, from: "src/geef_records.hrl") do
def new(name, email), do: :geef_sig.new(name, email) |> maybe_sig
def new(name, email, time), do: :geef_sig.new(name, email, time) |> maybe_sig
defp maybe_sig({ok, sig}), do: {ok, Geef.Signature.new sig}
defp maybe_sig(error), do: error
end

View File

@@ -148,6 +148,12 @@ index_add(_Handle, _Entry) ->
index_clear(_Handle) -> index_clear(_Handle) ->
?NIF_FN. ?NIF_FN.
signature_new(_Name, _Email) ->
?NIF_FN.
signature_new(_Name, _Email, _Time) ->
?NIF_FN.
nif_error(Line) -> nif_error(Line) ->
erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}). erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}).

View File

@@ -12,6 +12,7 @@
-record(geef_request, {service :: atom, path :: binary(), host :: binary()}). -record(geef_request, {service :: atom, path :: binary(), host :: binary()}).
-record(geef_tree_entry, {mode, type, id, name}). -record(geef_tree_entry, {mode, type, id, name}).
-record(geef_signature, {name :: iolist(), email :: iolist(), time :: geef_time()}).
-type geef_reference() :: #geef_reference{}. -type geef_reference() :: #geef_reference{}.
-type geef_oid() :: #geef_oid{}. -type geef_oid() :: #geef_oid{}.
@@ -19,3 +20,5 @@
-type geef_index_entry() :: #geef_index_entry{}. -type geef_index_entry() :: #geef_index_entry{}.
-type geef_request() :: #geef_request{}. -type geef_request() :: #geef_request{}.
-type geef_tree_entry() :: #geef_tree_entry{}. -type geef_tree_entry() :: #geef_tree_entry{}.
-type geef_signature() :: #geef_signature{}.
-type geef_time() :: {erlang:timestamp(), non_neg_integer()}.

24
src/geef_sig.erl Normal file
View File

@@ -0,0 +1,24 @@
-module(geef_sig).
-include("geef_records.hrl").
-export([new/2, new/3]).
-spec new(iolist(), iolist()) -> geef_signature() | {error, term()}.
new(Name0, Email0) ->
case geef_nif:signature_new(Name0, Email0) of
{ok, Name, Email, Time0, Offset} ->
Time = {{Time0 div 1000000, Time0 rem 1000000, 0}, Offset},
{ok, #geef_signature{name=Name, email=Email, time=Time}};
Err ->
Err
end.
-spec new(iolist(), iolist(), geef_time()) -> geef_signature() | {error, term()}.
new(Name0, Email0, Time) ->
case geef_nif:signature_new(Name0, Email0, 0) of
{ok, Name, Email} ->
{ok, #geef_signature{name=Name, email=Email, time=Time}};
Err ->
Err
end.

14
test/sig_test.erl Normal file
View File

@@ -0,0 +1,14 @@
-module(sig_test).
-compile([export_all]).
-include_lib("eunit/include/eunit.hrl").
-include("src/geef_records.hrl").
now_test() ->
Sig = geef_sig:new("Carlos", "a@b.c"),
?assertMatch(#geef_signature{name = <<"Carlos">>, email = <<"a@b.c">>, time=_}, Sig).
at_test() ->
Time = {os:timestamp(), 120},
Actual = geef_sig:new("Carlos", "a@b.c", Time),
Expected = #geef_signature{name = <<"Carlos">>, email = <<"a@b.c">>, time = Time},
?assertEqual(Expected, Actual).