// Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // // Authors: // Federico Di Gregorio using System; using System.Reflection; using System.Linq; using System.Linq.Expressions; using NUnit.Framework; namespace MonoTests.System.Linq.Expressions { [TestFixture] public class ExpressionTest_Property { [Test] [ExpectedException (typeof (ArgumentNullException))] public void Arg1Null () { Expression.Property (null, "NoProperty"); } [Test] [ExpectedException (typeof (ArgumentNullException))] public void Arg2Null1 () { Expression.Property (Expression.Constant (new MemberClass()), (string)null); } [Test] [ExpectedException (typeof (ArgumentNullException))] public void Arg2Null2 () { Expression.Property (Expression.Constant (new MemberClass()), (PropertyInfo)null); } [Test] [ExpectedException (typeof (ArgumentNullException))] public void Arg2Null3 () { Expression.Property (Expression.Constant (new MemberClass()), (MethodInfo)null); } [Test] [ExpectedException (typeof (ArgumentException))] public void NoProperty () { Expression.Property (Expression.Constant (new MemberClass()), "NoProperty"); } [Test] public void InstanceProperty1 () { MemberExpression expr = Expression.Property (Expression.Constant (new MemberClass()), "TestProperty1"); Assert.AreEqual (ExpressionType.MemberAccess, expr.NodeType, "Property#01"); Assert.AreEqual (typeof (int), expr.Type, "Property#02"); Assert.AreEqual ("value(MonoTests.System.Linq.Expressions.MemberClass).TestProperty1", expr.ToString(), "Property#03"); } [Test] public void InstanceProperty2 () { MemberExpression expr = Expression.Property (Expression.Constant (new MemberClass()), MemberClass.GetRoPropertyInfo()); Assert.AreEqual (ExpressionType.MemberAccess, expr.NodeType, "Property#04"); Assert.AreEqual (typeof (int), expr.Type, "Property#05"); Assert.AreEqual ("value(MonoTests.System.Linq.Expressions.MemberClass).TestProperty1", expr.ToString(), "Property#06"); } [Test] public void InstanceProperty3 () { MethodInfo mi = typeof(MemberClass).GetMethod("get_TestProperty1"); MemberExpression expr = Expression.Property (Expression.Constant (new MemberClass()), mi); Assert.AreEqual (ExpressionType.MemberAccess, expr.NodeType, "Property#07"); Assert.AreEqual (typeof (int), expr.Type, "Property#08"); Assert.AreEqual ("value(MonoTests.System.Linq.Expressions.MemberClass).TestProperty1", expr.ToString(), "Property#09"); Assert.AreEqual (MemberClass.GetRoPropertyInfo(), expr.Member, "Property#10"); } [Test] [ExpectedException (typeof (ArgumentException))] public void StaticProperty1 () { // This will fail because access to a static field should be created using a PropertyInfo and // not an instance plus the field name. Expression.Property (Expression.Constant (new MemberClass()), "StaticProperty"); } [Test] public void StaticProperty2 () { MemberExpression expr = Expression.Property (null, MemberClass.GetStaticPropertyInfo()); Assert.AreEqual (ExpressionType.MemberAccess, expr.NodeType, "Property#11"); Assert.AreEqual (typeof (int), expr.Type, "Property#12"); Assert.AreEqual ("MemberClass.StaticProperty", expr.ToString(), "Property#13"); } [Test] public void StaticProperty3 () { MethodInfo mi = typeof(MemberClass).GetMethod("get_StaticProperty"); MemberExpression expr = Expression.Property (null, mi); Assert.AreEqual (ExpressionType.MemberAccess, expr.NodeType, "Property#14"); Assert.AreEqual (typeof (int), expr.Type, "Property#15"); Assert.AreEqual ("MemberClass.StaticProperty", expr.ToString(), "Property#16"); Assert.AreEqual (MemberClass.GetStaticPropertyInfo(), expr.Member, "Property#17"); } public class Foo { public string Prop { get; set; } public static string StatProp { get { return "StaticFoo"; } } } [Test] public void TestCompileGetInstanceProperty () { var p = Expression.Parameter (typeof (Foo), "foo"); var fooer = Expression.Lambda> ( Expression.Property (p, typeof (Foo).GetProperty ("Prop")), p).Compile (); Assert.AreEqual ("foo", fooer (new Foo { Prop = "foo" })); } [Test] public void TestCompileGetStaticProperty () { var sf = Expression.Lambda> ( Expression.Property (null, typeof (Foo).GetProperty ( "StatProp", BindingFlags.Public | BindingFlags.Static))).Compile (); Assert.AreEqual ("StaticFoo", sf ()); } public struct Bar { private string slot; public string Prop { get { return slot; } set { slot = value; } } public Bar (string slot) { this.slot = slot; } } [Test] public void TestCompileGetInstancePropertyOnStruct () { var p = Expression.Parameter (typeof (Bar), "bar"); var barer = Expression.Lambda> ( Expression.Property (p, typeof (Bar).GetProperty ("Prop")), p).Compile (); Assert.AreEqual ("bar", barer (new Bar ("bar"))); } public static int StaticProperty { get { return 42; } } [Test] [Category ("NotDotNet")] // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=339351 [ExpectedException (typeof (ArgumentException))] public void StaticPropertyWithInstanceArgument () { Expression.Property ( Expression.Parameter (GetType (), "t"), GetType ().GetProperty ("StaticProperty")); } } }