Merge pull request #537 from madewokherd/ccwmarshal
[mono.git] / mcs / class / System.Core / Test / System.Linq.Expressions / ExpressionTest_New.cs
1 //
2 // ExpressionTest_New.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:
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
29 using System;
30 using System.Reflection;
31 using System.Linq;
32 using System.Linq.Expressions;
33
34 using NUnit.Framework;
35
36 namespace MonoTests.System.Linq.Expressions {
37
38         [TestFixture]
39         public class ExpressionTest_New {
40
41                 [Test]
42                 [ExpectedException (typeof (ArgumentNullException))]
43                 public void NullType ()
44                 {
45                         Expression.New (null as Type);
46                 }
47
48                 [Test]
49                 [ExpectedException (typeof (ArgumentNullException))]
50                 public void NullConstructor ()
51                 {
52                         Expression.New (null as ConstructorInfo);
53                 }
54
55                 public class Foo {
56
57                         public Foo (string s)
58                         {
59                         }
60                 }
61
62                 public class Bar {
63
64                         public string Value { get; set; }
65
66                         public Bar ()
67                         {
68                         }
69                 }
70
71                 public struct Baz {
72                 }
73
74                 [Test]
75                 [ExpectedException (typeof (ArgumentException))]
76                 public void NoParameterlessConstructor ()
77                 {
78                         Expression.New (typeof (Foo));
79                 }
80
81                 [Test]
82                 [ExpectedException (typeof (ArgumentException))]
83                 public void ConstructorHasTooMuchParameters ()
84                 {
85                         Expression.New (typeof (Foo).GetConstructor (new [] { typeof (string) }));
86                 }
87
88                 [Test]
89                 [Category ("NotDotNet")]
90                 [ExpectedException (typeof (ArgumentException))]
91                 public void NewVoid ()
92                 {
93                         Expression.New (typeof (void));
94                 }
95
96                 [Test]
97                 [ExpectedException (typeof (ArgumentNullException))]
98                 public void HasNullArgument ()
99                 {
100                         Expression.New (typeof (Foo).GetConstructor (new [] { typeof (string) }), null as Expression);
101                 }
102
103                 [Test]
104                 [ExpectedException (typeof (ArgumentException))]
105                 public void HasWrongArgument ()
106                 {
107                         Expression.New (typeof (Foo).GetConstructor (new [] { typeof (string) }), Expression.Constant (12));
108                 }
109
110                 [Test]
111                 public void NewFoo ()
112                 {
113                         var n = Expression.New (typeof (Foo).GetConstructor (new [] { typeof (string) }), Expression.Constant ("foo"));
114
115                         Assert.AreEqual (ExpressionType.New, n.NodeType);
116                         Assert.AreEqual (typeof (Foo), n.Type);
117                         Assert.AreEqual (1, n.Arguments.Count);
118                         Assert.IsNull (n.Members);
119                         Assert.AreEqual ("new Foo(\"foo\")", n.ToString ());
120                 }
121
122                 [Test]
123                 public void NewBar ()
124                 {
125                         var n = Expression.New (typeof (Bar));
126
127                         Assert.IsNotNull (n.Constructor);
128                         Assert.IsNotNull (n.Arguments);
129                         Assert.IsNull (n.Members); // wrong doc
130
131                         Assert.AreEqual ("new Bar()", n.ToString ());
132
133                         n = Expression.New (typeof (Bar).GetConstructor (Type.EmptyTypes));
134
135                         Assert.AreEqual ("new Bar()", n.ToString ());
136                 }
137
138                 public class Gazonk {
139
140                         string value;
141
142                         public Gazonk (string s)
143                         {
144                                 value = s;
145                         }
146
147                         public override bool Equals (object obj)
148                         {
149                                 var o = obj as Gazonk;
150                                 if (o == null)
151                                         return false;
152
153                                 return value == o.value;
154                         }
155
156                         public override int GetHashCode ()
157                         {
158                                 return value.GetHashCode ();
159                         }
160                 }
161
162                 [Test]
163                 public void CompileNewClass ()
164                 {
165                         var p = Expression.Parameter (typeof (string), "p");
166                         var n = Expression.New (typeof (Gazonk).GetConstructor (new [] { typeof (string) }), p);
167                         var fgaz = Expression.Lambda<Func<string, Gazonk>> (n, p).Compile ();
168
169                         var g1 = new Gazonk ("foo");
170                         var g2 = new Gazonk ("bar");
171
172                         Assert.IsNotNull (g1);
173                         Assert.AreEqual (g1, fgaz ("foo"));
174                         Assert.IsNotNull (g2);
175                         Assert.AreEqual (g2, fgaz ("bar"));
176
177                         n = Expression.New (typeof (Bar));
178                         var lbar = Expression.Lambda<Func<Bar>> (n).Compile ();
179
180                         var bar = lbar ();
181
182                         Assert.IsNotNull (bar);
183                         Assert.IsNull (bar.Value);
184                 }
185
186                 public class FakeAnonymousType {
187
188                         public string Foo { get; set; }
189                         public string Bar { get; set; }
190                         public string Baz { get; set; }
191                         public int Gazonk { get; set; }
192                         public string Tzap { set {} }
193
194                         public FakeAnonymousType (string foo)
195                         {
196                                 Foo = foo;
197                         }
198
199                         public FakeAnonymousType (string foo, string bar, string baz)
200                         {
201                                 Foo = foo;
202                                 Bar = bar;
203                                 Baz = baz;
204                         }
205                 }
206
207                 [Test]
208                 public void NewFakeAnonymousType ()
209                 {
210                         var n = Expression.New (
211                                 typeof (FakeAnonymousType).GetConstructor (new [] { typeof (string), typeof (string), typeof (string) } ),
212                                 new [] { "Foo".ToConstant (), "Bar".ToConstant (), "Baz".ToConstant () },
213                                 new [] { typeof (FakeAnonymousType).GetProperty ("Foo"), typeof (FakeAnonymousType).GetProperty ("Bar"), typeof (FakeAnonymousType).GetProperty ("Baz") });
214
215                         Assert.IsNotNull (n.Constructor);
216                         Assert.IsNotNull (n.Arguments);
217                         Assert.IsNotNull (n.Members);
218                         Assert.AreEqual ("new FakeAnonymousType(Foo = \"Foo\", Bar = \"Bar\", Baz = \"Baz\")", n.ToString ());
219                 }
220
221                 [Test]
222                 [ExpectedException (typeof (ArgumentNullException))]
223                 public void NullMember ()
224                 {
225                         Expression.New (
226                                 typeof (FakeAnonymousType).GetConstructor (new [] { typeof (string) }),
227                                 new [] { "Foo".ToConstant () },
228                                 new MemberInfo [] { null });
229                 }
230
231                 [Test]
232                 [ExpectedException (typeof (ArgumentException))]
233                 public void MemberArgumentMiscount ()
234                 {
235                         Expression.New (
236                                 typeof (FakeAnonymousType).GetConstructor (new [] { typeof (string) }),
237                                 new [] { "Foo".ToConstant () },
238                                 new [] { typeof (FakeAnonymousType).GetProperty ("Foo"), typeof (FakeAnonymousType).GetProperty ("Bar") });
239                 }
240
241                 [Test]
242                 [ExpectedException (typeof (ArgumentException))]
243                 public void MemberArgumentMismatch ()
244                 {
245                         Expression.New (
246                                 typeof (FakeAnonymousType).GetConstructor (new [] { typeof (string) }),
247                                 new [] { "Foo".ToConstant () },
248                                 new [] { typeof (FakeAnonymousType).GetProperty ("Gazonk") });
249                 }
250
251                 [Test]
252                 [ExpectedException (typeof (ArgumentException))]
253                 public void MemberHasNoGetter ()
254                 {
255                         Expression.New (
256                                 typeof (FakeAnonymousType).GetConstructor (new [] { typeof (string) }),
257                                 new [] { "Foo".ToConstant () },
258                                 new [] { typeof (FakeAnonymousType).GetProperty ("Tzap") });
259                 }
260
261                 public struct EineStrukt {
262                         public int left;
263                         public int right;
264
265                         public EineStrukt (int left, int right)
266                         {
267                                 this.left = left;
268                                 this.right = right;
269                         }
270                 }
271
272                 [Test]
273                 public void CompileNewStruct ()
274                 {
275                         var create = Expression.Lambda<Func<EineStrukt>> (
276                                 Expression.New (typeof (EineStrukt))).Compile ();
277
278                         var s = create ();
279                         Assert.AreEqual (0, s.left);
280                         Assert.AreEqual (0, s.right);
281                 }
282
283                 [Test]
284                 public void CompileNewStructWithParameters ()
285                 {
286                         var pl = Expression.Parameter (typeof (int), "left");
287                         var pr = Expression.Parameter (typeof (int), "right");
288
289                         var create = Expression.Lambda<Func<int, int, EineStrukt>> (
290                                 Expression.New (typeof (EineStrukt).GetConstructor (new [] { typeof (int), typeof (int) }), pl, pr), pl, pr).Compile ();
291
292                         var s = create (42, 12);
293
294                         Assert.AreEqual (42, s.left);
295                         Assert.AreEqual (12, s.right);
296                 }
297
298                 public class EineKlass {
299
300                         public string Left { get; set; }
301                         public string Right { get; set; }
302
303                         public EineKlass ()
304                         {
305                         }
306
307                         public EineKlass (string l, string r)
308                         {
309                                 Left = l;
310                                 Right = r;
311                         }
312                 }
313
314                 [Test]
315                 public void CompileNewClassEmptyConstructor ()
316                 {
317                         var create = Expression.Lambda<Func<EineKlass>> (
318                                 Expression.New (typeof (EineKlass))).Compile ();
319
320                         var k = create ();
321                         Assert.IsNull (k.Left);
322                         Assert.IsNull (k.Right);
323                 }
324
325                 [Test]
326                 public void CompileNewClassWithParameters ()
327                 {
328                         var pl = Expression.Parameter (typeof (string), "left");
329                         var pr = Expression.Parameter (typeof (string), "right");
330
331                         var create = Expression.Lambda<Func<string, string, EineKlass>> (
332                                 Expression.New (typeof (EineKlass).GetConstructor (new [] { typeof (string), typeof (string) }), pl, pr), pl, pr).Compile ();
333
334                         var k = create ("foo", "bar");
335
336                         Assert.AreEqual ("foo", k.Left);
337                         Assert.AreEqual ("bar", k.Right);
338                 }
339         }
340 }