summaryrefslogtreecommitdiff
path: root/subversion/tests/libsvn_subr/path-test.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/tests/libsvn_subr/path-test.c')
-rw-r--r--subversion/tests/libsvn_subr/path-test.c235
1 files changed, 233 insertions, 2 deletions
diff --git a/subversion/tests/libsvn_subr/path-test.c b/subversion/tests/libsvn_subr/path-test.c
index f9d36ff..ec35176 100644
--- a/subversion/tests/libsvn_subr/path-test.c
+++ b/subversion/tests/libsvn_subr/path-test.c
@@ -21,6 +21,13 @@
* ====================================================================
*/
+#ifdef _MSC_VER
+#include <direct.h>
+#define getcwd _getcwd
+#else
+#include <unistd.h> /* for getcwd() */
+#endif
+
#include <stdio.h>
#include <string.h>
#include <apr_general.h>
@@ -871,7 +878,7 @@ test_path_remove_component(apr_pool_t *pool)
int i;
svn_stringbuf_t *buf;
- buf = svn_stringbuf_create("", pool);
+ buf = svn_stringbuf_create_empty(pool);
i = 0;
while (tests[i].path)
@@ -1195,7 +1202,6 @@ test_path_splitext(apr_pool_t *pool)
const char *path;
const char *path_root;
const char *path_ext;
- svn_boolean_t result;
} tests[] = {
{ "no-ext", "no-ext", "" },
{ "test-file.py", "test-file.", "py" },
@@ -1465,6 +1471,225 @@ test_path_internal_style(apr_pool_t *pool)
}
+/* The type of a function to be tested by condense_targets_tests_helper().
+ * Matches svn_path_condense_targets().
+ */
+typedef svn_error_t *(*condense_targets_func_t)
+ (const char **pcommon,
+ apr_array_header_t **pcondensed_targets,
+ const apr_array_header_t *targets,
+ svn_boolean_t remove_redundancies,
+ apr_pool_t *pool);
+
+/** Executes function CONDENSE_TARGETS twice - with and without requesting the
+ * condensed targets list - on TEST_TARGETS (comma sep. string) and compares
+ * the results with EXP_COMMON and EXP_TARGETS (comma sep. string).
+ *
+ * @note: a '%' character at the beginning of EXP_COMMON or EXP_TARGETS will
+ * be replaced by the current working directory.
+ *
+ * Returns an error if any of the comparisons fail.
+ */
+static svn_error_t *
+condense_targets_tests_helper(const char* title,
+ const char* test_targets,
+ const char* exp_common,
+ const char* exp_targets,
+ const char* func_name,
+ condense_targets_func_t condense_targets,
+ apr_pool_t *pool)
+{
+ apr_array_header_t *targets;
+ apr_array_header_t *condensed_targets;
+ const char *common_path, *common_path2, *curdir;
+ char *token, *iter;
+ const char *exp_common_abs = exp_common;
+ int i;
+ char buf[8192];
+
+ if (! getcwd(buf, sizeof(buf)))
+ return svn_error_create(SVN_ERR_BASE, NULL, "getcwd() failed");
+ curdir = svn_path_internal_style(buf, pool);
+
+ /* Create the target array */
+ targets = apr_array_make(pool, sizeof(test_targets), sizeof(const char *));
+ token = apr_strtok(apr_pstrdup(pool, test_targets), ",", &iter);
+ while (token)
+ {
+ APR_ARRAY_PUSH(targets, const char *) =
+ svn_path_internal_style(token, pool);
+ token = apr_strtok(NULL, ",", &iter);
+ };
+
+ /* Call the function */
+ SVN_ERR(condense_targets(&common_path, &condensed_targets, targets,
+ TRUE, pool));
+
+ /* Verify the common part with the expected (prefix with cwd). */
+ if (*exp_common == '%')
+ exp_common_abs = apr_pstrcat(pool, curdir, exp_common + 1, (char *)NULL);
+
+ if (strcmp(common_path, exp_common_abs) != 0)
+ {
+ return svn_error_createf
+ (SVN_ERR_TEST_FAILED, NULL,
+ "%s (test %s) returned %s instead of %s",
+ func_name, title,
+ common_path, exp_common_abs);
+ }
+
+ /* Verify the condensed targets */
+ token = apr_strtok(apr_pstrdup(pool, exp_targets), ",", &iter);
+ for (i = 0; i < condensed_targets->nelts; i++)
+ {
+ const char * target = APR_ARRAY_IDX(condensed_targets, i, const char*);
+ if (token && (*token == '%'))
+ token = apr_pstrcat(pool, curdir, token + 1, (char *)NULL);
+ if (! token ||
+ (target && (strcmp(target, token) != 0)))
+ {
+ return svn_error_createf
+ (SVN_ERR_TEST_FAILED, NULL,
+ "%s (test %s) couldn't find %s in expected targets list",
+ func_name, title,
+ target);
+ }
+ token = apr_strtok(NULL, ",", &iter);
+ }
+
+ /* Now ensure it works without the pbasename */
+ SVN_ERR(condense_targets(&common_path2, NULL, targets, TRUE, pool));
+
+ /* Verify the common part again */
+ if (strcmp(common_path, common_path2) != 0)
+ {
+ return svn_error_createf
+ (SVN_ERR_TEST_FAILED, NULL,
+ "%s (test %s): Common path without getting targets %s does not match" \
+ "common path with targets %s",
+ func_name, title,
+ common_path2, common_path);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+test_path_condense_targets(apr_pool_t *pool)
+{
+ int i;
+ struct {
+ const char* title;
+ const char* targets;
+ const char* exp_common;
+ const char* exp_targets;
+ } tests[] = {
+ { "normal use", "z/A/B,z/A,z/A/C,z/D/E,z/D/F,z/D,z/G,z/G/H,z/G/I",
+ "%/z", "A,D,G" },
+ {"identical dirs", "z/A,z/A,z/A,z/A",
+ "%/z/A", "" },
+ {"identical files", "z/A/file,z/A/file,z/A/file,z/A/file",
+ "%/z/A/file", "" },
+ {"single dir", "z/A",
+ "%/z/A", "" },
+ {"single file", "z/A/file",
+ "%/z/A/file", "" },
+ {"URLs", "http://host/A/C,http://host/A/C/D,http://host/A/B/D",
+ "http://host/A", "C,B/D" },
+ {"URLs with no common prefix",
+ "http://host1/A/C,http://host2/A/C/D,http://host3/A/B/D",
+ "", "http://host1/A/C,http://host2/A/C/D,http://host3/A/B/D" },
+ {"file URLs with no common prefix", "file:///A/C,file:///B/D",
+ "", "file:///A/C,file:///B/D" },
+ {"URLs with mixed protocols",
+ "http://host/A/C,file:///B/D,gopher://host/A",
+ "", "http://host/A/C,file:///B/D,gopher://host/A" },
+ {"mixed paths and URLs",
+ "z/A/B,z/A,http://host/A/C/D,http://host/A/C",
+ "", "%/z/A,http://host/A/C" },
+ };
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ {
+ SVN_ERR(condense_targets_tests_helper(tests[i].title,
+ tests[i].targets,
+ tests[i].exp_common,
+ tests[i].exp_targets,
+ "svn_path_condense_targets",
+ svn_path_condense_targets,
+ pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_path_is_repos_relative_url(apr_pool_t *pool)
+{
+ int i;
+ struct {
+ const char* path;
+ svn_boolean_t result;
+ } tests[] = {
+ { "^/A", TRUE },
+ { "http://host/A", FALSE },
+ { "/A/B", FALSE },
+ };
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ {
+ svn_boolean_t result = svn_path_is_repos_relative_url(tests[i].path);
+
+ if (tests[i].result != result)
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "svn_path_is_repos_relative_url(\"%s\")"
+ " returned \"%s\" expected \"%s\"",
+ tests[i].path,
+ result ? "TRUE" : "FALSE",
+ tests[i].result ? "TRUE" : "FALSE");
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_path_resolve_repos_relative_url(apr_pool_t *pool)
+{
+ int i;
+ struct {
+ const char *relative_url;
+ const char *repos_root_url;
+ const char *absolute_url;
+ } tests[] = {
+ { "^/A", "file:///Z/X", "file:///Z/X/A" },
+ { "^/A", "file:///Z/X/", "file:///Z/X//A" }, /* doesn't canonicalize */
+ { "^/A@2", "file:///Z/X", "file:///Z/X/A@2" }, /* peg rev */
+ { "^/A", "/Z/X", "/Z/X/A" }, /* doesn't verify repos_root is URL */
+ };
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ {
+ const char *result;
+
+ SVN_ERR(svn_path_resolve_repos_relative_url(&result,
+ tests[i].relative_url,
+ tests[i].repos_root_url,
+ pool));
+
+ if (strcmp(tests[i].absolute_url,result))
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "svn_path_resolve_repos_relative_url(\"%s\","
+ "\"%s\") returned \"%s\" expected \"%s\"",
+ tests[i].relative_url,
+ tests[i].repos_root_url,
+ result, tests[i].absolute_url);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
/* local define to support XFail-ing tests on Windows/Cygwin only */
#ifdef SVN_USE_DOS_PATHS
#define WINDOWS_OR_CYGWIN TRUE
@@ -1526,5 +1751,11 @@ struct svn_test_descriptor_t test_funcs[] =
"test svn_path_local_style"),
SVN_TEST_PASS2(test_path_internal_style,
"test svn_path_internal_style"),
+ SVN_TEST_PASS2(test_path_condense_targets,
+ "test svn_path_condense_targets"),
+ SVN_TEST_PASS2(test_path_is_repos_relative_url,
+ "test svn_path_is_repos_relative_url"),
+ SVN_TEST_PASS2(test_path_resolve_repos_relative_url,
+ "test svn_path_resolve_repos_relative_url"),
SVN_TEST_NULL
};