1 /*
2  * opt-test.c -- test the option functions
3  *
4  * ====================================================================
5  *    Licensed to the Apache Software Foundation (ASF) under one
6  *    or more contributor license agreements.  See the NOTICE file
7  *    distributed with this work for additional information
8  *    regarding copyright ownership.  The ASF licenses this file
9  *    to you under the Apache License, Version 2.0 (the
10  *    "License"); you may not use this file except in compliance
11  *    with the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *    Unless required by applicable law or agreed to in writing,
16  *    software distributed under the License is distributed on an
17  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18  *    KIND, either express or implied.  See the License for the
19  *    specific language governing permissions and limitations
20  *    under the License.
21  * ====================================================================
22  */
23 
24 #include <string.h>
25 #include <apr_general.h>
26 
27 #include "../svn_test.h"
28 
29 #include "svn_opt.h"
30 
31 
32 static svn_error_t *
test_parse_peg_rev(apr_pool_t * pool)33 test_parse_peg_rev(apr_pool_t *pool)
34 {
35   apr_size_t i;
36   static struct {
37       const char *input;
38       const char *path; /* NULL means an error is expected. */
39       svn_opt_revision_t peg;
40   } const tests[] = {
41     { "foo/bar",              "foo/bar",      {svn_opt_revision_unspecified} },
42     { "foo/bar@13",           "foo/bar",      {svn_opt_revision_number, {13}} },
43     { "foo/bar@HEAD",         "foo/bar",      {svn_opt_revision_head} },
44     { "foo/bar@{1999-12-31}", "foo/bar",      {svn_opt_revision_date, {0}} },
45     { "http://a/b@27",        "http://a/b",   {svn_opt_revision_number, {27}} },
46     { "http://a/b@COMMITTED", "http://a/b",   {svn_opt_revision_committed} },
47     { "http://a/b@{1999-12-31}",    "http://a/b",{svn_opt_revision_date, {0}} },
48     { "http://a/b@%7B1999-12-31%7D","http://a/b",{svn_opt_revision_date, {0}} },
49     { "foo/bar@1:2",          NULL,           {-1} },
50     { "foo/bar@baz",          NULL,           {-1} },
51     { "foo/bar@",             "foo/bar",      {svn_opt_revision_unspecified} },
52     { "foo/@bar@",            "foo/@bar",     {svn_opt_revision_unspecified} },
53     { "foo/bar/@13",          "foo/bar/",     {svn_opt_revision_number, {13}} },
54     { "foo/bar@@13",          "foo/bar@",     {svn_opt_revision_number, {13}} },
55     { "foo/@bar@HEAD",        "foo/@bar",     {svn_opt_revision_head} },
56     { "foo@/bar",             "foo@/bar",     {svn_opt_revision_unspecified} },
57     { "foo@HEAD/bar",         "foo@HEAD/bar", {svn_opt_revision_unspecified} },
58     { "@foo/bar",             "@foo/bar",     {svn_opt_revision_unspecified} },
59     { "@foo/bar@",            "@foo/bar",     {svn_opt_revision_unspecified} },
60   };
61 
62   for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
63     {
64       const char *path;
65       svn_opt_revision_t peg;
66       svn_error_t *err;
67 
68       err = svn_opt_parse_path(&peg, &path, tests[i].input, pool);
69       if (err)
70         {
71           svn_error_clear(err);
72           if (tests[i].path)
73             {
74               return svn_error_createf
75                 (SVN_ERR_TEST_FAILED, NULL,
76                  "svn_opt_parse_path ('%s') returned an error instead of '%s'",
77                  tests[i].input, tests[i].path);
78             }
79         }
80       else
81         {
82           if ((path == NULL)
83               || (tests[i].path == NULL)
84               || (strcmp(path, tests[i].path) != 0)
85               || (peg.kind != tests[i].peg.kind)
86               || (peg.kind == svn_opt_revision_number && peg.value.number != tests[i].peg.value.number))
87             return svn_error_createf
88               (SVN_ERR_TEST_FAILED, NULL,
89                "svn_opt_parse_path ('%s') returned '%s' instead of '%s'", tests[i].input,
90                path ? path : "NULL", tests[i].path ? tests[i].path : "NULL");
91         }
92     }
93 
94   return SVN_NO_ERROR;
95 }
96 
97 static svn_error_t *
test_svn_opt_args_to_target_array2(apr_pool_t * pool)98 test_svn_opt_args_to_target_array2(apr_pool_t *pool)
99 {
100   apr_size_t i;
101   static struct {
102     const char *input;
103     const char *output; /* NULL means an error is expected. */
104   } const tests[] = {
105     { ".",                      "" },
106     { ".@BASE",                 "@BASE" },
107     { "foo///bar",              "foo/bar" },
108     { "foo///bar@13",           "foo/bar@13" },
109     { "foo///bar@HEAD",         "foo/bar@HEAD" },
110     { "foo///bar@{1999-12-31}", "foo/bar@{1999-12-31}" },
111     { "http://a//b////",        "http://a/b" },
112     { "http://a///b@27",        "http://a/b@27" },
113     { "http://a/b//@COMMITTED", "http://a/b@COMMITTED" },
114     { "foo///bar@1:2",          "foo/bar@1:2" },
115     { "foo///bar@baz",          "foo/bar@baz" },
116     { "foo///bar@",             "foo/bar@" },
117     { "foo///bar///@13",        "foo/bar@13" },
118     { "foo///bar@@13",          "foo/bar@@13" },
119     { "foo///@bar@HEAD",        "foo/@bar@HEAD" },
120     { "foo@///bar",             "foo@/bar" },
121     { "foo@HEAD///bar",         "foo@HEAD/bar" },
122   };
123 
124   for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
125     {
126       const char *input = tests[i].input;
127       const char *expected_output = tests[i].output;
128       apr_array_header_t *targets;
129       apr_getopt_t *os;
130       const int argc = 2;
131       const char *argv[3] = { 0 };
132       apr_status_t apr_err;
133       svn_error_t *err;
134 
135       argv[0] = "opt-test";
136       argv[1] = input;
137       argv[2] = NULL;
138 
139       apr_err = apr_getopt_init(&os, pool, argc, argv);
140       if (apr_err)
141         return svn_error_wrap_apr(apr_err,
142                                   "Error initializing command line arguments");
143 
144       err = svn_opt_args_to_target_array2(&targets, os, NULL, pool);
145 
146       if (expected_output)
147         {
148           const char *actual_output;
149 
150           if (err)
151             return err;
152           if (argc - 1 != targets->nelts)
153             return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
154                                      "Passed %d target(s) to "
155                                      "svn_opt_args_to_target_array2() but "
156                                      "got %d back.",
157                                      argc - 1,
158                                      targets->nelts);
159 
160           actual_output = APR_ARRAY_IDX(targets, 0, const char *);
161 
162           if (! svn_path_is_canonical(actual_output, pool))
163             return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
164                                      "Input '%s' to "
165                                      "svn_opt_args_to_target_array2() should "
166                                      "have returned a canonical path but "
167                                      "'%s' is not.",
168                                      input,
169                                      actual_output);
170 
171           if (strcmp(expected_output, actual_output) != 0)
172             return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
173                                      "Input '%s' to "
174                                      "svn_opt_args_to_target_array2() should "
175                                      "have returned '%s' but returned '%s'.",
176                                      input,
177                                      expected_output,
178                                      actual_output);
179         }
180       else
181         {
182           if (! err)
183             return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
184                                      "Unexpected success in passing '%s' "
185                                      "to svn_opt_args_to_target_array2().",
186                                      input);
187         }
188     }
189 
190   return SVN_NO_ERROR;
191 }
192 
193 
194 /* The test table.  */
195 
196 static int max_threads = 1;
197 
198 static struct svn_test_descriptor_t test_funcs[] =
199   {
200     SVN_TEST_NULL,
201     SVN_TEST_PASS2(test_parse_peg_rev,
202                    "test svn_opt_parse_path"),
203     SVN_TEST_PASS2(test_svn_opt_args_to_target_array2,
204                    "test svn_opt_args_to_target_array2"),
205     SVN_TEST_NULL
206   };
207 
208 SVN_TEST_MAIN
209