diff options
Diffstat (limited to 'tests-clay/attr')
-rw-r--r-- | tests-clay/attr/file.c | 236 | ||||
-rw-r--r-- | tests-clay/attr/lookup.c | 237 | ||||
-rw-r--r-- | tests-clay/attr/repo.c | 140 |
3 files changed, 613 insertions, 0 deletions
diff --git a/tests-clay/attr/file.c b/tests-clay/attr/file.c new file mode 100644 index 000000000..0a5bff59d --- /dev/null +++ b/tests-clay/attr/file.c @@ -0,0 +1,236 @@ +#include "clay_libgit2.h" +#include "attr_file.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))) + +void test_attr_file__simple_read(void) +{ + git_attr_file *file = NULL; + + cl_git_pass(git_attr_file__from_file(&file, cl_fixture("attr/attr0"))); + cl_assert_strequal(cl_fixture("attr/attr0"), file->path); + cl_assert(file->rules.length == 1); + + git_attr_rule *rule = get_rule(0); + cl_assert(rule != NULL); + cl_assert_strequal("*", rule->match.pattern); + cl_assert(rule->match.length == 1); + cl_assert(!rule->match.negative); + cl_assert(!rule->match.directory); + cl_assert(!rule->match.fullpath); + + cl_assert(rule->assigns.length == 1); + git_attr_assignment *assign = get_assign(rule, 0); + cl_assert(assign != NULL); + cl_assert_strequal("binary", assign->name); + cl_assert(assign->name_len == 6); + cl_assert(assign->value == GIT_ATTR_TRUE); + cl_assert(!assign->is_allocated); + + git_attr_file__free(file); +} + +void test_attr_file__match_variants(void) +{ + git_attr_file *file = NULL; + git_attr_rule *rule; + git_attr_assignment *assign; + + cl_git_pass(git_attr_file__from_file(&file, cl_fixture("attr/attr1"))); + cl_assert_strequal(cl_fixture("attr/attr1"), file->path); + cl_assert(file->rules.length == 10); + + /* let's do a thorough check of this rule, then just verify + * the things that are unique for the later rules + */ + rule = get_rule(0); + cl_assert(rule); + cl_assert_strequal("pat0", rule->match.pattern); + cl_assert(rule->match.length == strlen("pat0")); + cl_assert(!rule->match.negative); + cl_assert(!rule->match.directory); + cl_assert(!rule->match.fullpath); + cl_assert(rule->assigns.length == 1); + 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->name_len == strlen("attr0")); + cl_assert(assign->value == GIT_ATTR_TRUE); + cl_assert(!assign->is_allocated); + + rule = get_rule(1); + cl_assert_strequal("pat1", rule->match.pattern); + cl_assert(rule->match.length == strlen("pat1")); + cl_assert(rule->match.negative); + + rule = get_rule(2); + cl_assert_strequal("pat2", rule->match.pattern); + cl_assert(rule->match.length == strlen("pat2")); + cl_assert(rule->match.directory); + cl_assert(!rule->match.fullpath); + + rule = get_rule(3); + cl_assert_strequal("pat3dir/pat3file", rule->match.pattern); + cl_assert(!rule->match.directory); + cl_assert(rule->match.fullpath); + + rule = get_rule(4); + cl_assert_strequal("pat4.*", rule->match.pattern); + cl_assert(!rule->match.negative); + cl_assert(!rule->match.directory); + cl_assert(!rule->match.fullpath); + + rule = get_rule(5); + cl_assert_strequal("*.pat5", rule->match.pattern); + + rule = get_rule(7); + cl_assert_strequal("pat7[a-e]??[xyz]", rule->match.pattern); + cl_assert(rule->assigns.length == 1); + assign = get_assign(rule,0); + cl_assert_strequal("attr7", assign->name); + cl_assert(assign->value == GIT_ATTR_TRUE); + + rule = get_rule(8); + cl_assert_strequal("pat8 with spaces", rule->match.pattern); + cl_assert(rule->match.length == strlen("pat8 with spaces")); + cl_assert(!rule->match.negative); + cl_assert(!rule->match.directory); + cl_assert(!rule->match.fullpath); + + rule = get_rule(9); + cl_assert_strequal("pat9", rule->match.pattern); + + git_attr_file__free(file); +} + +static void check_one_assign( + git_attr_file *file, + int rule_idx, + int assign_idx, + const char *pattern, + const char *name, + const char *value, + int is_allocated) +{ + git_attr_rule *rule = get_rule(rule_idx); + git_attr_assignment *assign = get_assign(rule, assign_idx); + + cl_assert_strequal(pattern, rule->match.pattern); + 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->name_len == strlen(name)); + cl_assert(assign->is_allocated == is_allocated); + if (is_allocated) + cl_assert_strequal(value, assign->value); + else + cl_assert(assign->value == value); +} + +void test_attr_file__assign_variants(void) +{ + git_attr_file *file = NULL; + git_attr_rule *rule; + git_attr_assignment *assign; + + cl_git_pass(git_attr_file__from_file(&file, cl_fixture("attr/attr2"))); + 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); + + rule = get_rule(8); + cl_assert_strequal("pat7", rule->match.pattern); + cl_assert(rule->assigns.length == 5); + /* assignments will be sorted by hash value, so we have to do + * lookups by search instead of by position + */ + assign = git_attr_rule__lookup_assignment(rule, "multiple"); + cl_assert(assign); + cl_assert_strequal("multiple", assign->name); + cl_assert(assign->value == GIT_ATTR_TRUE); + assign = git_attr_rule__lookup_assignment(rule, "single"); + cl_assert(assign); + cl_assert_strequal("single", assign->name); + cl_assert(assign->value == GIT_ATTR_FALSE); + assign = git_attr_rule__lookup_assignment(rule, "values"); + cl_assert(assign); + cl_assert_strequal("values", assign->name); + cl_assert_strequal("1", assign->value); + assign = git_attr_rule__lookup_assignment(rule, "also"); + cl_assert(assign); + cl_assert_strequal("also", assign->name); + cl_assert_strequal("a-really-long-value/*", assign->value); + assign = git_attr_rule__lookup_assignment(rule, "happy"); + cl_assert(assign); + cl_assert_strequal("happy", assign->name); + cl_assert_strequal("yes!", assign->value); + assign = git_attr_rule__lookup_assignment(rule, "other"); + cl_assert(!assign); + + rule = get_rule(9); + cl_assert_strequal("pat8", rule->match.pattern); + cl_assert(rule->assigns.length == 2); + assign = git_attr_rule__lookup_assignment(rule, "again"); + cl_assert(assign); + cl_assert_strequal("again", assign->name); + cl_assert(assign->value == GIT_ATTR_TRUE); + 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); + + git_attr_file__free(file); +} + +void test_attr_file__check_attr_examples(void) +{ + git_attr_file *file = NULL; + git_attr_rule *rule; + git_attr_assignment *assign; + + cl_git_pass(git_attr_file__from_file(&file, cl_fixture("attr/attr3"))); + cl_assert_strequal(cl_fixture("attr/attr3"), file->path); + cl_assert(file->rules.length == 3); + + rule = get_rule(0); + cl_assert_strequal("*.java", rule->match.pattern); + cl_assert(rule->assigns.length == 3); + assign = git_attr_rule__lookup_assignment(rule, "diff"); + cl_assert_strequal("diff", assign->name); + 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); + assign = git_attr_rule__lookup_assignment(rule, "myAttr"); + cl_assert_strequal("myAttr", assign->name); + cl_assert(GIT_ATTR_TRUE == assign->value); + assign = git_attr_rule__lookup_assignment(rule, "missing"); + cl_assert(assign == NULL); + + rule = get_rule(1); + cl_assert_strequal("NoMyAttr.java", rule->match.pattern); + cl_assert(rule->assigns.length == 1); + assign = get_assign(rule, 0); + cl_assert_strequal("myAttr", assign->name); + cl_assert(assign->value == NULL); + + rule = get_rule(2); + cl_assert_strequal("README", rule->match.pattern); + cl_assert(rule->assigns.length == 1); + assign = get_assign(rule, 0); + cl_assert_strequal("caveat", assign->name); + cl_assert_strequal("unspecified", assign->value); + + git_attr_file__free(file); +} diff --git a/tests-clay/attr/lookup.c b/tests-clay/attr/lookup.c new file mode 100644 index 000000000..870dcd343 --- /dev/null +++ b/tests-clay/attr/lookup.c @@ -0,0 +1,237 @@ +#include "clay_libgit2.h" +#include "attr.h" + +void test_attr_lookup__simple(void) +{ + git_attr_file *file = NULL; + git_attr_path path; + const char *value = NULL; + + cl_git_pass(git_attr_file__from_file(&file, cl_fixture("attr/attr0"))); + cl_assert_strequal(cl_fixture("attr/attr0"), file->path); + cl_assert(file->rules.length == 1); + + cl_git_pass(git_attr_path__init(&path, "test")); + cl_assert_strequal("test", path.path); + cl_assert_strequal("test", path.basename); + cl_assert(!path.is_dir); + + cl_git_pass(git_attr_file__lookup_one(file,&path,"binary",&value)); + cl_assert(value == GIT_ATTR_TRUE); + + cl_git_pass(git_attr_file__lookup_one(file,&path,"missing",&value)); + cl_assert(!value); + + 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) +{ + git_attr_path path; + const char *value = NULL; + test_case *c; + int error; + + for (c = cases; c->path != NULL; c++) { + /* Put this in because I was surprised that all the tests passed */ + /* fprintf(stderr, "checking '%s' attr %s == %s\n", */ + /* c->path, c->attr, c->expected); */ + + cl_git_pass(git_attr_path__init(&path, c->path)); + + if (c->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); + } +} + +void test_attr_lookup__match_variants(void) +{ + git_attr_file *file = NULL; + git_attr_path path; + test_case 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 }, + /* 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 }, + /* 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 }, + /* path match */ + { "pat3file", "attr3", NULL, 0, 0 }, + { "/pat3dir/pat3file", "attr3", NULL, 0, 0 }, + { "pat3dir/pat3file", "attr3", GIT_ATTR_TRUE, 0, 0 }, + /* 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 }, + /* *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 }, + /* 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 }, + /* 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 }, + /* 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 }, + /* 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 }, + /* sentinel at end */ + { NULL, NULL, NULL, 0, 0 } + }; + + cl_git_pass(git_attr_file__from_file(&file, cl_fixture("attr/attr1"))); + cl_assert_strequal(cl_fixture("attr/attr1"), file->path); + cl_assert(file->rules.length == 10); + + cl_git_pass(git_attr_path__init(&path, "/testing/for/pat0")); + cl_assert_strequal("pat0", path.basename); + + run_test_cases(file, cases); + + git_attr_file__free(file); +} + +void test_attr_lookup__assign_variants(void) +{ + git_attr_file *file = NULL; + test_case 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 }, + /* 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 }, + /* 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 }, + /* assign value */ + { "pat3", "assigned", "test-value", 1, 0 }, + { "pat3", "notassigned", NULL, 0, 0 }, + /* assign value */ + { "pat4", "rule-with-more-chars", "value-with-more-chars", 1, 0 }, + { "pat4", "notassigned-rule-with-more-chars", NULL, 0, 0 }, + /* empty assignments */ + { "pat5", "empty", GIT_ATTR_TRUE, 0, 0 }, + { "pat6", "negempty", GIT_ATTR_FALSE, 0, 0 }, + /* 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 }, + /* bad assignment */ + { "patbad0", "simple", NULL, 0, 0 }, + { "patbad0", "notundef", GIT_ATTR_TRUE, 0, 0 }, + { "patbad1", "simple", NULL, 0, 0 }, + /* eof assignment */ + { "pat9", "at-eof", GIT_ATTR_FALSE, 0, 0 }, + /* sentinel at end */ + { NULL, NULL, NULL, 0, 0 } + }; + + cl_git_pass(git_attr_file__from_file(&file, cl_fixture("attr/attr2"))); + cl_assert(file->rules.length == 11); + + run_test_cases(file, cases); + + git_attr_file__free(file); +} + +void test_attr_lookup__check_attr_examples(void) +{ + git_attr_file *file = NULL; + 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 }, + /* sentinel at end */ + { NULL, NULL, NULL, 0, 0 } + }; + + cl_git_pass(git_attr_file__from_file(&file, cl_fixture("attr/attr3"))); + cl_assert(file->rules.length == 3); + + run_test_cases(file, cases); + + git_attr_file__free(file); +} diff --git a/tests-clay/attr/repo.c b/tests-clay/attr/repo.c new file mode 100644 index 000000000..b6815f3ba --- /dev/null +++ b/tests-clay/attr/repo.c @@ -0,0 +1,140 @@ +#include "clay_libgit2.h" +#include "fileops.h" +#include "git2/attr.h" + +static git_repository *g_repo = NULL; + +void test_attr_repo__initialize(void) +{ + /* before each test, instantiate the attr repo from the fixtures and + * rename the .gitted to .git so it is a repo with a working dir. + */ + cl_fixture_sandbox("attr"); + cl_git_pass(p_rename("attr/.gitted", "attr/.git")); + cl_git_pass(git_repository_open(&g_repo, "attr/.git")); +} + +void test_attr_repo__cleanup(void) +{ + git_repository_free(g_repo); + g_repo = NULL; + cl_fixture_cleanup("attr"); +} + +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_test3", "repoattr", GIT_ATTR_TRUE }, + { "root_test3", "rootattr", NULL }, + { "subdir/subdir_test1", "repoattr", GIT_ATTR_TRUE }, + { "subdir/subdir_test1", "rootattr", GIT_ATTR_TRUE }, + { "subdir/subdir_test1", "missingattr", NULL }, + { "subdir/subdir_test1", "subattr", "yes" }, + { "subdir/subdir_test1", "negattr", GIT_ATTR_FALSE }, + { "subdir/subdir_test1", "another", NULL }, + { "subdir/subdir_test2.txt", "repoattr", GIT_ATTR_TRUE }, + { "subdir/subdir_test2.txt", "rootattr", GIT_ATTR_TRUE }, + { "subdir/subdir_test2.txt", "missingattr", NULL }, + { "subdir/subdir_test2.txt", "subattr", "yes" }, + { "subdir/subdir_test2.txt", "negattr", GIT_ATTR_FALSE }, + { "subdir/subdir_test2.txt", "another", "one" }, + { 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); + } + + git_buf_free(&b); + } +} + +void test_attr_repo__get_many(void) +{ + const char *names[4] = { "repoattr", "rootattr", "missingattr", "subattr" }; + const char *values[4]; + + 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_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_git_pass(git_attr_get_many(g_repo, "subdir/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_strequal("yes", values[3]); + +} + +static int count_attrs( + const char *GIT_UNUSED(name), + const char *GIT_UNUSED(value), + void *payload) +{ + GIT_UNUSED_ARG(name); + GIT_UNUSED_ARG(value); + + *((int *)payload) += 1; + + return GIT_SUCCESS; +} + +void test_attr_repo__foreach(void) +{ + int count; + + count = 0; + cl_git_pass(git_attr_foreach(g_repo, "root_test1", &count_attrs, &count)); + cl_assert(count == 2); + + count = 0; + cl_git_pass(git_attr_foreach(g_repo, "subdir/subdir_test1", + &count_attrs, &count)); + cl_assert(count == 4); /* repoattr, rootattr, subattr, negattr */ + + count = 0; + cl_git_pass(git_attr_foreach(g_repo, "subdir/subdir_test2.txt", + &count_attrs, &count)); + cl_assert(count == 5); /* repoattr, rootattr, subattr, negattr, another */ +} |