Commit c63793ee by Vicent Martí

attr: Change the attribute check macros

The point of having `GIT_ATTR_TRUE` and `GIT_ATTR_FALSE` macros is to be
able to change the way that true and false values are stored inside of
the returned gitattributes value pointer.

However, if these macros are implemented as a simple rename for the
`git_attr__true` pointer, they will always be used with the `==`
operator, and hence we cannot really change the implementation to any
other way that doesn't imply using special pointer values and comparing
them!

We need to do the same thing that core Git does, which is using a
function macro. With `GIT_ATTR_TRUE(attr)`, we can change
internally the way that these values are stored to anything we want.

This commit does that, and rewrites a large chunk of the attributes test
suite to remove duplicated code for expected attributes, and to
properly test the function macro behavior instead of comparing
pointers.
parent 47a899ff
......@@ -19,12 +19,12 @@
*/
GIT_BEGIN_DECL
#define GIT_ATTR_TRUE git_attr__true
#define GIT_ATTR_FALSE git_attr__false
#define GIT_ATTR_UNSPECIFIED NULL
#define GIT_ATTR_TRUE(attr) ((attr) == git_attr__true)
#define GIT_ATTR_FALSE(attr) ((attr) == git_attr__false)
#define GIT_ATTR_UNSPECIFIED(attr) ((attr) == NULL)
GIT_EXTERN(const char *)git_attr__true;
GIT_EXTERN(const char *)git_attr__false;
GIT_EXTERN(const char *) git_attr__true;
GIT_EXTERN(const char *) git_attr__false;
/**
......
......@@ -458,12 +458,12 @@ int git_attr_assignment__parse(
}
assign->name_hash = 5381;
assign->value = GIT_ATTR_TRUE;
assign->value = git_attr__true;
assign->is_allocated = 0;
/* look for magic name prefixes */
if (*scan == '-') {
assign->value = GIT_ATTR_FALSE;
assign->value = git_attr__false;
scan++;
} else if (*scan == '!') {
assign->value = NULL; /* explicit unspecified state */
......@@ -510,7 +510,7 @@ int git_attr_assignment__parse(
}
/* expand macros (if given a repo with a macro cache) */
if (repo != NULL && assign->value == GIT_ATTR_TRUE) {
if (repo != NULL && assign->value == git_attr__true) {
git_attr_rule *macro =
git_hashtable_lookup(repo->attrcache.macros, assign->name);
......
......@@ -25,13 +25,13 @@ struct crlf_filter {
static int check_crlf(const char *value)
{
if (value == git_attr__true)
if (GIT_ATTR_TRUE(value))
return GIT_CRLF_TEXT;
if (value == git_attr__false)
if (GIT_ATTR_FALSE(value))
return GIT_CRLF_BINARY;
if (value == NULL)
if (GIT_ATTR_UNSPECIFIED(value))
return GIT_CRLF_GUESS;
if (strcmp(value, "input") == 0)
......@@ -45,7 +45,7 @@ static int check_crlf(const char *value)
static int check_eol(const char *value)
{
if (value == NULL)
if (GIT_ATTR_UNSPECIFIED(value))
return GIT_EOL_UNSET;
if (strcmp(value, "lf") == 0)
......
#include "clar_libgit2.h"
#include "attr_file.h"
#include "attr_expect.h"
#define get_rule(X) ((git_attr_rule *)git_vector_get(&file->rules,(X)))
#define get_assign(R,Y) ((git_attr_assignment *)git_vector_get(&(R)->assigns,(Y)))
......@@ -25,7 +26,7 @@ void test_attr_file__simple_read(void)
assign = get_assign(rule, 0);
cl_assert(assign != NULL);
cl_assert_strequal("binary", assign->name);
cl_assert(assign->value == GIT_ATTR_TRUE);
cl_assert(GIT_ATTR_TRUE(assign->value));
cl_assert(!assign->is_allocated);
git_attr_file__free(file);
......@@ -54,7 +55,7 @@ void test_attr_file__match_variants(void)
assign = get_assign(rule,0);
cl_assert_strequal("attr0", assign->name);
cl_assert(assign->name_hash == git_attr_file__name_hash(assign->name));
cl_assert(assign->value == GIT_ATTR_TRUE);
cl_assert(GIT_ATTR_TRUE(assign->value));
cl_assert(!assign->is_allocated);
rule = get_rule(1);
......@@ -83,7 +84,7 @@ void test_attr_file__match_variants(void)
cl_assert(rule->assigns.length == 1);
assign = get_assign(rule,0);
cl_assert_strequal("attr7", assign->name);
cl_assert(assign->value == GIT_ATTR_TRUE);
cl_assert(GIT_ATTR_TRUE(assign->value));
rule = get_rule(8);
cl_assert_strequal("pat8 with spaces", rule->match.pattern);
......@@ -102,8 +103,8 @@ static void check_one_assign(
int assign_idx,
const char *pattern,
const char *name,
const char *value,
int is_allocated)
enum attr_expect_t expected,
const char *expected_str)
{
git_attr_rule *rule = get_rule(rule_idx);
git_attr_assignment *assign = get_assign(rule, assign_idx);
......@@ -112,11 +113,8 @@ static void check_one_assign(
cl_assert(rule->assigns.length == 1);
cl_assert_strequal(name, assign->name);
cl_assert(assign->name_hash == git_attr_file__name_hash(assign->name));
cl_assert(assign->is_allocated == is_allocated);
if (is_allocated)
cl_assert_strequal(value, assign->value);
else
cl_assert(assign->value == value);
attr_check_expected(expected, expected_str, assign->value);
}
void test_attr_file__assign_variants(void)
......@@ -130,14 +128,14 @@ void test_attr_file__assign_variants(void)
cl_assert_strequal(cl_fixture("attr/attr2"), file->path);
cl_assert(file->rules.length == 11);
check_one_assign(file, 0, 0, "pat0", "simple", GIT_ATTR_TRUE, 0);
check_one_assign(file, 1, 0, "pat1", "neg", GIT_ATTR_FALSE, 0);
check_one_assign(file, 2, 0, "*", "notundef", GIT_ATTR_TRUE, 0);
check_one_assign(file, 3, 0, "pat2", "notundef", NULL, 0);
check_one_assign(file, 4, 0, "pat3", "assigned", "test-value", 1);
check_one_assign(file, 5, 0, "pat4", "rule-with-more-chars", "value-with-more-chars", 1);
check_one_assign(file, 6, 0, "pat5", "empty", GIT_ATTR_TRUE, 0);
check_one_assign(file, 7, 0, "pat6", "negempty", GIT_ATTR_FALSE, 0);
check_one_assign(file, 0, 0, "pat0", "simple", EXPECT_TRUE, NULL);
check_one_assign(file, 1, 0, "pat1", "neg", EXPECT_FALSE, NULL);
check_one_assign(file, 2, 0, "*", "notundef", EXPECT_TRUE, NULL);
check_one_assign(file, 3, 0, "pat2", "notundef", EXPECT_UNDEFINED, NULL);
check_one_assign(file, 4, 0, "pat3", "assigned", EXPECT_STRING, "test-value");
check_one_assign(file, 5, 0, "pat4", "rule-with-more-chars", EXPECT_STRING, "value-with-more-chars");
check_one_assign(file, 6, 0, "pat5", "empty", EXPECT_TRUE, NULL);
check_one_assign(file, 7, 0, "pat6", "negempty", EXPECT_FALSE, NULL);
rule = get_rule(8);
cl_assert_strequal("pat7", rule->match.pattern);
......@@ -148,11 +146,11 @@ void test_attr_file__assign_variants(void)
assign = git_attr_rule__lookup_assignment(rule, "multiple");
cl_assert(assign);
cl_assert_strequal("multiple", assign->name);
cl_assert(assign->value == GIT_ATTR_TRUE);
cl_assert(GIT_ATTR_TRUE(assign->value));
assign = git_attr_rule__lookup_assignment(rule, "single");
cl_assert(assign);
cl_assert_strequal("single", assign->name);
cl_assert(assign->value == GIT_ATTR_FALSE);
cl_assert(GIT_ATTR_FALSE(assign->value));
assign = git_attr_rule__lookup_assignment(rule, "values");
cl_assert(assign);
cl_assert_strequal("values", assign->name);
......@@ -174,13 +172,13 @@ void test_attr_file__assign_variants(void)
assign = git_attr_rule__lookup_assignment(rule, "again");
cl_assert(assign);
cl_assert_strequal("again", assign->name);
cl_assert(assign->value == GIT_ATTR_TRUE);
cl_assert(GIT_ATTR_TRUE(assign->value));
assign = git_attr_rule__lookup_assignment(rule, "another");
cl_assert(assign);
cl_assert_strequal("another", assign->name);
cl_assert_strequal("12321", assign->value);
check_one_assign(file, 10, 0, "pat9", "at-eof", GIT_ATTR_FALSE, 0);
check_one_assign(file, 10, 0, "pat9", "at-eof", EXPECT_FALSE, NULL);
git_attr_file__free(file);
}
......@@ -204,10 +202,10 @@ void test_attr_file__check_attr_examples(void)
cl_assert_strequal("java", assign->value);
assign = git_attr_rule__lookup_assignment(rule, "crlf");
cl_assert_strequal("crlf", assign->name);
cl_assert(GIT_ATTR_FALSE == assign->value);
cl_assert(GIT_ATTR_FALSE(assign->value));
assign = git_attr_rule__lookup_assignment(rule, "myAttr");
cl_assert_strequal("myAttr", assign->name);
cl_assert(GIT_ATTR_TRUE == assign->value);
cl_assert(GIT_ATTR_TRUE(assign->value));
assign = git_attr_rule__lookup_assignment(rule, "missing");
cl_assert(assign == NULL);
......
#include "clar_libgit2.h"
#include "attr_file.h"
#include "attr_expect.h"
void test_attr_lookup__simple(void)
{
git_attr_file *file;
......@@ -18,7 +20,7 @@ void test_attr_lookup__simple(void)
cl_assert(!path.is_dir);
cl_git_pass(git_attr_file__lookup_one(file,&path,"binary",&value));
cl_assert(value == GIT_ATTR_TRUE);
cl_assert(GIT_ATTR_TRUE(value));
cl_git_pass(git_attr_file__lookup_one(file,&path,"missing",&value));
cl_assert(!value);
......@@ -26,36 +28,23 @@ void test_attr_lookup__simple(void)
git_attr_file__free(file);
}
typedef struct {
const char *path;
const char *attr;
const char *expected;
int use_strcmp;
int force_dir;
} test_case;
static void run_test_cases(git_attr_file *file, test_case *cases)
static void run_test_cases(git_attr_file *file, struct attr_expected *cases, int force_dir)
{
git_attr_path path;
const char *value = NULL;
test_case *c;
struct attr_expected *c;
int error;
for (c = cases; c->path != NULL; c++) {
cl_git_pass(git_attr_path__init(&path, c->path, NULL));
if (c->force_dir)
if (force_dir)
path.is_dir = 1;
error = git_attr_file__lookup_one(file,&path,c->attr,&value);
if (error != GIT_SUCCESS)
fprintf(stderr, "failure with %s %s %s\n", c->path, c->attr, c->expected);
cl_git_pass(error);
if (c->use_strcmp)
cl_assert_strequal(c->expected, value);
else
cl_assert(c->expected == value);
attr_check_expected(c->expected, c->expected_str, value);
}
}
......@@ -63,74 +52,79 @@ void test_attr_lookup__match_variants(void)
{
git_attr_file *file;
git_attr_path path;
test_case cases[] = {
struct attr_expected dir_cases[] = {
{ "pat2", "attr2", EXPECT_TRUE, NULL },
{ "/testing/for/pat2", "attr2", EXPECT_TRUE, NULL },
{ "/not/pat2/yousee", "attr2", EXPECT_UNDEFINED, NULL },
{ "/fun/fun/fun/pat4.dir", "attr4", EXPECT_TRUE, NULL },
{ "foo.pat5", "attr5", EXPECT_TRUE, NULL },
{ NULL, NULL, 0, NULL }
};
struct attr_expected cases[] = {
/* pat0 -> simple match */
{ "pat0", "attr0", GIT_ATTR_TRUE, 0, 0 },
{ "/testing/for/pat0", "attr0", GIT_ATTR_TRUE, 0, 0 },
{ "relative/to/pat0", "attr0", GIT_ATTR_TRUE, 0, 0 },
{ "this-contains-pat0-inside", "attr0", NULL, 0, 0 },
{ "this-aint-right", "attr0", NULL, 0, 0 },
{ "/this/pat0/dont/match", "attr0", NULL, 0, 0 },
{ "pat0", "attr0", EXPECT_TRUE, NULL },
{ "/testing/for/pat0", "attr0", EXPECT_TRUE, NULL },
{ "relative/to/pat0", "attr0", EXPECT_TRUE, NULL },
{ "this-contains-pat0-inside", "attr0", EXPECT_UNDEFINED, NULL },
{ "this-aint-right", "attr0", EXPECT_UNDEFINED, NULL },
{ "/this/pat0/dont/match", "attr0", EXPECT_UNDEFINED, NULL },
/* negative match */
{ "pat0", "attr1", GIT_ATTR_TRUE, 0, 0 },
{ "pat1", "attr1", NULL, 0, 0 },
{ "/testing/for/pat1", "attr1", NULL, 0, 0 },
{ "/testing/for/pat0", "attr1", GIT_ATTR_TRUE, 0, 0 },
{ "/testing/for/pat1/inside", "attr1", GIT_ATTR_TRUE, 0, 0 },
{ "misc", "attr1", GIT_ATTR_TRUE, 0, 0 },
{ "pat0", "attr1", EXPECT_TRUE, NULL },
{ "pat1", "attr1", EXPECT_UNDEFINED, NULL },
{ "/testing/for/pat1", "attr1", EXPECT_UNDEFINED, NULL },
{ "/testing/for/pat0", "attr1", EXPECT_TRUE, NULL },
{ "/testing/for/pat1/inside", "attr1", EXPECT_TRUE, NULL },
{ "misc", "attr1", EXPECT_TRUE, NULL },
/* dir match */
{ "pat2", "attr2", NULL, 0, 0 },
{ "pat2", "attr2", GIT_ATTR_TRUE, 0, 1 },
{ "/testing/for/pat2", "attr2", NULL, 0, 0 },
{ "/testing/for/pat2", "attr2", GIT_ATTR_TRUE, 0, 1 },
{ "/not/pat2/yousee", "attr2", NULL, 0, 0 },
{ "/not/pat2/yousee", "attr2", NULL, 0, 1 },
{ "pat2", "attr2", EXPECT_UNDEFINED, NULL },
{ "/testing/for/pat2", "attr2", EXPECT_UNDEFINED, NULL },
{ "/not/pat2/yousee", "attr2", EXPECT_UNDEFINED, NULL },
/* path match */
{ "pat3file", "attr3", NULL, 0, 0 },
{ "/pat3dir/pat3file", "attr3", NULL, 0, 0 },
{ "pat3dir/pat3file", "attr3", GIT_ATTR_TRUE, 0, 0 },
{ "pat3file", "attr3", EXPECT_UNDEFINED, NULL },
{ "/pat3dir/pat3file", "attr3", EXPECT_UNDEFINED, NULL },
{ "pat3dir/pat3file", "attr3", EXPECT_TRUE, NULL },
/* pattern* match */
{ "pat4.txt", "attr4", GIT_ATTR_TRUE, 0, 0 },
{ "/fun/fun/fun/pat4.c", "attr4", GIT_ATTR_TRUE, 0, 0 },
{ "pat4.", "attr4", GIT_ATTR_TRUE, 0, 0 },
{ "pat4", "attr4", NULL, 0, 0 },
{ "/fun/fun/fun/pat4.dir", "attr4", GIT_ATTR_TRUE, 0, 1 },
{ "pat4.txt", "attr4", EXPECT_TRUE, NULL },
{ "/fun/fun/fun/pat4.c", "attr4", EXPECT_TRUE, NULL },
{ "pat4.", "attr4", EXPECT_TRUE, NULL },
{ "pat4", "attr4", EXPECT_UNDEFINED, NULL },
/* *pattern match */
{ "foo.pat5", "attr5", GIT_ATTR_TRUE, 0, 0 },
{ "foo.pat5", "attr5", GIT_ATTR_TRUE, 0, 1 },
{ "/this/is/ok.pat5", "attr5", GIT_ATTR_TRUE, 0, 0 },
{ "/this/is/bad.pat5/yousee.txt", "attr5", NULL, 0, 0 },
{ "foo.pat5", "attr100", NULL, 0, 0 },
{ "foo.pat5", "attr5", EXPECT_TRUE, NULL },
{ "/this/is/ok.pat5", "attr5", EXPECT_TRUE, NULL },
{ "/this/is/bad.pat5/yousee.txt", "attr5", EXPECT_UNDEFINED, NULL },
{ "foo.pat5", "attr100", EXPECT_UNDEFINED, NULL },
/* glob match with slashes */
{ "foo.pat6", "attr6", NULL, 0, 0 },
{ "pat6/pat6/foobar.pat6", "attr6", GIT_ATTR_TRUE, 0, 0 },
{ "pat6/pat6/.pat6", "attr6", GIT_ATTR_TRUE, 0, 0 },
{ "pat6/pat6/extra/foobar.pat6", "attr6", NULL, 0, 0 },
{ "/prefix/pat6/pat6/foobar.pat6", "attr6", NULL, 0, 0 },
{ "/pat6/pat6/foobar.pat6", "attr6", NULL, 0, 0 },
{ "foo.pat6", "attr6", EXPECT_UNDEFINED, NULL },
{ "pat6/pat6/foobar.pat6", "attr6", EXPECT_TRUE, NULL },
{ "pat6/pat6/.pat6", "attr6", EXPECT_TRUE, NULL },
{ "pat6/pat6/extra/foobar.pat6", "attr6", EXPECT_UNDEFINED, NULL },
{ "/prefix/pat6/pat6/foobar.pat6", "attr6", EXPECT_UNDEFINED, NULL },
{ "/pat6/pat6/foobar.pat6", "attr6", EXPECT_UNDEFINED, NULL },
/* complex pattern */
{ "pat7a12z", "attr7", GIT_ATTR_TRUE, 0, 0 },
{ "pat7e__x", "attr7", GIT_ATTR_TRUE, 0, 0 },
{ "pat7b/1y", "attr7", NULL, 0, 0 }, /* ? does not match / */
{ "pat7e_x", "attr7", NULL, 0, 0 },
{ "pat7aaaa", "attr7", NULL, 0, 0 },
{ "pat7zzzz", "attr7", NULL, 0, 0 },
{ "/this/can/be/anything/pat7a12z", "attr7", GIT_ATTR_TRUE, 0, 0 },
{ "but/it/still/must/match/pat7aaaa", "attr7", NULL, 0, 0 },
{ "pat7aaay.fail", "attr7", NULL, 0, 0 },
{ "pat7a12z", "attr7", EXPECT_TRUE, NULL },
{ "pat7e__x", "attr7", EXPECT_TRUE, NULL },
{ "pat7b/1y", "attr7", EXPECT_UNDEFINED, NULL }, /* ? does not match / */
{ "pat7e_x", "attr7", EXPECT_UNDEFINED, NULL },
{ "pat7aaaa", "attr7", EXPECT_UNDEFINED, NULL },
{ "pat7zzzz", "attr7", EXPECT_UNDEFINED, NULL },
{ "/this/can/be/anything/pat7a12z", "attr7", EXPECT_TRUE, NULL },
{ "but/it/still/must/match/pat7aaaa", "attr7", EXPECT_UNDEFINED, NULL },
{ "pat7aaay.fail", "attr7", EXPECT_UNDEFINED, NULL },
/* pattern with spaces */
{ "pat8 with spaces", "attr8", GIT_ATTR_TRUE, 0, 0 },
{ "/gotta love/pat8 with spaces", "attr8", GIT_ATTR_TRUE, 0, 0 },
{ "failing pat8 with spaces", "attr8", NULL, 0, 0 },
{ "spaces", "attr8", NULL, 0, 0 },
{ "pat8 with spaces", "attr8", EXPECT_TRUE, NULL },
{ "/gotta love/pat8 with spaces", "attr8", EXPECT_TRUE, NULL },
{ "failing pat8 with spaces", "attr8", EXPECT_UNDEFINED, NULL },
{ "spaces", "attr8", EXPECT_UNDEFINED, NULL },
/* pattern at eof */
{ "pat9", "attr9", GIT_ATTR_TRUE, 0, 0 },
{ "/eof/pat9", "attr9", GIT_ATTR_TRUE, 0, 0 },
{ "pat", "attr9", NULL, 0, 0 },
{ "at9", "attr9", NULL, 0, 0 },
{ "pat9.fail", "attr9", NULL, 0, 0 },
{ "pat9", "attr9", EXPECT_TRUE, NULL },
{ "/eof/pat9", "attr9", EXPECT_TRUE, NULL },
{ "pat", "attr9", EXPECT_UNDEFINED, NULL },
{ "at9", "attr9", EXPECT_UNDEFINED, NULL },
{ "pat9.fail", "attr9", EXPECT_UNDEFINED, NULL },
/* sentinel at end */
{ NULL, NULL, NULL, 0, 0 }
{ NULL, NULL, 0, NULL }
};
cl_git_pass(git_attr_file__new(&file));
......@@ -141,7 +135,8 @@ void test_attr_lookup__match_variants(void)
cl_git_pass(git_attr_path__init(&path, "/testing/for/pat0", NULL));
cl_assert_strequal("pat0", path.basename);
run_test_cases(file, cases);
run_test_cases(file, cases, 0);
run_test_cases(file, dir_cases, 1);
git_attr_file__free(file);
}
......@@ -149,54 +144,54 @@ void test_attr_lookup__match_variants(void)
void test_attr_lookup__assign_variants(void)
{
git_attr_file *file;
test_case cases[] = {
struct attr_expected cases[] = {
/* pat0 -> simple assign */
{ "pat0", "simple", GIT_ATTR_TRUE, 0, 0 },
{ "/testing/pat0", "simple", GIT_ATTR_TRUE, 0, 0 },
{ "pat0", "fail", NULL, 0, 0 },
{ "/testing/pat0", "fail", NULL, 0, 0 },
{ "pat0", "simple", EXPECT_TRUE, NULL },
{ "/testing/pat0", "simple", EXPECT_TRUE, NULL },
{ "pat0", "fail", EXPECT_UNDEFINED, NULL },
{ "/testing/pat0", "fail", EXPECT_UNDEFINED, NULL },
/* negative assign */
{ "pat1", "neg", GIT_ATTR_FALSE, 0, 0 },
{ "/testing/pat1", "neg", GIT_ATTR_FALSE, 0, 0 },
{ "pat1", "fail", NULL, 0, 0 },
{ "/testing/pat1", "fail", NULL, 0, 0 },
{ "pat1", "neg", EXPECT_FALSE, NULL },
{ "/testing/pat1", "neg", EXPECT_FALSE, NULL },
{ "pat1", "fail", EXPECT_UNDEFINED, NULL },
{ "/testing/pat1", "fail", EXPECT_UNDEFINED, NULL },
/* forced undef */
{ "pat1", "notundef", GIT_ATTR_TRUE, 0, 0 },
{ "pat2", "notundef", NULL, 0, 0 },
{ "/lead/in/pat1", "notundef", GIT_ATTR_TRUE, 0, 0 },
{ "/lead/in/pat2", "notundef", NULL, 0, 0 },
{ "pat1", "notundef", EXPECT_TRUE, NULL },
{ "pat2", "notundef", EXPECT_UNDEFINED, NULL },
{ "/lead/in/pat1", "notundef", EXPECT_TRUE, NULL },
{ "/lead/in/pat2", "notundef", EXPECT_UNDEFINED, NULL },
/* assign value */
{ "pat3", "assigned", "test-value", 1, 0 },
{ "pat3", "notassigned", NULL, 0, 0 },
{ "pat3", "assigned", EXPECT_STRING, "test-value" },
{ "pat3", "notassigned", EXPECT_UNDEFINED, NULL },
/* assign value */
{ "pat4", "rule-with-more-chars", "value-with-more-chars", 1, 0 },
{ "pat4", "notassigned-rule-with-more-chars", NULL, 0, 0 },
{ "pat4", "rule-with-more-chars", EXPECT_STRING, "value-with-more-chars" },
{ "pat4", "notassigned-rule-with-more-chars", EXPECT_UNDEFINED, NULL },
/* empty assignments */
{ "pat5", "empty", GIT_ATTR_TRUE, 0, 0 },
{ "pat6", "negempty", GIT_ATTR_FALSE, 0, 0 },
{ "pat5", "empty", EXPECT_TRUE, NULL },
{ "pat6", "negempty", EXPECT_FALSE, NULL },
/* multiple assignment */
{ "pat7", "multiple", GIT_ATTR_TRUE, 0, 0 },
{ "pat7", "single", GIT_ATTR_FALSE, 0, 0 },
{ "pat7", "values", "1", 1, 0 },
{ "pat7", "also", "a-really-long-value/*", 1, 0 },
{ "pat7", "happy", "yes!", 1, 0 },
{ "pat8", "again", GIT_ATTR_TRUE, 0, 0 },
{ "pat8", "another", "12321", 1, 0 },
{ "pat7", "multiple", EXPECT_TRUE, NULL },
{ "pat7", "single", EXPECT_FALSE, NULL },
{ "pat7", "values", EXPECT_STRING, "1" },
{ "pat7", "also", EXPECT_STRING, "a-really-long-value/*" },
{ "pat7", "happy", EXPECT_STRING, "yes!" },
{ "pat8", "again", EXPECT_TRUE, NULL },
{ "pat8", "another", EXPECT_STRING, "12321" },
/* bad assignment */
{ "patbad0", "simple", NULL, 0, 0 },
{ "patbad0", "notundef", GIT_ATTR_TRUE, 0, 0 },
{ "patbad1", "simple", NULL, 0, 0 },
{ "patbad0", "simple", EXPECT_UNDEFINED, NULL },
{ "patbad0", "notundef", EXPECT_TRUE, NULL },
{ "patbad1", "simple", EXPECT_UNDEFINED, NULL },
/* eof assignment */
{ "pat9", "at-eof", GIT_ATTR_FALSE, 0, 0 },
{ "pat9", "at-eof", EXPECT_FALSE, NULL },
/* sentinel at end */
{ NULL, NULL, NULL, 0, 0 }
{ NULL, NULL, 0, NULL }
};
cl_git_pass(git_attr_file__new(&file));
cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr2"), file));
cl_assert(file->rules.length == 11);
run_test_cases(file, cases);
run_test_cases(file, cases, 0);
git_attr_file__free(file);
}
......@@ -204,34 +199,34 @@ void test_attr_lookup__assign_variants(void)
void test_attr_lookup__check_attr_examples(void)
{
git_attr_file *file;
test_case cases[] = {
{ "foo.java", "diff", "java", 1, 0 },
{ "foo.java", "crlf", GIT_ATTR_FALSE, 0, 0 },
{ "foo.java", "myAttr", GIT_ATTR_TRUE, 0, 0 },
{ "foo.java", "other", NULL, 0, 0 },
{ "/prefix/dir/foo.java", "diff", "java", 1, 0 },
{ "/prefix/dir/foo.java", "crlf", GIT_ATTR_FALSE, 0, 0 },
{ "/prefix/dir/foo.java", "myAttr", GIT_ATTR_TRUE, 0, 0 },
{ "/prefix/dir/foo.java", "other", NULL, 0, 0 },
{ "NoMyAttr.java", "crlf", GIT_ATTR_FALSE, 0, 0 },
{ "NoMyAttr.java", "myAttr", NULL, 0, 0 },
{ "NoMyAttr.java", "other", NULL, 0, 0 },
{ "/prefix/dir/NoMyAttr.java", "crlf", GIT_ATTR_FALSE, 0, 0 },
{ "/prefix/dir/NoMyAttr.java", "myAttr", NULL, 0, 0 },
{ "/prefix/dir/NoMyAttr.java", "other", NULL, 0, 0 },
{ "README", "caveat", "unspecified", 1, 0 },
{ "/specific/path/README", "caveat", "unspecified", 1, 0 },
{ "README", "missing", NULL, 0, 0 },
{ "/specific/path/README", "missing", NULL, 0, 0 },
struct attr_expected cases[] = {
{ "foo.java", "diff", EXPECT_STRING, "java" },
{ "foo.java", "crlf", EXPECT_FALSE, NULL },
{ "foo.java", "myAttr", EXPECT_TRUE, NULL },
{ "foo.java", "other", EXPECT_UNDEFINED, NULL },
{ "/prefix/dir/foo.java", "diff", EXPECT_STRING, "java" },
{ "/prefix/dir/foo.java", "crlf", EXPECT_FALSE, NULL },
{ "/prefix/dir/foo.java", "myAttr", EXPECT_TRUE, NULL },
{ "/prefix/dir/foo.java", "other", EXPECT_UNDEFINED, NULL },
{ "NoMyAttr.java", "crlf", EXPECT_FALSE, NULL },
{ "NoMyAttr.java", "myAttr", EXPECT_UNDEFINED, NULL },
{ "NoMyAttr.java", "other", EXPECT_UNDEFINED, NULL },
{ "/prefix/dir/NoMyAttr.java", "crlf", EXPECT_FALSE, NULL },
{ "/prefix/dir/NoMyAttr.java", "myAttr", EXPECT_UNDEFINED, NULL },
{ "/prefix/dir/NoMyAttr.java", "other", EXPECT_UNDEFINED, NULL },
{ "README", "caveat", EXPECT_STRING, "unspecified" },
{ "/specific/path/README", "caveat", EXPECT_STRING, "unspecified" },
{ "README", "missing", EXPECT_UNDEFINED, NULL },
{ "/specific/path/README", "missing", EXPECT_UNDEFINED, NULL },
/* sentinel at end */
{ NULL, NULL, NULL, 0, 0 }
{ NULL, NULL, 0, NULL }
};
cl_git_pass(git_attr_file__new(&file));
cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr3"), file));
cl_assert(file->rules.length == 3);
run_test_cases(file, cases);
run_test_cases(file, cases, 0);
git_attr_file__free(file);
}
......@@ -239,24 +234,24 @@ void test_attr_lookup__check_attr_examples(void)
void test_attr_lookup__from_buffer(void)
{
git_attr_file *file;
test_case cases[] = {
{ "abc", "foo", GIT_ATTR_TRUE, 0, 0 },
{ "abc", "bar", GIT_ATTR_TRUE, 0, 0 },
{ "abc", "baz", GIT_ATTR_TRUE, 0, 0 },
{ "aaa", "foo", GIT_ATTR_TRUE, 0, 0 },
{ "aaa", "bar", NULL, 0, 0 },
{ "aaa", "baz", GIT_ATTR_TRUE, 0, 0 },
{ "qqq", "foo", NULL, 0, 0 },
{ "qqq", "bar", NULL, 0, 0 },
{ "qqq", "baz", GIT_ATTR_TRUE, 0, 0 },
{ NULL, NULL, NULL, 0, 0 }
struct attr_expected cases[] = {
{ "abc", "foo", EXPECT_TRUE, NULL },
{ "abc", "bar", EXPECT_TRUE, NULL },
{ "abc", "baz", EXPECT_TRUE, NULL },
{ "aaa", "foo", EXPECT_TRUE, NULL },
{ "aaa", "bar", EXPECT_UNDEFINED, NULL },
{ "aaa", "baz", EXPECT_TRUE, NULL },
{ "qqq", "foo", EXPECT_UNDEFINED, NULL },
{ "qqq", "bar", EXPECT_UNDEFINED, NULL },
{ "qqq", "baz", EXPECT_TRUE, NULL },
{ NULL, NULL, 0, NULL }
};
cl_git_pass(git_attr_file__new(&file));
cl_git_pass(git_attr_file__from_buffer(NULL, "a* foo\nabc bar\n* baz", file));
cl_assert(file->rules.length == 3);
run_test_cases(file, cases);
run_test_cases(file, cases, 0);
git_attr_file__free(file);
}
......@@ -3,6 +3,8 @@
#include "git2/attr.h"
#include "attr.h"
#include "attr_expect.h"
static git_repository *g_repo = NULL;
void test_attr_repo__initialize(void)
......@@ -28,67 +30,45 @@ void test_attr_repo__cleanup(void)
void test_attr_repo__get_one(void)
{
const char *value;
struct {
const char *file;
const char *attr;
const char *expected;
} test_cases[] = {
{ "root_test1", "repoattr", GIT_ATTR_TRUE },
{ "root_test1", "rootattr", GIT_ATTR_TRUE },
{ "root_test1", "missingattr", NULL },
{ "root_test1", "subattr", NULL },
{ "root_test1", "negattr", NULL },
{ "root_test2", "repoattr", GIT_ATTR_TRUE },
{ "root_test2", "rootattr", GIT_ATTR_FALSE },
{ "root_test2", "missingattr", NULL },
{ "root_test2", "multiattr", GIT_ATTR_FALSE },
{ "root_test3", "repoattr", GIT_ATTR_TRUE },
{ "root_test3", "rootattr", NULL },
{ "root_test3", "multiattr", "3" },
{ "root_test3", "multi2", NULL },
{ "sub/subdir_test1", "repoattr", GIT_ATTR_TRUE },
{ "sub/subdir_test1", "rootattr", GIT_ATTR_TRUE },
{ "sub/subdir_test1", "missingattr", NULL },
{ "sub/subdir_test1", "subattr", "yes" },
{ "sub/subdir_test1", "negattr", GIT_ATTR_FALSE },
{ "sub/subdir_test1", "another", NULL },
{ "sub/subdir_test2.txt", "repoattr", GIT_ATTR_TRUE },
{ "sub/subdir_test2.txt", "rootattr", GIT_ATTR_TRUE },
{ "sub/subdir_test2.txt", "missingattr", NULL },
{ "sub/subdir_test2.txt", "subattr", "yes" },
{ "sub/subdir_test2.txt", "negattr", GIT_ATTR_FALSE },
{ "sub/subdir_test2.txt", "another", "zero" },
{ "sub/subdir_test2.txt", "reposub", GIT_ATTR_TRUE },
{ "sub/sub/subdir.txt", "another", "one" },
{ "sub/sub/subdir.txt", "reposubsub", GIT_ATTR_TRUE },
{ "sub/sub/subdir.txt", "reposub", NULL },
{ "does-not-exist", "foo", "yes" },
{ "sub/deep/file", "deepdeep", GIT_ATTR_TRUE },
{ NULL, NULL, NULL }
}, *scan;
for (scan = test_cases; scan->file != NULL; scan++) {
git_buf b = GIT_BUF_INIT;
git_buf_printf(&b, "%s:%s == expect %s",
scan->file, scan->attr, scan->expected);
cl_must_pass_(
git_attr_get(g_repo, scan->file, scan->attr, &value) == GIT_SUCCESS,
b.ptr);
git_buf_printf(&b, ", got %s", value);
if (scan->expected == NULL ||
scan->expected == GIT_ATTR_TRUE ||
scan->expected == GIT_ATTR_FALSE)
{
cl_assert_(scan->expected == value, b.ptr);
} else {
cl_assert_strequal(scan->expected, value);
}
struct attr_expected test_cases[] = {
{ "root_test1", "repoattr", EXPECT_TRUE, NULL },
{ "root_test1", "rootattr", EXPECT_TRUE, NULL },
{ "root_test1", "missingattr", EXPECT_UNDEFINED, NULL },
{ "root_test1", "subattr", EXPECT_UNDEFINED, NULL },
{ "root_test1", "negattr", EXPECT_UNDEFINED, NULL },
{ "root_test2", "repoattr", EXPECT_TRUE, NULL },
{ "root_test2", "rootattr", EXPECT_FALSE, NULL },
{ "root_test2", "missingattr", EXPECT_UNDEFINED, NULL },
{ "root_test2", "multiattr", EXPECT_FALSE, NULL },
{ "root_test3", "repoattr", EXPECT_TRUE, NULL },
{ "root_test3", "rootattr", EXPECT_UNDEFINED, NULL },
{ "root_test3", "multiattr", EXPECT_STRING, "3" },
{ "root_test3", "multi2", EXPECT_UNDEFINED, NULL },
{ "sub/subdir_test1", "repoattr", EXPECT_TRUE, NULL },
{ "sub/subdir_test1", "rootattr", EXPECT_TRUE, NULL },
{ "sub/subdir_test1", "missingattr", EXPECT_UNDEFINED, NULL },
{ "sub/subdir_test1", "subattr", EXPECT_STRING, "yes" },
{ "sub/subdir_test1", "negattr", EXPECT_FALSE, NULL },
{ "sub/subdir_test1", "another", EXPECT_UNDEFINED, NULL },
{ "sub/subdir_test2.txt", "repoattr", EXPECT_TRUE, NULL },
{ "sub/subdir_test2.txt", "rootattr", EXPECT_TRUE, NULL },
{ "sub/subdir_test2.txt", "missingattr", EXPECT_UNDEFINED, NULL },
{ "sub/subdir_test2.txt", "subattr", EXPECT_STRING, "yes" },
{ "sub/subdir_test2.txt", "negattr", EXPECT_FALSE, NULL },
{ "sub/subdir_test2.txt", "another", EXPECT_STRING, "zero" },
{ "sub/subdir_test2.txt", "reposub", EXPECT_TRUE, NULL },
{ "sub/sub/subdir.txt", "another", EXPECT_STRING, "one" },
{ "sub/sub/subdir.txt", "reposubsub", EXPECT_TRUE, NULL },
{ "sub/sub/subdir.txt", "reposub", EXPECT_UNDEFINED, NULL },
{ "does-not-exist", "foo", EXPECT_STRING, "yes" },
{ "sub/deep/file", "deepdeep", EXPECT_TRUE, NULL },
{ NULL, NULL, 0, NULL }
}, *scan;
git_buf_free(&b);
for (scan = test_cases; scan->path != NULL; scan++) {
cl_git_pass(git_attr_get(g_repo, scan->path, scan->attr, &value));
attr_check_expected(scan->expected, scan->expected_str, value);
}
cl_git_pass(git_attr_cache__is_cached(g_repo, ".git/info/attributes"));
......@@ -103,25 +83,24 @@ void test_attr_repo__get_many(void)
cl_git_pass(git_attr_get_many(g_repo, "root_test1", 4, names, values));
cl_assert(values[0] == GIT_ATTR_TRUE);
cl_assert(values[1] == GIT_ATTR_TRUE);
cl_assert(values[2] == NULL);
cl_assert(values[3] == NULL);
cl_assert(GIT_ATTR_TRUE(values[0]));
cl_assert(GIT_ATTR_TRUE(values[1]));
cl_assert(GIT_ATTR_UNSPECIFIED(values[2]));
cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
cl_git_pass(git_attr_get_many(g_repo, "root_test2", 4, names, values));
cl_assert(values[0] == GIT_ATTR_TRUE);
cl_assert(values[1] == GIT_ATTR_FALSE);
cl_assert(values[2] == NULL);
cl_assert(values[3] == NULL);
cl_assert(GIT_ATTR_TRUE(values[0]));
cl_assert(GIT_ATTR_FALSE(values[1]));
cl_assert(GIT_ATTR_UNSPECIFIED(values[2]));
cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
cl_git_pass(git_attr_get_many(g_repo, "sub/subdir_test1", 4, names, values));
cl_assert(values[0] == GIT_ATTR_TRUE);
cl_assert(values[1] == GIT_ATTR_TRUE);
cl_assert(values[2] == NULL);
cl_assert(GIT_ATTR_TRUE(values[0]));
cl_assert(GIT_ATTR_TRUE(values[1]));
cl_assert(GIT_ATTR_UNSPECIFIED(values[2]));
cl_assert_strequal("yes", values[3]);
}
static int count_attrs(
......@@ -161,19 +140,19 @@ void test_attr_repo__manpage_example(void)
const char *value;
cl_git_pass(git_attr_get(g_repo, "sub/abc", "foo", &value));
cl_assert(value == GIT_ATTR_TRUE);
cl_assert(GIT_ATTR_TRUE(value));
cl_git_pass(git_attr_get(g_repo, "sub/abc", "bar", &value));
cl_assert(value == NULL);
cl_assert(GIT_ATTR_UNSPECIFIED(value));
cl_git_pass(git_attr_get(g_repo, "sub/abc", "baz", &value));
cl_assert(value == GIT_ATTR_FALSE);
cl_assert(GIT_ATTR_FALSE(value));
cl_git_pass(git_attr_get(g_repo, "sub/abc", "merge", &value));
cl_assert_strequal("filfre", value);
cl_git_pass(git_attr_get(g_repo, "sub/abc", "frotz", &value));
cl_assert(value == NULL);
cl_assert(GIT_ATTR_UNSPECIFIED(value));
}
void test_attr_repo__macros(void)
......@@ -185,24 +164,24 @@ void test_attr_repo__macros(void)
cl_git_pass(git_attr_get_many(g_repo, "binfile", 5, names, values));
cl_assert(values[0] == GIT_ATTR_TRUE);
cl_assert(values[1] == GIT_ATTR_TRUE);
cl_assert(values[2] == GIT_ATTR_FALSE);
cl_assert(values[3] == GIT_ATTR_FALSE);
cl_assert(values[4] == NULL);
cl_assert(GIT_ATTR_TRUE(values[0]));
cl_assert(GIT_ATTR_TRUE(values[1]));
cl_assert(GIT_ATTR_FALSE(values[2]));
cl_assert(GIT_ATTR_FALSE(values[3]));
cl_assert(GIT_ATTR_UNSPECIFIED(values[4]));
cl_git_pass(git_attr_get_many(g_repo, "macro_test", 5, names2, values));
cl_assert(values[0] == GIT_ATTR_TRUE);
cl_assert(values[1] == GIT_ATTR_TRUE);
cl_assert(values[2] == GIT_ATTR_FALSE);
cl_assert(values[3] == NULL);
cl_assert(GIT_ATTR_TRUE(values[0]));
cl_assert(GIT_ATTR_TRUE(values[1]));
cl_assert(GIT_ATTR_FALSE(values[2]));
cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
cl_assert_strequal("77", values[4]);
cl_git_pass(git_attr_get_many(g_repo, "macro_test", 3, names3, values));
cl_assert(values[0] == GIT_ATTR_TRUE);
cl_assert(values[1] == GIT_ATTR_FALSE);
cl_assert(GIT_ATTR_TRUE(values[0]));
cl_assert(GIT_ATTR_FALSE(values[1]));
cl_assert_strequal("answer", values[2]);
}
......@@ -215,9 +194,9 @@ void test_attr_repo__bad_macros(void)
cl_git_pass(git_attr_get_many(g_repo, "macro_bad", 6, names, values));
/* these three just confirm that the "mymacro" rule ran */
cl_assert(values[0] == NULL);
cl_assert(values[1] == GIT_ATTR_TRUE);
cl_assert(values[2] == GIT_ATTR_FALSE);
cl_assert(GIT_ATTR_UNSPECIFIED(values[0]));
cl_assert(GIT_ATTR_TRUE(values[1]));
cl_assert(GIT_ATTR_FALSE(values[2]));
/* file contains:
* # let's try some malicious macro defs
......@@ -241,7 +220,7 @@ void test_attr_repo__bad_macros(void)
* so summary results should be:
* -firstmacro secondmacro="hahaha" thirdmacro
*/
cl_assert(values[3] == GIT_ATTR_FALSE);
cl_assert(GIT_ATTR_FALSE(values[3]));
cl_assert_strequal("hahaha", values[4]);
cl_assert(values[5] == GIT_ATTR_TRUE);
cl_assert(GIT_ATTR_TRUE(values[5]));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment