tree: add various tests exercising the tree parser We currently don't have any tests that directly exercise the tree parser. This is due to the fact that the parsers for raw object data has only been recently introduce with commit ca4db5f4a (object: implement function to parse raw data, 2017-10-13), and previous to that the setup simply was too cumbersome as it always required going through the ODB. Now that we have the infrastructure, add a suite of tests that directly exercise the tree parser and various edge cases.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
diff --git a/tests/object/tree/parse.c b/tests/object/tree/parse.c
new file mode 100644
index 0000000..6ac3a2d
--- /dev/null
+++ b/tests/object/tree/parse.c
@@ -0,0 +1,146 @@
+#include "clar_libgit2.h"
+#include "tree.h"
+#include "object.h"
+
+#define OID1_HEX \
+ "\xae\x90\xf1\x2e\xea\x69\x97\x29\xed\x24" \
+ "\x55\x5e\x40\xb9\xfd\x66\x9d\xa1\x2a\x12"
+#define OID1_STR "ae90f12eea699729ed24555e40b9fd669da12a12"
+
+#define OID2_HEX \
+ "\xe8\xbf\xe5\xaf\x39\x57\x9a\x7e\x48\x98" \
+ "\xbb\x23\xf3\xa7\x6a\x72\xc3\x68\xce\xe6"
+#define OID2_STR "e8bfe5af39579a7e4898bb23f3a76a72c368cee6"
+
+typedef struct {
+ const char *filename;
+ uint16_t attr;
+ const char *oid;
+} expected_entry;
+
+static void assert_tree_parses(const char *data, size_t datalen,
+ expected_entry *expected_entries, size_t expected_nentries)
+{
+ git_tree *tree;
+ size_t n;
+
+ if (!datalen)
+ datalen = strlen(data);
+ cl_git_pass(git_object__from_raw((git_object **) &tree, data, datalen, GIT_OBJ_TREE));
+
+ cl_assert_equal_i(git_tree_entrycount(tree), expected_nentries);
+
+ for (n = 0; n < expected_nentries; n++) {
+ expected_entry *expected = expected_entries + n;
+ const git_tree_entry *entry;
+ git_oid oid;
+
+ cl_git_pass(git_oid_fromstr(&oid, expected->oid));
+
+ cl_assert(entry = git_tree_entry_byname(tree, expected->filename));
+ cl_assert_equal_s(expected->filename, entry->filename);
+ cl_assert_equal_i(expected->attr, entry->attr);
+ cl_assert_equal_oid(&oid, entry->oid);
+ }
+
+ git_object_free(&tree->object);
+}
+
+static void assert_tree_fails(const char *data, size_t datalen)
+{
+ git_object *object;
+ if (!datalen)
+ datalen = strlen(data);
+ cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJ_TREE));
+}
+
+void test_object_tree_parse__single_blob_parses(void)
+{
+ expected_entry entries[] = {
+ { "foo", 0100644, OID1_STR },
+ };
+ const char data[] = "100644 foo\x00" OID1_HEX;
+
+ assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
+}
+
+void test_object_tree_parse__single_tree_parses(void)
+{
+ expected_entry entries[] = {
+ { "foo", 040000, OID1_STR },
+ };
+ const char data[] = "040000 foo\x00" OID1_HEX;
+
+ assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
+}
+
+void test_object_tree_parse__leading_filename_spaces_parse(void)
+{
+ expected_entry entries[] = {
+ { " bar", 0100644, OID1_STR },
+ };
+ const char data[] = "100644 bar\x00" OID1_HEX;
+
+ assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
+}
+
+void test_object_tree_parse__multiple_entries_parse(void)
+{
+ expected_entry entries[] = {
+ { "bar", 0100644, OID1_STR },
+ { "foo", 040000, OID2_STR },
+ };
+ const char data[] =
+ "100644 bar\x00" OID1_HEX
+ "040000 foo\x00" OID2_HEX;
+
+ assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
+}
+
+void test_object_tree_parse__invalid_mode_fails(void)
+{
+ const char data[] = "10x644 bar\x00" OID1_HEX;
+ assert_tree_fails(data, ARRAY_SIZE(data) - 1);
+}
+
+void test_object_tree_parse__missing_mode_fails(void)
+{
+ const char data[] = " bar\x00" OID1_HEX;
+ assert_tree_fails(data, ARRAY_SIZE(data) - 1);
+}
+
+void test_object_tree_parse__missing_filename_separator_fails(void)
+{
+ const char data[] = "100644bar\x00" OID1_HEX;
+ assert_tree_fails(data, ARRAY_SIZE(data) - 1);
+}
+
+void test_object_tree_parse__missing_filename_terminator_fails(void)
+{
+ const char data[] = "100644 bar" OID1_HEX;
+ assert_tree_fails(data, ARRAY_SIZE(data) - 1);
+}
+
+void test_object_tree_parse__empty_filename_fails(void)
+{
+ const char data[] = "100644 \x00" OID1_HEX;
+ assert_tree_fails(data, ARRAY_SIZE(data) - 1);
+}
+
+void test_object_tree_parse__trailing_garbage_fails(void)
+{
+ const char data[] = "100644 bar\x00" OID1_HEX "x";
+ assert_tree_fails(data, ARRAY_SIZE(data) - 1);
+}
+
+void test_object_tree_parse__leading_space_fails(void)
+{
+ const char data[] = " 100644 bar\x00" OID1_HEX;
+ assert_tree_fails(data, ARRAY_SIZE(data) - 1);
+}
+
+void test_object_tree_parse__truncated_oid_fails(void)
+{
+ const char data[] = " 100644 bar\x00" OID1_HEX;
+ assert_tree_fails(data, ARRAY_SIZE(data) - 2);
+}