Replace SIZEOF_REGISTER with sizeof(mgreg_t) for consistency with sizeof(gpointer)
[mono.git] / mcs / class / System.ServiceModel.Web / Test / System / UriTemplateTest.cs
1 //
2 // UriTemplate.cs
3 //
4 // Author:
5 //      Atsushi Enomoto  <atsushi@ximian.com>
6 //
7 // Copyright (C) 2008 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Collections.Generic;
30 using System.Collections.ObjectModel;
31 using System.Collections.Specialized;
32 using NUnit.Framework;
33
34 namespace MonoTests.System
35 {
36         [TestFixture]
37         public class UriTemplateTest
38         {
39                 [Test]
40                 [ExpectedException (typeof (ArgumentNullException))]
41                 public void ConstructorNull ()
42                 {
43                         new UriTemplate (null);
44                 }
45
46                 [Test]
47                 public void ConstructorEmpty ()
48                 {
49                         // it does not raise an error at this state.
50                         new UriTemplate (String.Empty);
51                 }
52
53                 [Test]
54                 public void ConstructorNullDictionary ()
55                 {
56                         new UriTemplate (String.Empty, null);
57                 }
58
59                 [Test]
60                 public void IgnoreTrailingSlashDefault ()
61                 {
62                         Assert.IsFalse (new UriTemplate (String.Empty).IgnoreTrailingSlash);
63                 }
64
65                 [Test]
66                 [ExpectedException (typeof (FormatException))]
67                 public void ConstructorBrokenTemplate ()
68                 {
69                         // it used to be allowed but now it isn't in 3.5 SP1.
70                         new UriTemplate ("{");
71                 }
72
73                 [Test]
74                 [ExpectedException (typeof (FormatException))]
75                 public void ConstructorBrokenTemplate2 ()
76                 {
77                         new UriTemplate ("http://localhost:8080/{foo}/{");
78                 }
79
80                 [Test]
81                 [ExpectedException (typeof (FormatException))]
82                 public void ConstructorBrokenTemplate3 ()
83                 {
84                         new UriTemplate ("http://localhost:8080/{foo}/*/baz");
85                 }
86
87                 [Test]
88                 public void ToString ()
89                 {
90                         Assert.AreEqual ("urn:foo", new UriTemplate ("urn:foo").ToString (), "#1");
91                         // It used to be allowed but now it isn't in 3.5 SP1.
92                         //Assert.AreEqual ("{", new UriTemplate ("{").ToString (), "#2");
93                 }
94
95                 [Test]
96                 public void Variables ()
97                 {
98                         var t = new UriTemplate ("urn:foo");
99                         Assert.AreEqual (0, t.PathSegmentVariableNames.Count, "#1a");
100                         Assert.AreEqual (0, t.QueryValueVariableNames.Count, "#1b");
101
102                         t = new UriTemplate ("http://localhost:8080/");
103                         Assert.AreEqual (0, t.PathSegmentVariableNames.Count, "#2a");
104                         Assert.AreEqual (0, t.QueryValueVariableNames.Count, "#2b");
105
106                         t = new UriTemplate ("http://localhost:8080/foo/");
107                         Assert.AreEqual (0, t.PathSegmentVariableNames.Count, "#3a");
108                         Assert.AreEqual (0, t.QueryValueVariableNames.Count, "#3b");
109
110                         t = new UriTemplate ("http://localhost:8080/{foo}");
111                         Assert.AreEqual (1, t.PathSegmentVariableNames.Count, "#4a");
112                         Assert.AreEqual ("FOO", t.PathSegmentVariableNames [0], "#4b");
113                         Assert.AreEqual (0, t.QueryValueVariableNames.Count, "#4c");
114
115                         // This became invalid in 3.5 SP1
116                         //t = new UriTemplate ("http://localhost:8080/{foo}/{");
117                         //Assert.AreEqual (1, t.PathSegmentVariableNames.Count, "#5a");
118                         //Assert.AreEqual ("FOO", t.PathSegmentVariableNames [0], "#5b");
119                         //Assert.AreEqual (0, t.QueryValueVariableNames.Count, "#5c");
120
121                         t = new UriTemplate ("http://localhost:8080/hoge?test={foo}&test2={bar}");
122                         Assert.AreEqual (0, t.PathSegmentVariableNames.Count, "#6a");
123                         Assert.AreEqual (2, t.QueryValueVariableNames.Count, "#6b");
124                         Assert.AreEqual ("FOO", t.QueryValueVariableNames [0], "#6c");
125                         Assert.AreEqual ("BAR", t.QueryValueVariableNames [1], "#6d");
126                 }
127
128                 [Test]
129                 [ExpectedException (typeof (ArgumentException))]
130                 public void VariablesInSameSegment ()
131                 {
132                         new UriTemplate ("http://localhost:8080/{foo}{bar}");
133                 }
134
135                 [Test]
136                 [Category ("NotDotNet")] //.NET 3.5 SP1 incorrectly matches the port part
137                 public void VariablesInNonPathQuery ()
138                 {
139                         var t = new UriTemplate ("http://localhost:{foo}/");
140                         Assert.AreEqual (0, t.PathSegmentVariableNames.Count, "#8a");
141                         Assert.AreEqual (0, t.QueryValueVariableNames.Count, "#8b");
142                 }
143
144                 [Test]
145                 [ExpectedException (typeof (InvalidOperationException))]
146                 public void DuplicateNameInTemplate ()
147                 {
148                         // one name to two places to match
149                         new UriTemplate ("http://localhost:8080/hoge?test={foo}&test2={foo}");
150                 }
151
152                 [Test]
153                 [ExpectedException (typeof (InvalidOperationException))]
154                 public void DuplicateNameInTemplate2 ()
155                 {
156                         // one name to two places to match
157                         new UriTemplate ("http://localhost:8080/hoge/{foo}?test={foo}");
158                 }
159
160                 [Test]
161                 [ExpectedException (typeof (ArgumentNullException))]
162                 public void BindByNameNullBaseAddress ()
163                 {
164                         var t = new UriTemplate ("http://localhost:8080/");
165                         t.BindByName (null, new NameValueCollection ());
166                 }
167
168                 [Test]
169                 [ExpectedException (typeof (ArgumentException))]
170                 public void BindByNameRelativeBaseAddress ()
171                 {
172                         var t = new UriTemplate ("http://localhost:8080/");
173                         t.BindByName (new Uri ("", UriKind.Relative), new NameValueCollection ());
174                 }
175
176                 [Test]
177                 [Category ("NotWorking")] // not worthy
178                 public void BindByNameFileUriBaseAddress ()
179                 {
180                         var t = new UriTemplate ("http://localhost:8080/");
181                         var u = t.BindByName (new Uri ("file:///"), new NameValueCollection ());
182                         Assert.AreEqual ("file:///http://localhost:8080/", u.ToString ());
183                 }
184
185                 [Test] // it is allowed.
186                 public void BindByNameFileExtraNames ()
187                 {
188                         var t = new UriTemplate ("http://localhost:8080/");
189                         var n = new NameValueCollection ();
190                         n.Add ("name", "value");
191                         t.BindByName (new Uri ("http://localhost/"), n);
192                 }
193
194                 [Test]
195                 [ExpectedException (typeof (ArgumentException))]
196                 public void BindByNameFileMissingName ()
197                 {
198                         var t = new UriTemplate ("/{foo}/");
199                         t.BindByName (new Uri ("http://localhost/"), new NameValueCollection ());
200                 }
201
202                 [Test]
203                 [ExpectedException (typeof (ArgumentException))]
204                 public void BindInSameSegment ()
205                 {
206                         new UriTemplate ("/hoo/{foo}{bar}");
207                 }
208
209                 [Test]
210                 public void BindByName ()
211                 {
212                         var t = new UriTemplate ("/{foo}/{bar}/");
213                         var n = new NameValueCollection ();
214                         n.Add ("Bar", "value1"); // case insensitive
215                         n.Add ("FOO", "value2"); // case insensitive
216                         var u = t.BindByName (new Uri ("http://localhost/"), n);
217                         Assert.AreEqual ("http://localhost/value2/value1/", u.ToString ());
218                 }
219
220                 [Test]
221                 public void BindByNameWithDefaults ()
222                 {
223                         var d = new Dictionary<string,string> ();
224                         d.Add ("Bar", "value1"); // case insensitive
225                         d.Add ("FOO", "value2"); // case insensitive
226                         var t = new UriTemplate ("/{foo}/{bar}/", d);
227                         var u = t.BindByName (new Uri ("http://localhost/"), new NameValueCollection ());
228                         Assert.AreEqual ("http://localhost/value2/value1/", u.ToString ());
229                 }
230
231                 [Test]
232                 [ExpectedException (typeof (ArgumentException))]
233                 public void BindByNameWithDefaults2 ()
234                 {
235                         var d = new Dictionary<string,string> ();
236                         d.Add ("Bar", "value1"); // case insensitive
237                         d.Add ("FOO", "value2"); // case insensitive
238                         var t = new UriTemplate ("/{foo}/{bar}/{baz}", d);
239                         t.BindByName (new Uri ("http://localhost/"), new NameValueCollection ()); // missing baz
240                 }
241
242                 [Test]
243                 [ExpectedException (typeof (ArgumentNullException))]
244                 public void BindByPositionNullBaseAddress ()
245                 {
246                         var t = new UriTemplate ("http://localhost:8080/");
247                         t.BindByPosition (null);
248                 }
249
250                 [Test]
251                 [ExpectedException (typeof (ArgumentException))]
252                 public void BindByPositionRelativeBaseAddress ()
253                 {
254                         var t = new UriTemplate ("http://localhost:8080/");
255                         t.BindByPosition (new Uri ("", UriKind.Relative));
256                 }
257
258                 [Test]
259                 [Category ("NotWorking")] // not worthy
260                 public void BindByPositionFileUriBaseAddress ()
261                 {
262                         var t = new UriTemplate ("http://localhost:8080/");
263                         Assert.AreEqual (new Uri ("file:///http://localhost:8080/"), t.BindByPosition (new Uri ("file:///")));
264                 }
265
266                 [Test] // it is NOT allowed (unlike BindByName)
267                 [ExpectedException (typeof (FormatException))]
268                 public void BindByPositionFileExtraValues ()
269                 {
270                         var t = new UriTemplate ("http://localhost:8080/");
271                         t.BindByPosition (new Uri ("http://localhost/"), "value");
272                 }
273
274                 [Test]
275                 [ExpectedException (typeof (FormatException))]
276                 public void BindByPositionFileMissingValues ()
277                 {
278                         var t = new UriTemplate ("/{foo}/");
279                         t.BindByPosition (new Uri ("http://localhost/"));
280                 }
281
282                 [Test]
283                 public void BindByPosition ()
284                 {
285                         var t = new UriTemplate ("/{foo}/{bar}/");
286                         var u = t.BindByPosition (new Uri ("http://localhost/"), "value1", "value2");
287                         Assert.AreEqual ("http://localhost/value1/value2/", u.ToString ());
288                 }
289
290                 [Test]
291                 [ExpectedException (typeof (FormatException))] // it does not allow default values
292                 public void BindByPositionWithDefaults ()
293                 {
294                         var d = new Dictionary<string,string> ();
295                         d ["baz"] = "value3";
296                         var t = new UriTemplate ("/{foo}/{bar}/{baz}", d);
297                         t.BindByPosition (new Uri ("http://localhost/"), "value1", "value2");
298                 }
299
300                 [Test]
301                 public void MatchNoTemplateItem ()
302                 {
303                         var t = new UriTemplate ("/hooray");
304                         var n = new NameValueCollection ();
305                         Assert.IsNotNull (t.Match (new Uri ("http://localhost/"), new Uri ("http://localhost/hooray")), "#1");
306                         Assert.IsNull (t.Match (new Uri ("http://localhost/"), new Uri ("http://localhost/foobar")), "#2");
307                         Assert.IsNull (t.Match (new Uri ("http://localhost/"), new Uri ("http://localhost/hooray/foobar")), "#3");
308                 }
309
310                 [Test]
311                 public void MatchWrongTemplate ()
312                 {
313                         var t = new UriTemplate ("/hoo{foo}");
314                         var n = new NameValueCollection ();
315                         var m = t.Match (new Uri ("http://localhost/"), new Uri ("http://localhost/hooray"));
316                         Assert.AreEqual ("ray", m.BoundVariables ["foo"], "#1");
317                         Assert.IsNull (t.Match (new Uri ("http://localhost/"), new Uri ("http://localhost/foobar")), "#2");
318                         Assert.IsNull (t.Match (new Uri ("http://localhost/"), new Uri ("http://localhost/hooray/foobar")), "#3");
319                         Assert.IsNull (t.Match (new Uri ("http://localhost/"), new Uri ("http://localhost/hoo/ray")), "#4");
320                         Assert.IsNull (t.Match (new Uri ("http://localhost/"), new Uri ("http://localhost/hoo")), "#5");
321                         // this matches (as if there were no template).
322                         Assert.IsNotNull (t.Match (new Uri ("http://localhost/"), new Uri ("http://localhost/hoo{foo}")), "#6");
323                 }
324
325                 [Test]
326                 public void Match ()
327                 {
328                         var t = new UriTemplate ("/{foo}/{bar}");
329                         var n = new NameValueCollection ();
330                         Uri baseUri = new Uri ("http://localhost/");
331                         Assert.IsNull (t.Match (baseUri, new Uri ("http://localhost/hooray")), "#1");
332                         Assert.IsNull (t.Match (baseUri, new Uri ("http://localhost/v1/v2/extra")), "#2");
333                         Assert.IsNull (t.Match (baseUri, new Uri ("http://localhost/1/2/")), "#3");
334                         UriTemplateMatch m = t.Match (baseUri, new Uri ("http://localhost/foooo/baaar"));
335                         Assert.IsNotNull (m, "#4");
336                         Assert.AreEqual ("foooo", m.BoundVariables ["foo"], "#5");
337                         Assert.AreEqual ("baaar", m.BoundVariables ["bar"], "#6");
338                 }
339
340                 [Test]
341                 public void Match2 ()
342                 {
343                         var t = new UriTemplate ("/{foo}/{bar}?p1={baz}");
344                         var n = new NameValueCollection ();
345                         Uri baseUri = new Uri ("http://localhost/");
346                         Assert.IsNotNull (t.Match (baseUri, new Uri ("http://localhost/X/Y")), "#1");
347                         UriTemplateMatch m = t.Match (baseUri, new Uri ("http://localhost/X/Y?p2=v&p1=vv"));
348                         Assert.IsNotNull (m, "#2");
349                         // QueryParameters must contain non-template query parameters.
350                         Assert.AreEqual (2, m.QueryParameters.Count, "#3");
351                         Assert.AreEqual ("v", m.QueryParameters ["p2"], "#4");
352                         Assert.AreEqual ("vv", m.QueryParameters ["p1"], "#5");
353                 }
354
355                 [Test]
356                 public void MatchWildcard ()
357                 {
358                         var t = new UriTemplate ("/hoge/*?p1={foo}");
359                         var m = t.Match (new Uri ("http://localhost"), new Uri ("http://localhost/hoge/ppp/qqq?p1=v1"));
360                         Assert.IsNotNull (m, "#0");
361                         Assert.IsNotNull (m.QueryParameters, "#1.0");
362                         Assert.AreEqual ("v1", m.QueryParameters ["p1"], "#1");
363                         Assert.IsNotNull (m.WildcardPathSegments, "#2.0");
364                         Assert.AreEqual (2, m.WildcardPathSegments.Count, "#2");
365                         Assert.AreEqual ("ppp", m.WildcardPathSegments [0], "#3");
366                         Assert.AreEqual ("qqq", m.WildcardPathSegments [1], "#4");
367                 }
368
369                 [Test]
370                 public void IgnoreTrailingSlash ()
371                 {
372                         var t = new UriTemplate ("/{foo}/{bar}", true);
373                         var n = new NameValueCollection ();
374                         Uri baseUri = new Uri ("http://localhost/");
375                         Assert.IsNotNull (t.Match (baseUri, new Uri ("http://localhost/v1/v2/")), "#1");
376
377                         t = new UriTemplate ("/{foo}/{bar}", false);
378                         Assert.IsNull (t.Match (baseUri, new Uri ("http://localhost/v1/v2/")), "#2");
379                 }
380
381                 [Test]
382                 public void SimpleWebGet () {
383                         UriTemplate t = new UriTemplate ("GetBlog");
384                         Assert.IsNotNull(t.Match(new Uri("http://localhost:8000/BlogService"),
385                                 new Uri("http://localhost:8000/BlogService/GetBlog")), "Matches simple WebGet method");
386                         Assert.IsNull(t.Match (new Uri ("http://localhost:8000/BlogService"),
387                                 new Uri ("http://localhost:8000/BlogService/GetData")), "Doesn't match wrong WebGet method");
388                 }
389
390                 [Test]
391                 [ExpectedException (typeof (ArgumentException))]
392                 public void DictContainsNullValue ()
393                 {
394                         var t = new UriTemplate ("/id-{foo}/{bar}");
395                         var dic = new Dictionary<string,string> ();
396                         dic ["foo"] = null;
397                         dic ["bar"] = "bbb";
398                         t.BindByName (new Uri ("http://localhost:8080"), dic);
399                 }
400
401                 [Test]
402                 public void DictContainsCaseInsensitiveKey ()
403                 {
404                         var t = new UriTemplate ("/id-{foo}/{bar}");
405                         var dic = new Dictionary<string,string> ();
406                         dic ["foo"] = "aaa";
407                         dic ["Bar"] = "bbb";
408                         var uri = t.BindByName (new Uri ("http://localhost:8080"), dic);
409                         Assert.AreEqual ("http://localhost:8080/id-aaa/bbb", uri.ToString ());
410                 }
411
412         }
413 }