mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 15:00:04 +00:00

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.
228 lines
7.6 KiB
C
228 lines
7.6 KiB
C
#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)))
|
|
|
|
void test_attr_file__simple_read(void)
|
|
{
|
|
git_attr_file *file;
|
|
git_attr_assignment *assign;
|
|
git_attr_rule *rule;
|
|
|
|
cl_git_pass(git_attr_file__new(&file));
|
|
cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr0"), file));
|
|
cl_assert_strequal(cl_fixture("attr/attr0"), file->path);
|
|
cl_assert(file->rules.length == 1);
|
|
|
|
rule = get_rule(0);
|
|
cl_assert(rule != NULL);
|
|
cl_assert_strequal("*", rule->match.pattern);
|
|
cl_assert(rule->match.length == 1);
|
|
cl_assert(rule->match.flags == 0);
|
|
|
|
cl_assert(rule->assigns.length == 1);
|
|
assign = get_assign(rule, 0);
|
|
cl_assert(assign != NULL);
|
|
cl_assert_strequal("binary", assign->name);
|
|
cl_assert(GIT_ATTR_TRUE(assign->value));
|
|
cl_assert(!assign->is_allocated);
|
|
|
|
git_attr_file__free(file);
|
|
}
|
|
|
|
void test_attr_file__match_variants(void)
|
|
{
|
|
git_attr_file *file;
|
|
git_attr_rule *rule;
|
|
git_attr_assignment *assign;
|
|
|
|
cl_git_pass(git_attr_file__new(&file));
|
|
cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr1"), file));
|
|
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.flags == 0);
|
|
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(GIT_ATTR_TRUE(assign->value));
|
|
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.flags == GIT_ATTR_FNMATCH_NEGATIVE);
|
|
|
|
rule = get_rule(2);
|
|
cl_assert_strequal("pat2", rule->match.pattern);
|
|
cl_assert(rule->match.length == strlen("pat2"));
|
|
cl_assert(rule->match.flags == GIT_ATTR_FNMATCH_DIRECTORY);
|
|
|
|
rule = get_rule(3);
|
|
cl_assert_strequal("pat3dir/pat3file", rule->match.pattern);
|
|
cl_assert(rule->match.flags == GIT_ATTR_FNMATCH_FULLPATH);
|
|
|
|
rule = get_rule(4);
|
|
cl_assert_strequal("pat4.*", rule->match.pattern);
|
|
cl_assert(rule->match.flags == 0);
|
|
|
|
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(GIT_ATTR_TRUE(assign->value));
|
|
|
|
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.flags == 0);
|
|
|
|
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,
|
|
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);
|
|
|
|
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));
|
|
|
|
attr_check_expected(expected, expected_str, assign->value);
|
|
}
|
|
|
|
void test_attr_file__assign_variants(void)
|
|
{
|
|
git_attr_file *file;
|
|
git_attr_rule *rule;
|
|
git_attr_assignment *assign;
|
|
|
|
cl_git_pass(git_attr_file__new(&file));
|
|
cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr2"), file));
|
|
cl_assert_strequal(cl_fixture("attr/attr2"), file->path);
|
|
cl_assert(file->rules.length == 11);
|
|
|
|
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);
|
|
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(GIT_ATTR_TRUE(assign->value));
|
|
assign = git_attr_rule__lookup_assignment(rule, "single");
|
|
cl_assert(assign);
|
|
cl_assert_strequal("single", assign->name);
|
|
cl_assert(GIT_ATTR_FALSE(assign->value));
|
|
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(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", EXPECT_FALSE, NULL);
|
|
|
|
git_attr_file__free(file);
|
|
}
|
|
|
|
void test_attr_file__check_attr_examples(void)
|
|
{
|
|
git_attr_file *file;
|
|
git_attr_rule *rule;
|
|
git_attr_assignment *assign;
|
|
|
|
cl_git_pass(git_attr_file__new(&file));
|
|
cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr3"), file));
|
|
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);
|
|
}
|