Implemented overloaded versions of Parse and TryParse functions for BigInteger.
[mono.git] / mcs / class / System.Core / Test / System.Linq.Expressions / ExpressionTest_Coalesce.cs
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:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
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
18 //
19 // Authors:
20 //              Federico Di Gregorio <fog@initd.org>
21 //              Jb Evain <jbevain@novell.com>
22
23 using System;
24 using System.Reflection;
25 using System.Linq;
26 using System.Linq.Expressions;
27 using NUnit.Framework;
28
29 namespace MonoTests.System.Linq.Expressions
30 {
31         [TestFixture]
32         public class ExpressionTest_Coalesce
33         {
34                 [Test]
35                 [ExpectedException (typeof (ArgumentNullException))]
36                 public void Arg1Null ()
37                 {
38                         Expression.Coalesce (null, Expression.Constant (1));
39                 }
40
41                 [Test]
42                 [ExpectedException (typeof (ArgumentNullException))]
43                 public void Arg2Null ()
44                 {
45                         Expression.Coalesce (Expression.Constant (1), null);
46                 }
47
48                 [Test]
49                 [ExpectedException (typeof (InvalidOperationException))]
50                 public void NonNullLeftParameter ()
51                 {
52                         // This throws because they are both doubles, which are never
53                         Expression.Coalesce (Expression.Constant (1.0), Expression.Constant (2.0));
54                 }
55
56                 [Test]
57                 [ExpectedException (typeof (ArgumentException))]
58                 public void Incompatible_Arguments ()
59                 {
60                         // The artuments are not compatible
61                         Expression.Coalesce (Expression.Parameter (typeof (int?), "a"),
62                                              Expression.Parameter (typeof (bool), "b"));
63                 }
64
65                 [Test]
66                 public void IsCoalesceStringLifted ()
67                 {
68                         var coalesce = Expression.Coalesce (
69                                 Expression.Parameter (typeof (string), "a"),
70                                 Expression.Parameter (typeof (string), "b"));
71
72                         Assert.AreEqual ("(a ?? b)", coalesce.ToString ());
73
74                         Assert.IsFalse (coalesce.IsLifted);
75                         Assert.IsFalse (coalesce.IsLiftedToNull);
76                 }
77
78                 [Test]
79                 public void IsCoalesceNullableIntLifted ()
80                 {
81                         var coalesce = Expression.Coalesce (
82                                 Expression.Parameter (typeof (int?), "a"),
83                                 Expression.Parameter (typeof (int?), "b"));
84
85                         Assert.IsFalse (coalesce.IsLifted);
86                         Assert.IsFalse (coalesce.IsLiftedToNull);
87                 }
88
89                 [Test]
90                 public void CoalesceNullableInt ()
91                 {
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 ();
96
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));
101                 }
102
103                 [Test]
104                 public void CoalesceString ()
105                 {
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 ();
110
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));
115                 }
116
117                 [Test]
118                 public void CoalesceNullableToNonNullable ()
119                 {
120                         var a = Expression.Parameter (typeof (int?), "a");
121
122                         var node = Expression.Coalesce (a, Expression.Constant (99, typeof (int)));
123
124                         Assert.AreEqual (typeof (int), node.Type);
125                         Assert.IsFalse (node.IsLifted);
126                         Assert.IsFalse (node.IsLiftedToNull);
127
128                         var coalesce = Expression.Lambda<Func<int?, int>> (node, a).Compile ();
129
130                         Assert.AreEqual (5, coalesce (5));
131                         Assert.AreEqual (99, coalesce (null));
132                 }
133
134                 [Test]
135                 [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=349822
136                 public void CoalesceUserDefinedConversion ()
137                 {
138                         var s = Expression.Parameter (typeof (string), "s");
139
140                         var coalesce = Expression.Lambda<Func<string, int>> (
141                                 Expression.Coalesce (
142                                         s,
143                                         Expression.Constant (42),
144                                         Expression.Lambda<Func<string, int>> (
145                                                 Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s)), s).Compile ();
146
147                         Assert.AreEqual (12, coalesce ("12"));
148                         Assert.AreEqual (42, coalesce (null));
149                 }
150
151                 struct Slot {
152                         int Value;
153
154                         public Slot (int v)
155                         {
156                                 Value = v;
157                         }
158
159                         public static implicit operator int (Slot s)
160                         {
161                                 return s.Value;
162                         }
163                 }
164
165                 [Test]
166                 // #12987
167                 [Category ("MobileNotWorking")]
168                 public void CoalesceNullableSlotIntoInteger ()
169                 {
170                         var s = Expression.Parameter (typeof (Slot?), "s");
171
172                         var method = typeof (Slot).GetMethod ("op_Implicit");
173
174                         var coalesce = Expression.Lambda<Func<Slot?, int>> (
175                                 Expression.Coalesce (
176                                         s,
177                                         Expression.Constant (-3),
178                                         Expression.Lambda (
179                                                 Expression.Convert (s, typeof (int), method),
180                                                 s)), s).Compile ();
181
182                         Assert.AreEqual (-3, coalesce (null));
183                         Assert.AreEqual (42, coalesce (new Slot (42)));
184                 }
185
186                 [Test]
187                 [ExpectedException (typeof (ArgumentException))]
188                 public void WrongCoalesceConversionParameterCount ()
189                 {
190                         var s = Expression.Parameter (typeof (string), "s");
191                         var p = Expression.Parameter (typeof (string), "foo");
192
193                         Expression.Coalesce (
194                                 s,
195                                 42.ToConstant (),
196                                 Expression.Lambda<Func<string, string, int>> (
197                                         Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s, p));
198
199                 }
200
201                 [Test]
202                 [ExpectedException (typeof (InvalidOperationException))]
203                 public void WrongCoalesceConversionParameterType ()
204                 {
205                         var s = Expression.Parameter (typeof (string), "s");
206                         var i = Expression.Parameter (typeof (int), "i");
207
208                         Expression.Coalesce (
209                                 s,
210                                 42.ToConstant (),
211                                 Expression.Lambda<Func<int, int>> (
212                                         i, i));
213
214                 }
215
216                 [Test]
217                 [ExpectedException (typeof (InvalidOperationException))]
218                 public void WrongCoalesceConversionReturnType ()
219                 {
220                         var s = Expression.Parameter (typeof (string), "s");
221
222                         Expression.Coalesce (
223                                 s,
224                                 42.ToConstant (),
225                                 Expression.Lambda<Func<string, string>> (
226                                         s, s));
227                 }
228
229                 [Test]
230                 [ExpectedException (typeof (ArgumentException))]
231                 public void CoalesceVoidUserDefinedConversion ()
232                 {
233                         var s = Expression.Parameter (typeof (string), "s");
234
235                         Expression.Coalesce (
236                                 s,
237                                 42.ToConstant (),
238                                 Expression.Lambda<Action<string>> (
239                                         Expression.Call (typeof (int).GetMethod ("Parse", new [] { typeof (string) }), s), s));
240                 }
241         }
242 }