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 public void CoalesceNullableInt ()
92 var a = Expression.Parameter (typeof (int?), "a");
93 var b = Expression.Parameter (typeof (int?), "b");
94 var coalesce = Expression.Lambda<Func<int?, int?, int?>> (
95 Expression.Coalesce (a, b), a, b).Compile ();
97 Assert.AreEqual ((int?) 1, coalesce (1, 2));
98 Assert.AreEqual ((int?) null, coalesce (null, null));
99 Assert.AreEqual ((int?) 2, coalesce (null, 2));
100 Assert.AreEqual ((int?) 2, coalesce (2, null));
104 public void CoalesceString ()
106 var a = Expression.Parameter (typeof (string), "a");
107 var b = Expression.Parameter (typeof (string), "b");
108 var coalesce = Expression.Lambda<Func<string, string, string>> (
109 Expression.Coalesce (a, b), a, b).Compile ();
111 Assert.AreEqual ("foo", coalesce ("foo", "bar"));
112 Assert.AreEqual (null, coalesce (null, null));
113 Assert.AreEqual ("bar", coalesce (null, "bar"));
114 Assert.AreEqual ("foo", coalesce ("foo", null));
118 public void CoalesceNullableToNonNullable ()
120 var a = Expression.Parameter (typeof (int?), "a");
122 var node = Expression.Coalesce (a, Expression.Constant (99, typeof (int)));
124 Assert.AreEqual (typeof (int), node.Type);
125 Assert.IsFalse (node.IsLifted);
126 Assert.IsFalse (node.IsLiftedToNull);
128 var coalesce = Expression.Lambda<Func<int?, int>> (node, a).Compile ();
130 Assert.AreEqual (5, coalesce (5));
131 Assert.AreEqual (99, coalesce (null));
135 [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=349822
136 public void CoalesceUserDefinedConversion ()
138 var s = Expression.Parameter (typeof (string), "s");
140 var coalesce = Expression.Lambda<Func<string, int>> (
141 Expression.Coalesce (
143 Expression.Constant (42),
144 Expression.Lambda<Func<string, int>> (
145 Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s)), s).Compile ();
147 Assert.AreEqual (12, coalesce ("12"));
148 Assert.AreEqual (42, coalesce (null));
159 public static implicit operator int (Slot s)
167 [Category ("MobileNotWorking")]
168 public void CoalesceNullableSlotIntoInteger ()
170 var s = Expression.Parameter (typeof (Slot?), "s");
172 var method = typeof (Slot).GetMethod ("op_Implicit");
174 var coalesce = Expression.Lambda<Func<Slot?, int>> (
175 Expression.Coalesce (
177 Expression.Constant (-3),
179 Expression.Convert (s, typeof (int), method),
182 Assert.AreEqual (-3, coalesce (null));
183 Assert.AreEqual (42, coalesce (new Slot (42)));
187 [ExpectedException (typeof (ArgumentException))]
188 public void WrongCoalesceConversionParameterCount ()
190 var s = Expression.Parameter (typeof (string), "s");
191 var p = Expression.Parameter (typeof (string), "foo");
193 Expression.Coalesce (
196 Expression.Lambda<Func<string, string, int>> (
197 Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s, p));
202 [ExpectedException (typeof (InvalidOperationException))]
203 public void WrongCoalesceConversionParameterType ()
205 var s = Expression.Parameter (typeof (string), "s");
206 var i = Expression.Parameter (typeof (int), "i");
208 Expression.Coalesce (
211 Expression.Lambda<Func<int, int>> (
217 [ExpectedException (typeof (InvalidOperationException))]
218 public void WrongCoalesceConversionReturnType ()
220 var s = Expression.Parameter (typeof (string), "s");
222 Expression.Coalesce (
225 Expression.Lambda<Func<string, string>> (
230 [ExpectedException (typeof (ArgumentException))]
231 public void CoalesceVoidUserDefinedConversion ()
233 var s = Expression.Parameter (typeof (string), "s");
235 Expression.Coalesce (
238 Expression.Lambda<Action<string>> (
239 Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s));