do not assert on ToString result
[mcs.git] / class / System.Core / Test / System.Linq.Expressions / ExpressionTest_Convert.cs
blob9b9d4d9e5422349c94abbe7df09a901894aad515
1 //
2 // ExpressionTest_Convert.cs
3 //
4 // Author:
5 // Jb Evain (jbevain@novell.com)
6 //
7 // (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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 using System;
30 using System.Reflection;
31 using System.Linq;
32 using System.Linq.Expressions;
33 using NUnit.Framework;
35 namespace MonoTests.System.Linq.Expressions {
37 [TestFixture]
38 public class ExpressionTest_Convert {
40 [Test]
41 [ExpectedException (typeof (ArgumentNullException))]
42 public void NullExpression ()
44 Expression.Convert (null, typeof (int));
47 [Test]
48 [ExpectedException (typeof (ArgumentNullException))]
49 public void NullType ()
51 Expression.Convert (1.ToConstant (), null);
54 [Test]
55 [ExpectedException (typeof (InvalidOperationException))]
56 public void ConvertIntToString ()
58 Expression.Convert (1.ToConstant (), typeof (string));
61 interface IFoo { }
62 class Foo : IFoo { }
63 class Bar : Foo { }
64 class Baz { }
66 interface ITzap { }
68 [Test]
69 public void ConvertBackwardAssignability ()
71 var c = Expression.Convert (
72 Expression.Constant (null, typeof (Bar)), typeof (Foo));
74 Assert.AreEqual ("Convert(null)", c.ToString ());
77 [Test]
78 public void ConvertInterfaces ()
80 var p = Expression.Parameter (typeof (IFoo), null);
82 var conv = Expression.Convert (p, typeof (ITzap));
83 Assert.AreEqual (typeof (ITzap), conv.Type);
84 #if !NET_4_0
85 Assert.AreEqual ("Convert(<param>)", conv.ToString ());
86 #endif
87 p = Expression.Parameter (typeof (ITzap), null);
88 conv = Expression.Convert (p, typeof (IFoo));
90 Assert.AreEqual (typeof (IFoo), conv.Type);
91 #if !NET_4_0
92 Assert.AreEqual ("Convert(<param>)", conv.ToString ());
93 #endif
96 [Test]
97 public void ConvertCheckedInt32ToInt64 ()
99 var c = Expression.ConvertChecked (
100 Expression.Constant (2, typeof (int)), typeof (long));
102 Assert.AreEqual (ExpressionType.ConvertChecked, c.NodeType);
103 Assert.AreEqual ("ConvertChecked(2)", c.ToString ());
106 [Test]
107 public void ConvertCheckedFallbackToConvertForNonPrimitives ()
109 var p = Expression.ConvertChecked (
110 Expression.Constant (null, typeof (object)), typeof (IFoo));
112 Assert.AreEqual (ExpressionType.Convert, p.NodeType);
115 [Test]
116 [ExpectedException (typeof (InvalidOperationException))]
117 public void ConvertBazToFoo ()
119 Expression.Convert (Expression.Parameter (typeof (Baz), ""), typeof (Foo));
122 struct EineStrukt { }
124 [Test]
125 [ExpectedException (typeof (InvalidOperationException))]
126 public void ConvertStructToFoo ()
128 Expression.Convert (Expression.Parameter (typeof (EineStrukt), ""), typeof (Foo));
131 [Test]
132 [ExpectedException (typeof (InvalidOperationException))]
133 public void ConvertInt32ToBool ()
135 Expression.Convert (Expression.Parameter (typeof (int), ""), typeof (bool));
138 [Test]
139 public void ConvertIFooToFoo ()
141 var c = Expression.Convert (Expression.Parameter (typeof (IFoo), ""), typeof (Foo));
142 Assert.AreEqual (typeof (Foo), c.Type);
143 Assert.IsFalse (c.IsLifted);
144 Assert.IsFalse (c.IsLiftedToNull);
145 Assert.IsNull (c.Method);
148 [Test]
149 public void BoxInt32 ()
151 var c = Expression.Convert (Expression.Parameter (typeof (int), ""), typeof (object));
152 Assert.AreEqual (typeof (object), c.Type);
153 Assert.IsFalse (c.IsLifted);
154 Assert.IsFalse (c.IsLiftedToNull);
155 Assert.IsNull (c.Method);
158 [Test]
159 public void UnBoxInt32 ()
161 var c = Expression.Convert (Expression.Parameter (typeof (object), ""), typeof (int));
162 Assert.AreEqual (typeof (int), c.Type);
163 Assert.IsFalse (c.IsLifted);
164 Assert.IsFalse (c.IsLiftedToNull);
165 Assert.IsNull (c.Method);
168 [Test]
169 public void ConvertInt32ToInt64 ()
171 var c = Expression.Convert (Expression.Parameter (typeof (int), ""), typeof (long));
172 Assert.AreEqual (typeof (long), c.Type);
173 Assert.IsFalse (c.IsLifted);
174 Assert.IsFalse (c.IsLiftedToNull);
175 Assert.IsNull (c.Method);
178 [Test]
179 public void ConvertInt64ToInt32 ()
181 var c = Expression.Convert (Expression.Parameter (typeof (long), ""), typeof (int));
182 Assert.AreEqual (typeof (int), c.Type);
183 Assert.IsFalse (c.IsLifted);
184 Assert.IsFalse (c.IsLiftedToNull);
185 Assert.IsNull (c.Method);
188 enum EineEnum { }
190 [Test]
191 public void ConvertEnumToInt32 ()
193 var c = Expression.Convert (Expression.Parameter (typeof (EineEnum), ""), typeof (int));
194 Assert.AreEqual (typeof (int), c.Type);
195 Assert.IsFalse (c.IsLifted);
196 Assert.IsFalse (c.IsLiftedToNull);
197 Assert.IsNull (c.Method);
200 [Test]
201 public void ConvertNullableInt32ToInt32 ()
203 var c = Expression.Convert (Expression.Parameter (typeof (int?), ""), typeof (int));
204 Assert.AreEqual (typeof (int), c.Type);
205 Assert.IsTrue (c.IsLifted);
206 Assert.IsFalse (c.IsLiftedToNull);
207 Assert.IsNull (c.Method);
210 [Test]
211 public void ConvertInt32ToNullableInt32 ()
213 var c = Expression.Convert (Expression.Parameter (typeof (int), ""), typeof (int?));
214 Assert.AreEqual (typeof (int?), c.Type);
215 Assert.IsTrue (c.IsLifted);
216 Assert.IsTrue (c.IsLiftedToNull);
217 Assert.IsNull (c.Method);
221 class Klang {
222 int i;
224 public Klang (int i)
226 this.i = i;
229 public static explicit operator int (Klang k)
231 return k.i;
235 [Test]
236 public void ConvertClassWithExplicitOp ()
238 var c = Expression.Convert (Expression.Parameter (typeof (Klang), ""), typeof (int));
239 Assert.AreEqual (typeof (int), c.Type);
240 Assert.IsFalse (c.IsLifted);
241 Assert.IsFalse (c.IsLiftedToNull);
242 Assert.IsNotNull (c.Method);
245 [Test]
246 public void CompileConvertClassWithExplicitOp ()
248 var p = Expression.Parameter (typeof (Klang), "klang");
249 var c = Expression.Lambda<Func<Klang, int>> (
250 Expression.Convert (p, typeof (int)), p).Compile ();
252 Assert.AreEqual (42, c (new Klang (42)));
255 [Test]
256 public void ConvertClassWithExplicitOpToNullableInt ()
258 var c = Expression.Convert (Expression.Parameter (typeof (Klang), ""), typeof (int?));
259 Assert.AreEqual (typeof (int?), c.Type);
260 Assert.IsTrue (c.IsLifted);
261 Assert.IsTrue (c.IsLiftedToNull);
262 Assert.IsNotNull (c.Method);
265 struct Kling {
266 int i;
268 public Kling (int i)
270 this.i = i;
273 public static implicit operator int (Kling k)
275 return k.i;
279 [Test]
280 public void ConvertStructWithImplicitOp ()
282 var c = Expression.Convert (Expression.Parameter (typeof (Kling), ""), typeof (int));
283 Assert.AreEqual (typeof (int), c.Type);
284 Assert.IsFalse (c.IsLifted);
285 Assert.IsFalse (c.IsLiftedToNull);
286 Assert.IsNotNull (c.Method);
289 [Test]
290 public void CompileConvertStructWithImplicitOp ()
292 var p = Expression.Parameter (typeof (Kling), "kling");
293 var c = Expression.Lambda<Func<Kling, int>> (
294 Expression.Convert (p, typeof (int)), p).Compile ();
296 Assert.AreEqual (42, c (new Kling (42)));
299 [Test]
300 public void ConvertStructWithImplicitOpToNullableInt ()
302 var c = Expression.Convert (Expression.Parameter (typeof (Kling), ""), typeof (int?));
303 Assert.AreEqual (typeof (int?), c.Type);
304 Assert.IsTrue (c.IsLifted);
305 Assert.IsTrue (c.IsLiftedToNull);
306 Assert.IsNotNull (c.Method);
309 [Test]
310 public void ConvertNullableStructWithImplicitOpToNullableInt ()
312 var c = Expression.Convert (Expression.Parameter (typeof (Kling?), ""), typeof (int?));
313 Assert.AreEqual (typeof (int?), c.Type);
314 Assert.IsTrue (c.IsLifted);
315 Assert.IsTrue (c.IsLiftedToNull);
316 Assert.IsNotNull (c.Method);
319 [Test]
320 public void CompiledBoxing ()
322 var b = Expression.Lambda<Func<object>> (
323 Expression.Convert (42.ToConstant (), typeof (object))).Compile ();
325 Assert.AreEqual ((object) 42, b ());
328 [Test]
329 public void CompiledUnBoxing ()
331 var p = Expression.Parameter (typeof (object), "o");
333 var u = Expression.Lambda<Func<object, int>> (
334 Expression.Convert (p, typeof (int)), p).Compile ();
336 Assert.AreEqual (42, u ((object) 42));
339 [Test]
340 public void CompiledCast ()
342 var p = Expression.Parameter (typeof (IFoo), "foo");
344 var c = Expression.Lambda<Func<IFoo, Bar>> (
345 Expression.Convert (p, typeof (Bar)), p).Compile ();
347 IFoo foo = new Bar ();
349 Bar b = c (foo);
351 Assert.AreEqual (b, foo);
354 [Test]
355 public void CompileNotNullableToNullable ()
357 var p = Expression.Parameter (typeof (int), "i");
358 var c = Expression.Lambda<Func<int, int?>> (
359 Expression.Convert (p, typeof (int?)), p).Compile ();
361 Assert.AreEqual ((int?) 0, c (0));
362 Assert.AreEqual ((int?) 42, c (42));
365 [Test]
366 public void CompileNullableToNotNullable ()
368 var p = Expression.Parameter (typeof (int?), "i");
369 var c = Expression.Lambda<Func<int?, int>> (
370 Expression.Convert (p, typeof (int)), p).Compile ();
372 Assert.AreEqual (0, c ((int?) 0));
373 Assert.AreEqual (42, c ((int?) 42));
375 Action a = () => c (null);
377 a.AssertThrows (typeof (InvalidOperationException));
380 [Test]
381 public void CompiledConvertToSameType ()
383 var k = new Klang (42);
385 var p = Expression.Parameter (typeof (Klang), "klang");
386 var c = Expression.Lambda<Func<Klang, Klang>> (
387 Expression.Convert (
388 p, typeof (Klang)),
389 p).Compile ();
391 Assert.AreEqual (k, c (k));
394 [Test]
395 public void CompiledConvertNullableToNullable ()
397 var p = Expression.Parameter (typeof (int?), "i");
398 var c = Expression.Lambda<Func<int?, short?>> (
399 Expression.Convert (p, typeof (short?)), p).Compile ();
401 Assert.AreEqual ((short?) null, c (null));
402 Assert.AreEqual ((short?) 12, c (12));
405 [Test]
406 public void CompiledNullableBoxing ()
408 var p = Expression.Parameter (typeof (int?), "i");
409 var c = Expression.Lambda<Func<int?, object>> (
410 Expression.Convert (p, typeof (object)), p).Compile ();
412 Assert.AreEqual (null, c (null));
413 Assert.AreEqual ((object) (int?) 42, c (42));
416 [Test]
417 public void CompiledNullableUnboxing ()
419 var p = Expression.Parameter (typeof (object), "o");
420 var c = Expression.Lambda<Func<object, int?>> (
421 Expression.Convert (p, typeof (int?)), p).Compile ();
423 Assert.AreEqual ((int?) null, c (null));
424 Assert.AreEqual ((int?) 42, c ((int?) 42));
427 [Test]
428 public void ChainedNullableConvert ()
430 var p = Expression.Parameter (typeof (sbyte?), "a");
432 var test = Expression.Lambda<Func<sbyte?, long?>> (
433 Expression.Convert (
434 Expression.Convert (
436 typeof (int?)),
437 typeof (long?)), p).Compile ();
439 Assert.AreEqual ((long?) 3, test ((sbyte?) 3));
440 Assert.AreEqual (null, test (null));
443 struct ImplicitToShort {
444 short value;
446 public ImplicitToShort (short v)
448 value = v;
451 public static implicit operator short (ImplicitToShort i)
453 return i.value;
457 [Test]
458 public void ConvertImplicitToShortToNullableInt ()
460 var a = Expression.Parameter (typeof (ImplicitToShort?), "a");
462 var method = typeof (ImplicitToShort).GetMethod ("op_Implicit");
464 var node = Expression.Convert (a, typeof (short), method);
465 Assert.IsTrue (node.IsLifted);
466 Assert.IsFalse (node.IsLiftedToNull);
467 Assert.AreEqual (typeof (short), node.Type);
468 Assert.AreEqual (method, node.Method);
470 var conv = Expression.Lambda<Func<ImplicitToShort?, int?>> (
471 Expression.Convert (
472 node,
473 typeof (int?)), a).Compile ();
475 Assert.AreEqual ((int?) 42, conv (new ImplicitToShort (42)));
477 Action convnull = () => Assert.AreEqual (null, conv (null));
479 convnull.AssertThrows (typeof (InvalidOperationException));
482 [Test]
483 public void NullableImplicitToShort ()
485 var i = Expression.Parameter (typeof (ImplicitToShort?), "i");
487 var method = typeof (ImplicitToShort).GetMethod ("op_Implicit");
489 var node = Expression.Convert (i, typeof (short?), method);
491 Assert.IsTrue (node.IsLifted);
492 Assert.IsTrue (node.IsLiftedToNull);
493 Assert.AreEqual (typeof (short?), node.Type);
494 Assert.AreEqual (method, node.Method);
496 var convert = Expression.Lambda<Func<ImplicitToShort?, short?>> (node, i).Compile ();
498 Assert.AreEqual ((short?) 42, convert (new ImplicitToShort (42)));
501 [Test]
502 public void ConvertLongToDecimal ()
504 var p = Expression.Parameter (typeof (long), "l");
506 var node = Expression.Convert (p, typeof (decimal));
507 Assert.IsFalse (node.IsLifted);
508 Assert.IsFalse (node.IsLiftedToNull);
509 Assert.AreEqual (typeof (decimal), node.Type);
510 Assert.IsNotNull (node.Method);
512 var convert = Expression.Lambda<Func<long, decimal>> (node, p).Compile ();
514 Assert.AreEqual (42, convert (42));
517 [Test]
518 public void ConvertNullableULongToNullableDecimal ()
520 var p = Expression.Parameter (typeof (ulong?), "l");
522 var node = Expression.Convert (p, typeof (decimal?));
523 Assert.IsTrue (node.IsLifted);
524 Assert.IsTrue (node.IsLiftedToNull);
525 Assert.AreEqual (typeof (decimal?), node.Type);
526 Assert.IsNotNull (node.Method);
528 var convert = Expression.Lambda<Func<ulong?, decimal?>> (node, p).Compile ();
530 Assert.AreEqual (42, convert (42));
531 Assert.AreEqual (null, convert (null));
534 [Test]
535 public void ConvertCheckedNullableIntToInt ()
537 var p = Expression.Parameter (typeof (int?), "i");
539 var node = Expression.ConvertChecked (p, typeof (int));
540 Assert.AreEqual (ExpressionType.ConvertChecked, node.NodeType);
541 Assert.IsTrue (node.IsLifted);
542 Assert.IsFalse (node.IsLiftedToNull);
543 Assert.AreEqual (typeof (int), node.Type);
544 Assert.IsNull (node.Method);
547 struct ImplicitToInt {
548 int Value;
550 public ImplicitToInt (int v)
552 Value = v;
555 public static implicit operator int (ImplicitToInt i)
557 return i.Value;
561 [Test]
562 public void ConvertNullableImplictToIntToNullableLong ()
564 var i = Expression.Parameter (typeof (ImplicitToInt?), "i");
566 var method = typeof (ImplicitToInt).GetMethod ("op_Implicit");
568 var node = Expression.Convert (i, typeof (int), method);
569 node = Expression.Convert (node, typeof (long?));
570 var conv = Expression.Lambda<Func<ImplicitToInt?, long?>> (node, i).Compile ();
572 Assert.AreEqual ((long?) 42, conv (new ImplicitToInt (42)));
573 Action convnull = () => Assert.AreEqual (null, conv (null));
574 convnull.AssertThrows (typeof (InvalidOperationException));
577 [Test]
578 [ExpectedException (typeof (InvalidOperationException))]
579 [Category ("NotWorking")]
580 public void ConvertNullableIntToStringWithConvertMethod ()
582 Expression.Convert (
583 Expression.Constant ((int?) 0),
584 typeof (string),
585 typeof (Convert).GetMethod ("ToString", new [] { typeof (object) }));