1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // Federico Di Gregorio <fog@initd.org>
21 // Jb Evain <jbevain@novell.com>
24 using System.Reflection;
26 using System.Linq.Expressions;
27 using NUnit.Framework;
29 namespace MonoTests.System.Linq.Expressions
32 public class ExpressionTest_Coalesce
35 [ExpectedException (typeof (ArgumentNullException))]
36 public void Arg1Null ()
38 Expression.Coalesce (null, Expression.Constant (1));
42 [ExpectedException (typeof (ArgumentNullException))]
43 public void Arg2Null ()
45 Expression.Coalesce (Expression.Constant (1), null);
49 [ExpectedException (typeof (InvalidOperationException))]
50 public void NonNullLeftParameter ()
52 // This throws because they are both doubles, which are never
53 Expression.Coalesce (Expression.Constant (1.0), Expression.Constant (2.0));
57 [ExpectedException (typeof (ArgumentException))]
58 public void Incompatible_Arguments ()
60 // The artuments are not compatible
61 Expression.Coalesce (Expression.Parameter (typeof (int?), "a"),
62 Expression.Parameter (typeof (bool), "b"));
66 public void IsCoalesceStringLifted ()
68 var coalesce = Expression.Coalesce (
69 Expression.Parameter (typeof (string), "a"),
70 Expression.Parameter (typeof (string), "b"));
72 Assert.AreEqual ("(a ?? b)", coalesce.ToString ());
74 Assert.IsFalse (coalesce.IsLifted);
75 Assert.IsFalse (coalesce.IsLiftedToNull);
79 public void IsCoalesceNullableIntLifted ()
81 var coalesce = Expression.Coalesce (
82 Expression.Parameter (typeof (int?), "a"),
83 Expression.Parameter (typeof (int?), "b"));
85 Assert.IsFalse (coalesce.IsLifted);
86 Assert.IsFalse (coalesce.IsLiftedToNull);
90 [Category ("NotWorkingInterpreter")]
91 public void CoalesceNullableInt ()
93 var a = Expression.Parameter (typeof (int?), "a");
94 var b = Expression.Parameter (typeof (int?), "b");
95 var coalesce = Expression.Lambda<Func<int?, int?, int?>> (
96 Expression.Coalesce (a, b), a, b).Compile ();
98 Assert.AreEqual ((int?) 1, coalesce (1, 2));
99 Assert.AreEqual ((int?) null, coalesce (null, null));
100 Assert.AreEqual ((int?) 2, coalesce (null, 2));
101 Assert.AreEqual ((int?) 2, coalesce (2, null));
105 public void CoalesceString ()
107 var a = Expression.Parameter (typeof (string), "a");
108 var b = Expression.Parameter (typeof (string), "b");
109 var coalesce = Expression.Lambda<Func<string, string, string>> (
110 Expression.Coalesce (a, b), a, b).Compile ();
112 Assert.AreEqual ("foo", coalesce ("foo", "bar"));
113 Assert.AreEqual (null, coalesce (null, null));
114 Assert.AreEqual ("bar", coalesce (null, "bar"));
115 Assert.AreEqual ("foo", coalesce ("foo", null));
119 [Category ("NotWorkingInterpreter")]
120 public void CoalesceNullableToNonNullable ()
122 var a = Expression.Parameter (typeof (int?), "a");
124 var node = Expression.Coalesce (a, Expression.Constant (99, typeof (int)));
126 Assert.AreEqual (typeof (int), node.Type);
127 Assert.IsFalse (node.IsLifted);
128 Assert.IsFalse (node.IsLiftedToNull);
130 var coalesce = Expression.Lambda<Func<int?, int>> (node, a).Compile ();
132 Assert.AreEqual (5, coalesce (5));
133 Assert.AreEqual (99, coalesce (null));
137 [Category ("NotWorkingInterpreter")]
138 [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=349822
139 public void CoalesceUserDefinedConversion ()
141 var s = Expression.Parameter (typeof (string), "s");
143 var coalesce = Expression.Lambda<Func<string, int>> (
144 Expression.Coalesce (
146 Expression.Constant (42),
147 Expression.Lambda<Func<string, int>> (
148 Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s)), s).Compile ();
150 Assert.AreEqual (12, coalesce ("12"));
151 Assert.AreEqual (42, coalesce (null));
162 public static implicit operator int (Slot s)
170 [Category ("MobileNotWorking")]
171 [Category ("NotWorkingInterpreter")]
172 public void CoalesceNullableSlotIntoInteger ()
174 var s = Expression.Parameter (typeof (Slot?), "s");
176 var method = typeof (Slot).GetMethod ("op_Implicit");
178 var coalesce = Expression.Lambda<Func<Slot?, int>> (
179 Expression.Coalesce (
181 Expression.Constant (-3),
183 Expression.Convert (s, typeof (int), method),
186 Assert.AreEqual (-3, coalesce (null));
187 Assert.AreEqual (42, coalesce (new Slot (42)));
191 [ExpectedException (typeof (ArgumentException))]
192 public void WrongCoalesceConversionParameterCount ()
194 var s = Expression.Parameter (typeof (string), "s");
195 var p = Expression.Parameter (typeof (string), "foo");
197 Expression.Coalesce (
200 Expression.Lambda<Func<string, string, int>> (
201 Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s, p));
206 [ExpectedException (typeof (InvalidOperationException))]
207 public void WrongCoalesceConversionParameterType ()
209 var s = Expression.Parameter (typeof (string), "s");
210 var i = Expression.Parameter (typeof (int), "i");
212 Expression.Coalesce (
215 Expression.Lambda<Func<int, int>> (
221 [ExpectedException (typeof (InvalidOperationException))]
222 public void WrongCoalesceConversionReturnType ()
224 var s = Expression.Parameter (typeof (string), "s");
226 Expression.Coalesce (
229 Expression.Lambda<Func<string, string>> (
234 [ExpectedException (typeof (ArgumentException))]
235 public void CoalesceVoidUserDefinedConversion ()
237 var s = Expression.Parameter (typeof (string), "s");
239 Expression.Coalesce (
242 Expression.Lambda<Action<string>> (
243 Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s));