#region License
/*
* Copyright 2002-2004 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
#region Imports
using System;
using System.Collections;
#if NET_2_0
using System.Collections.Generic;
#endif
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using Common.Logging;
using Common.Logging.Simple;
using NUnit.Framework;
using Spring.Collections;
using Spring.Core;
using Spring.Core.TypeConversion;
using Spring.Objects.Factory;
using Spring.Util;
#endregion
namespace Spring.Objects{
/// <summary>
/// Unit tests for the ObjectWrapper class.
/// </summary>
/// <author>Rod Johnson</author>
/// <author>Mark Pollack (.NET)</author>
/// <author>Rick Evans (.NET)</author>
[TestFixture]
public sealed class ObjectWrapperTests
{
/// <summary>
/// The setup logic executed before the execution of this test fixture.
/// </summary>
[TestFixtureSetUp]
public void FixtureSetUp()
{
// enable logging (to nowhere), just to exercisee the logging code...
LogManager.Adapter = new NoOpLoggerFactoryAdapter();
}
#region Classes Used During Tests
public class Person
{
private IList favoriteNames = new ArrayList();
private IDictionary properties = new Hashtable();
private string sillyString;
public Person()
{
favoriteNames.Add("p1");
favoriteNames.Add("p2");
}
public Person(IList favNums)
{
favoriteNames = favNums;
}
public string SillyString
{
get { return sillyString; }
}
public IList FavoriteNames
{
get { return favoriteNames; }
}
public IDictionary Properties
{
get { return properties; }
}
public string this[int index]
{
get { return (string)favoriteNames[index]; }
set { favoriteNames[index] = value; }
}
public string this[string keyName]
{
get { return (string) properties[keyName]; }
set { properties.Add(keyName,value); }
}
public string this[int index, string keyname]
{
get { return sillyString; }
set { sillyString = index + "-" + keyname + ",val=" + value;}
}
}
#if NET_2_0
public class GenericPerson
{
private List<string> favoriteNames = new List<string>();
private IDictionary<string, string> properties = new Dictionary<string, string>();
public GenericPerson()
{
favoriteNames.Add("p1");
favoriteNames.Add("p2");
}
public GenericPerson(List<string> favNums)
{
favoriteNames = favNums;
}
/*
public string this[int index]
{
get { return (string)favoriteNames[index]; }
set { favoriteNames[index] = value; }
}
*/
public string this[string keyName]
{
get { return properties[keyName]; }
set { properties.Add(keyName, value); }
}
}
#endif
public class AltPerson
{
private IList favoriteNames = new ArrayList();
public AltPerson()
{
favoriteNames.Add("ap1");
favoriteNames.Add("ap2");
}
public AltPerson(IList favNums)
{
favoriteNames = favNums;
}
[IndexerName("FavoriteName")]
public string this[int index]
{
get { return (string)favoriteNames[index]; }
set { favoriteNames[index] = value; }
}
}
public class NoNullsList : ArrayList
{
public override int Add(object value)
{
if (value == null)
{
throw new NullReferenceException("Adding nulls is not supported in this implementation.");
}
return base.Add(value);
}
}
private class Honey
{
public Honey(IList akas)
{
_akas = new Aliases(akas);
}
protected Aliases _akas;
public Aliases AlsoKnownAs
{
get { return _akas; }
}
public string this[int index]
{
get { return AlsoKnownAs[index]; }
}
}
private class NonReadableHoney : Honey
{
public NonReadableHoney(IList akas) : base(akas)
{
}
new public Aliases AlsoKnownAs
{
set { _akas = value; }
}
}
private class Milk
{
public Milk(Honey[] honeys)
{
}
public Honey[] Honeys
{
set
{
}
}
}
private sealed class Aliases
{
private IList _names;
public Aliases() : this(new ArrayList())
{
}
public Aliases(IList names)
{
_names = names;
}
public string this[int index]
{
get { return (string) _names[index]; }
set { _names[index] = value; }
}
}
private sealed class RealNestedTestObject
{
public TestObject Datum
{
get { return _datum; }
set { _datum = value; }
}
private TestObject _datum;
}
private sealed class WanPropsClass
{
public bool IsWan
{
get { return true; }
}
}
private sealed class StringAppenderConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof (string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(
ITypeDescriptorContext context, CultureInfo culture, object val)
{
if (val is string)
{
return "OctopusOil : " + val;
}
return base.ConvertFrom(context, culture, val);
}
}
private sealed class TestStringArrayConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof (string[]))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object val)
{
if (val is string[])
{
return "-" + StringUtils.CollectionToCommaDelimitedString(val as string[]) + "-";
}
return base.ConvertFrom(context, culture, val);
}
}
private sealed class TestObjectArrayConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof (string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object val)
{
if (val is string)
{
return new TestObject((string) val, 99);
}
return base.ConvertFrom(context, culture, val);
}
}
private sealed class ObjectWithTypeProperty
{
private Type _type;
public Type Type
{
get { return _type; }
set { _type = value; }
}
}
/// <summary>
/// A class for use in testing the object wrapper with read only properties.
/// </summary>
private sealed class NoRead
{
public int Age
{
set
{
}
}
}
private sealed class GetterObject
{
public string Name
{
get
{
if (_name == null)
{
throw new ApplicationException("name property must be set");
}
return _name;
}
set { _name = value; }
}
private string _name;
}
private sealed class ThrowsException
{
public void DoSomething(Exception t)
{
throw t;
}
}
internal sealed class PrimitiveArrayObject
{
public int[] Array
{
get { return array; }
set { this.array = value; }
}
private int[] array;
}
private sealed class PropsTest
{
public NameValueCollection Properties
{
set
{
}
}
public String Name
{
set
{
}
}
public String[] StringArray
{
set { this.stringArray = value; }
}
public int[] IntArray
{
set { this.intArray = value; }
}
public String[] stringArray;
public int[] intArray;
}
#endregion
#region Methods
/// <summary>
/// Factory method for getting an ObjectWrapper instance.
/// </summary>
/// <returns>A new object wrapper (with no WrappedObject).</returns>
private ObjectWrapper GetWrapper()
{
return new ObjectWrapper();
}
/// <summary>
/// Factory method for getting an ObjectWrapper instance.
/// </summary>
/// <param name="objectToBeWrapped">
/// The object that is to be wrapped by the returned object wrapper.
/// </param>
/// <returns>
/// A new object wrapper that wraps the supplied <paramref name="objectToBeWrapped"/>.
/// </returns>
private ObjectWrapper GetWrapper(object objectToBeWrapped)
{
return new ObjectWrapper(objectToBeWrapped);
}
#endregion
[Test]
[ExpectedException(typeof (TypeMismatchException))]
public void SetPropertyUsingValueThatNeedsConversionWithNoCustomConverterRegistered()
{
ObjectWrapper wrapper = GetWrapper(new TestObject("Rick", 30));
// needs conversion to NestedTestObject...
wrapper.SetPropertyValue("doctor", "Pollack, Pinch, & Pounce");
}
[Test]
[Ignore()]
public void GetValueOfCustomIndexerProperty()
{
ObjectWrapper wrapper = GetWrapper();
Honey darwin = new Honey(new string[] {"dickens", "of gaunt"});
wrapper.WrappedInstance = darwin;
string alias = (string) wrapper.GetPropertyValue("AlsoKnownAs[1]");
Assert.AreEqual("of gaunt", alias);
alias = (string) wrapper.GetPropertyValue("[1]");
Assert.AreEqual("of gaunt", alias, "indexer on object not working.");
wrapper.SetPropertyValue("Item[1]", "of foobar");
alias = (string)wrapper.GetPropertyValue("[1]");
Assert.AreEqual("of foobar", alias, "indexer on object not working.");
}
[Test]
[Ignore()]
public void GetSetIndexerProperties()
{
IList favNames = new ArrayList();
favNames.Add("Master Shake");
favNames.Add("Meatwad");
favNames.Add("Frylock");
Person p = new Person(favNames);
ObjectWrapper wrapper = GetWrapper();
wrapper.WrappedInstance = p;
//This is 'new' Spring.Expressions notation, i.e. not "Item[i]" but plain [i].
string name = (string)wrapper.GetPropertyValue("[0]");
Assert.AreEqual("Master Shake", name);
wrapper.SetPropertyValue("[0]", "Carl");
name = (string)wrapper.GetPropertyValue("[0]");
Assert.AreEqual("Carl", name);
//Try with Custom Indexer Name.
favNames = new ArrayList();
favNames.Add("Master Shake");
favNames.Add("Meatwad");
favNames.Add("Frylock");
AltPerson ap = new AltPerson(favNames);
wrapper = GetWrapper();
wrapper.WrappedInstance = ap;
name = (string)wrapper.GetPropertyValue("FavoriteName[0]");
Assert.AreEqual("Master Shake", name);
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetValueOfCustomIndexerPropertyWithMalformedIndexer()
{
ObjectWrapper wrapper = GetWrapper();
Honey darwin = new Honey(new string[] {"dickens", "of gaunt"});
wrapper.WrappedInstance = darwin;
wrapper.GetPropertyValue("AlsoKnownAs[1");
}
[Test]
[ExpectedException(typeof (FatalObjectException))]
public void GetPropertyTypeWithNullPropertyPath()
{
GetWrapper().GetPropertyType(null);
}
[Test]
[ExpectedException(typeof (FatalObjectException))]
public void GetPropertyTypeWithEmptyPropertyPath()
{
GetWrapper().GetPropertyType(string.Empty);
}
[Test]
[ExpectedException(typeof (FatalObjectException))]
public void GetPropertyTypeWithWhitespacedPropertyPath()
{
GetWrapper().GetPropertyType(" ");
}
[Test]
public void GetPropertyType()
{
ObjectWrapper wrapper = GetWrapper(new TestObject());
Type propertyType = wrapper.GetPropertyType("name");
Assert.AreEqual(typeof (string), propertyType);
}
[Test]
public void GetPropertyTypeFromField_SPRNET502()
{
ObjectWrapper wrapper = GetWrapper(new TestObject());
Type propertyType = wrapper.GetPropertyType("FileModeEnum");
Assert.AreEqual(typeof (FileMode), propertyType);
}
[Test]
public void GetPropertyTypeWithNestedLookup()
{
TestObject target = new TestObject();
target.Spouse = new TestObject("Fiona", 28);
ObjectWrapper wrapper = GetWrapper(target);
Type propertyType = wrapper.GetPropertyType("spouse.age");
Assert.AreEqual(typeof (int), propertyType);
}
[Test]
[ExpectedException(typeof (NotWritablePropertyException))]
public void SetValueOfCustomIndexerPropertyWithNonReadablePropertyInIndexedPath()
{
ObjectWrapper wrapper = GetWrapper();
Honey[] honeys = new NonReadableHoney[] {new NonReadableHoney(new string[] {"hsu", "feng"})};
wrapper.WrappedInstance = new Milk(honeys);
wrapper.SetPropertyValue("Honeys[0][0]", "mei");
}
[Test]
[ExpectedException(typeof (TypeMismatchException))]
public void SetPropertyThatRequiresTypeConversionWithNonConvertibleType()
{
ObjectWrapper wrapper = GetWrapper();
TestObject to = new TestObject();
wrapper.WrappedInstance = to;
wrapper.SetPropertyValue("RealLawyer", "Noob");
Console.Out.WriteLine(to.RealLawyer);
}
/// <summary>
/// This test blows up because index is out of range.
/// </summary>
[Test]
[ExpectedException(typeof(InvalidPropertyException))]
public void SetIndexedPropertyOnListThatsOutOfRange()
{
TestObject to = new TestObject();
ObjectWrapper wrapper = GetWrapper(to);
to.Friends = new NoNullsList();
wrapper.SetPropertyValue("Friends[5]", "Inheritance Tax");
}
/// <summary>
/// Tests that a property lookup such as <c>foo[0][1]['ben'][12]</c> is ok
/// Well, rather it tests that its valid... 'cos man, that shoh ain't ok :D
/// </summary>
[Test]
public void GetChainedIndexers()
{
Honey to = new Honey(new string[] {"wee", "jakey", "ned"});
ObjectWrapper wrapper = GetWrapper(to);
Assert.AreEqual('j', wrapper.GetPropertyValue("AlsoKnownAs[1][0]"));
}
/// <summary>
/// Test that passing a null value of the object to manipulate with the ObjectWrapper
/// will throw a FatalPropertyException with the correct exception message.
/// </summary>
[Test]
[ExpectedException(typeof (FatalObjectException))]
public void NullObject()
{
new ObjectWrapper((object) null);
}
[Test]
[ExpectedException(typeof (FatalObjectException))]
public void InstantiateWithInterfaceType()
{
new ObjectWrapper(typeof (IList));
}
[Test]
[ExpectedException(typeof (FatalObjectException))]
public void InstantiateWithAbstractType()
{
new ObjectWrapper(typeof (AbstractObjectFactoryTests));
}
[Test]
public void InstantiateWithOkType()
{
IObjectWrapper wrapper = GetWrapper(typeof (TestObject));
Assert.IsNotNull(wrapper.WrappedInstance);
}
[Test]
public void NestedProperties()
{
string doctorCompany = "";
string lawyerCompany = "Dr. Sueem";
TestObject to = new TestObject();
IObjectWrapper wrapper = GetWrapper(to);
wrapper.SetPropertyValue("Doctor.Company", doctorCompany);
wrapper.SetPropertyValue("Lawyer.Company", lawyerCompany);
Assert.AreEqual(doctorCompany, to.Doctor.Company);
Assert.AreEqual(lawyerCompany, to.Lawyer.Company);
}
[Test]
public void GetterThrowsException()
{
GetterObject go = new GetterObject();
IObjectWrapper wrapper = GetWrapper(go);
wrapper.SetPropertyValue("Name", "tom");
Assert.IsTrue(go.Name.Equals("tom"), "Expected name to be set to 'tom'");
}
[Test]
[ExpectedException(typeof (NotReadablePropertyException))]
public void TryToReadTheValueOfAWriteOnlyProperty()
{
NoRead nr = new NoRead();
ObjectWrapper wrapper = GetWrapper(nr);
wrapper.GetPropertyValue("Age");
}
[Test]
[ExpectedException(typeof(NullValueInNestedPathException))]
public void TryToReadAnIndexedValueFromANullProperty()
{
TestObject o = new TestObject();
o.Friends = null;
ObjectWrapper wrapper = GetWrapper(o);
wrapper.GetPropertyValue("Friends[2]");
}
/// <summary>
/// Test that applying an empty MutablePropertyValues does not modify the object contents.
/// </summary>
[Test]
public void EmptyPropertyValuesSet()
{
TestObject t = new TestObject();
int age = 50;
string name = "Tony";
t.Age = age;
t.Name = name;
IObjectWrapper wrapper = GetWrapper(t);
Assert.IsTrue(t.Age.Equals(age), "Age is not set correctly");
Assert.IsTrue(name.Equals(t.Name), "Name is not set correctly");
wrapper.SetPropertyValues(new MutablePropertyValues());
Assert.IsTrue(t.Age.Equals(age), "Age is not set correctly");
Assert.IsTrue(name.Equals(t.Name), "Name is not set correctly");
}
/// <summary>
/// Test basic ObjectWrapper functionality by setting properties using MutablePropertyValues.
/// </summary>
[Test]
public void AllValid()
{
TestObject t = new TestObject();
string newName = "tony";
int newAge = 65;
string newTouchy = "valid";
IObjectWrapper wrapper = GetWrapper(t);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.Add(new PropertyValue("Age", newAge));
pvs.Add(new PropertyValue("Name", newName));
pvs.Add(new PropertyValue("Touchy", newTouchy));
wrapper.SetPropertyValues(pvs);
Assert.IsTrue(t.Name.Equals(newName), "Validly set property must stick");
Assert.IsTrue(t.Touchy.Equals(newTouchy), "Validly set property must stick");
Assert.IsTrue(t.Age == newAge, "Validly set property must stick");
}
[Test]
public void IndividualAllValid()
{
TestObject t = new TestObject();
String newName = "tony";
int newAge = 65;
string newTouchy = "valid";
IObjectWrapper wrapper = GetWrapper(t);
wrapper.SetPropertyValue("Age", newAge);
wrapper.SetPropertyValue(new PropertyValue("Name", newName));
wrapper.SetPropertyValue(new PropertyValue("Touchy", newTouchy));
Assert.IsTrue(t.Name.Equals(newName), "Validly set property must stick");
Assert.IsTrue(t.Touchy.Equals(newTouchy), "Validly set property must stick");
Assert.IsTrue(t.Age == newAge, "Validly set property must stick");
}
[Test]
public void SettingAnInvalidValue()
{
TestObject t = new TestObject();
string newName = "tony";
try
{
IObjectWrapper wrapper = GetWrapper(t);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.Add(new PropertyValue("Age", "foobar"));
pvs.Add(new PropertyValue("Name", newName));
wrapper.SetPropertyValues(pvs);
Assert.Fail("Should throw exception when setting an invalid value");
}
catch (PropertyAccessExceptionsException ex)
{
Assert.IsTrue(ex.ExceptionCount == 1, "Must contain 2 exceptions");
// Test validly set property matches
Assert.IsTrue(t.Name.Equals(newName), "Validly set property must stick");
Assert.IsTrue(t.Age == 0, "Invalidly set property must retain old value");
}
catch (Exception ex)
{
Assert.Fail(
"Shouldn't throw exception other than PropertyAccessExceptions. Exception Message = " + ex.Message);
}
}
[Test]
public void ArrayToStringConversion()
{
TestObject t = new TestObject();
IObjectWrapper wrapper = GetWrapper(t);
TypeConverterRegistry.RegisterConverter(typeof(string), new TestStringArrayConverter());
wrapper.SetPropertyValue("Name", new string[] {"a", "b"});
Assert.AreEqual("-a,b-", t.Name);
}
[Test]
public void ArrayToArrayConversion()
{
IndexedTestObject to = new IndexedTestObject();
IObjectWrapper wrapper = GetWrapper(to);
TypeConverterRegistry.RegisterConverter(typeof(TestObject), new TestObjectArrayConverter());
wrapper.SetPropertyValue("Array", new string[] {"a", "b"});
Assert.AreEqual("a", to.Array[0].Name);
Assert.AreEqual("b", to.Array[1].Name);
}
[Test]
public void PrimitiveArray()
{
PrimitiveArrayObject to = new PrimitiveArrayObject();
IObjectWrapper wrapper = GetWrapper(to);
wrapper.SetPropertyValue("Array", new String[] {"1", "2"});
Assert.AreEqual(2, to.Array.Length);
Assert.AreEqual(1, to.Array[0]);
Assert.AreEqual(2, to.Array[1]);
}
[Test]
public void PrimitiveArrayFromCommaDelimitedString()
{
PrimitiveArrayObject to = new PrimitiveArrayObject();
IObjectWrapper wrapper = GetWrapper(to);
wrapper.SetPropertyValue("Array", "1,2");
Assert.AreEqual(2, to.Array.Length);
Assert.AreEqual(1, to.Array[0]);
Assert.AreEqual(2, to.Array[1]);
}
[Test]
public void ObjectWrapperUpdates()
{
TestObject to = new TestObject("Rick", 2);
int newAge = 33;
ObjectWrapper wrapper = GetWrapper(to);
to.Age = newAge;
object owAge = wrapper.GetPropertyValue("Age");
Assert.IsTrue(owAge is Int32, "Age is an integer");
int owi = (int) owAge;
Assert.IsTrue(owi == newAge, "Object wrapper must pick up changes");
}
[Test]
public void SetWrappedInstanceOfSameClass()
{
TestObject to = new TestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Age = 11;
TestObject to2 = new TestObject();
wrapper.WrappedInstance = to2;
wrapper.SetPropertyValue("Age", 14);
Assert.IsTrue(to2.Age == 14, "2nd changed");
Assert.IsTrue(to.Age == 11, "1st didn't change");
}
[Test]
public void SetWrappedInstanceOfDifferentClass()
{
ThrowsException tex = new ThrowsException();
ObjectWrapper wrapper = GetWrapper(tex);
TestObject to2 = new TestObject();
wrapper.WrappedInstance = to2;
wrapper.SetPropertyValue("Age", 14);
Assert.IsTrue(to2.Age == 14);
}
[Test]
[ExpectedException(typeof (TypeMismatchException))]
public void TypeMismatch()
{
TestObject to = new TestObject();
IObjectWrapper wrapper = GetWrapper(to);
wrapper.SetPropertyValue("Age", "foobar");
}
[Test]
[ExpectedException(typeof (TypeMismatchException))]
public void EmptyValueForPrimitiveProperty()
{
TestObject to = new TestObject();
ObjectWrapper wrapper = GetWrapper(to);
wrapper.SetPropertyValue("Age", "");
}
[Test]
public void GetProtectedPropertyValue()
{
TestObject foo = new TestObject();
IObjectWrapper wrapper = GetWrapper(foo);
string happyPlace = (string) wrapper.GetPropertyValue("HappyPlace");
Assert.AreEqual(TestObject.DefaultHappyPlace, happyPlace,
"Failed to read the value of a property with 'protected' access.");
}
[Test]
public void SetProtectedPropertyValue()
{
TestObject foo = new TestObject();
IObjectWrapper wrapper = GetWrapper(foo);
const string expectedHappyPlace = "The Rockies! Brrr...";
wrapper.SetPropertyValue(new PropertyValue("HappyPlace", expectedHappyPlace));
string happyPlace = (string) wrapper.GetPropertyValue("HappyPlace");
Assert.AreEqual(expectedHappyPlace, happyPlace,
"Failed to read / write the value of a property with 'protected' access.");
}
[Test]
public void GetPrivatePropertyValue()
{
TestObject foo = new TestObject();
IObjectWrapper wrapper = GetWrapper(foo);
string[] contents = (string[]) wrapper.GetPropertyValue("SamsoniteSuitcase");
Assert.IsTrue(ArrayUtils.AreEqual(TestObject.DefaultContentsOfTheSuitcase, contents),
"Failed to read the value of a property with 'private' access.");
}
[Test]
public void SetPrivatePropertyValue()
{
TestObject foo = new TestObject();
IObjectWrapper wrapper = GetWrapper(foo);
string[] expectedContents = new string[] {"Lloyd's Soul", "Harry's John Denver Records"};
wrapper.SetPropertyValue(new PropertyValue("SamsoniteSuitcase", expectedContents));
string[] contents = (string[]) wrapper.GetPropertyValue("SamsoniteSuitcase");
Assert.IsTrue(ArrayUtils.AreEqual(expectedContents, contents),
"Failed to read / write the value of a property with 'private' access.");
}
[Test]
public void GetNestedProperty()
{
ITestObject rod = new TestObject("rod", 31);
ITestObject kerry = new TestObject("kerry", 35);
rod.Spouse = kerry;
kerry.Spouse = rod;
IObjectWrapper wrapper = GetWrapper(rod);
int KA = (int) wrapper.GetPropertyValue("Spouse.Age");
Assert.IsTrue(KA == 35, "Expected kerry's age to be 35");
int RA = (int) wrapper.GetPropertyValue("Spouse.Spouse.Age");
Assert.IsTrue(RA == 31, "Expected rod's age to be 31");
ITestObject spousesSpouse = (ITestObject) wrapper.GetPropertyValue("Spouse.Spouse");
Assert.IsTrue(rod == spousesSpouse, "spousesSpouse == initial point");
}
[Test]
[ExpectedException(typeof (NullValueInNestedPathException))]
public void GetNestedPropertyValueNullValue()
{
TestObject rod = new TestObject("rod", 31);
rod.Doctor = new NestedTestObject(null);
GetWrapper(rod).GetPropertyValue("Doctor.Company.Length");
}
[Test]
public void SetNestedProperty()
{
ITestObject rod = new TestObject("rod", 31);
ITestObject kerry = new TestObject("kerry", 0);
IObjectWrapper wrapper = GetWrapper(rod);
wrapper.SetPropertyValue("Spouse", kerry);
Assert.AreEqual(rod.Spouse, kerry, "nested set did not work");
wrapper.SetPropertyValue("Spouse.Spouse", rod);
Assert.AreEqual(rod, rod.Spouse.Spouse, "Nested set did not work.");
wrapper.SetPropertyValue("Spouse.Age", 100);
Assert.AreEqual(100, kerry.Age, "Nested setting of primitive property did not work.");
}
[Test]
public void SetPropertyValue()
{
ITestObject bigby = new TestObject("Bigby", 4500);
ITestObject snow = new TestObject("Snow", 2500);
IObjectWrapper wrapper = GetWrapper(bigby);
wrapper.SetPropertyValue("Spouse", snow);
Assert.AreEqual(snow, bigby.Spouse);
}
[Test]
[ExpectedException(typeof (NullValueInNestedPathException))]
public void SetIndexedPropertyValueOnUninitializedPath()
{
TestObject obj = new TestObject("Bill", 4500);
IObjectWrapper wrapper = GetWrapper(obj);
wrapper.SetPropertyValue("hats [0]", "Hicks & Co");
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void SetIndexedPropertyValueOnNonIndexableType()
{
TestObject obj = new TestObject("Bill", 4500);
IObjectWrapper wrapper = GetWrapper(obj);
wrapper.SetPropertyValue("doctor [0]", "Hicks & Co");
}
[Test]
[ExpectedException(typeof (TypeMismatchException))]
public void SetPrimitivePropertyToNullReference()
{
TestObject obj = new TestObject("Bill", 4500);
IObjectWrapper wrapper = GetWrapper(obj);
wrapper.SetPropertyValue("Age", null);
}
[Test]
public void SetPropertyValueIgnoresCase()
{
ITestObject bigby = new TestObject("Bigby", 4500);
ITestObject snow = new TestObject("Snow", 2500);
IObjectWrapper wrapper = GetWrapper(bigby);
wrapper.SetPropertyValue("spouse", snow);
Assert.AreEqual(snow, bigby.Spouse,
"Property setting is not case insensitive with regard to the property name (and for CLS compliance it should be).");
}
[Test]
public void IntArrayProperty()
{
PropsTest pt = new PropsTest();
IObjectWrapper wrapper = GetWrapper(pt);
wrapper.SetPropertyValue("IntArray", new int[] {4, 5, 2, 3});
Assert.IsTrue(pt.intArray.Length == 4, "intArray length = 4");
Assert.IsTrue(pt.intArray[0] == 4 && pt.intArray[1] == 5 && pt.intArray[2] == 2 && pt.intArray[3] == 3,
"correct values");
wrapper.SetPropertyValue("IntArray", new String[] {"4", "5", "2", "3"});
Assert.IsTrue(pt.intArray.Length == 4, "intArray length = 4");
Assert.IsTrue(pt.intArray[0] == 4 && pt.intArray[1] == 5 && pt.intArray[2] == 2 && pt.intArray[3] == 3,
"correct values");
wrapper.SetPropertyValue("IntArray", 1);
Assert.IsTrue(pt.intArray.Length == 1, "intArray length = 1");
Assert.IsTrue(pt.intArray[0] == 1, "correct values");
wrapper.SetPropertyValue("IntArray", new String[] {"1"});
Assert.IsTrue(pt.intArray.Length == 1, "intArray length = 1");
Assert.IsTrue(pt.intArray[0] == 1, "correct values");
}
[Test]
public void NewWrappedInstancePropertyValuesGet()
{
ObjectWrapper wrapper = GetWrapper();
TestObject t = new TestObject("Tony", 50);
wrapper.WrappedInstance = t;
Assert.AreEqual(t.Age, wrapper.GetPropertyValue("Age"), "Object wrapper returns wrong property value");
TestObject u = new TestObject("Udo", 30);
wrapper.WrappedInstance = u;
Assert.AreEqual(u.Age, wrapper.GetPropertyValue("Age"), "Object wrapper returns cached property value");
}
[Test]
public void NewWrappedInstanceNestedPropertyValuesGet()
{
IObjectWrapper wrapper = GetWrapper();
TestObject t = new TestObject("Tony", 50);
t.Spouse = new TestObject("Sue", 40);
wrapper.WrappedInstance = t;
Assert.AreEqual(t.Spouse.Age, wrapper.GetPropertyValue("Spouse.Age"),
"Object wrapper returns wrong nested property value");
TestObject u = new TestObject("Udo", 30);
u.Spouse = new TestObject("Vera", 20);
wrapper.WrappedInstance = u;
Assert.AreEqual(u.Spouse.Age, wrapper.GetPropertyValue("Spouse.Age"),
"Object wrapper returns cached nested property value");
}
[Test]
public void StringArrayProperty()
{
PropsTest pt = new PropsTest();
ObjectWrapper wrapper = GetWrapper(pt);
wrapper.SetPropertyValue("StringArray", "foo,fi,fi,fum");
Assert.IsTrue(pt.stringArray.Length == 4, "StringArray length = 4");
Assert.IsTrue(
pt.stringArray[0].Equals("foo") && pt.stringArray[1].Equals("fi") && pt.stringArray[2].Equals("fi") &&
pt.stringArray[3].Equals("fum"), "in correct values of string array");
}
#region Test for DateTime Properties
internal class DateTimeTestObject
{
private DateTime _dt;
public DateTime TriggerDateTime
{
get { return _dt; }
set { _dt = value; }
}
}
[Test]
public void SetDateTimeProperty()
{
DateTimeTestObject o = new DateTimeTestObject();
ObjectWrapper wrapper = GetWrapper(o);
wrapper.SetPropertyValue("TriggerDateTime", "1991-10-10");
Assert.AreEqual(1991, ((DateTime) wrapper.GetPropertyValue("TriggerDateTime")).Year);
}
#endregion
#region Test for CultureInfo Properties
internal class CultureTestObject
{
private CultureInfo _ci;
public CultureInfo Cult
{
get { return _ci; }
set { _ci = value; }
}
}
[Test]
public void SetCultureInfoProperty()
{
CultureTestObject o = new CultureTestObject();
ObjectWrapper wrapper = GetWrapper(o);
wrapper.SetPropertyValue("Cult", "es-ES");
Assert.AreEqual("es-ES",
((CultureInfo) wrapper.GetPropertyValue("Cult")).Name);
}
#endregion
#region Tests for URI Properties
internal class URITestObject
{
private Uri _uri;
public Uri ResourceIdentifier
{
get { return _uri; }
set { _uri = value; }
}
}
[Test]
public void SetURIProperty()
{
URITestObject o = new URITestObject();
ObjectWrapper wrapper = GetWrapper(o);
wrapper.SetPropertyValue("ResourceIdentifier", "http://www.springframework.net");
Assert.AreEqual("www.springframework.net",
((Uri) wrapper.GetPropertyValue("ResourceIdentifier")).Host);
}
#endregion
#region Tests for Indexed Array Properties
[Test]
public void GetIndexedFromArrayProperty()
{
PrimitiveArrayObject to = new PrimitiveArrayObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Array = new int[] {1, 2, 3, 4, 5};
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("Array[0]"));
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetIndexOutofRangeFromArrayProperty()
{
PrimitiveArrayObject to = new PrimitiveArrayObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Array = new int[] {1, 2, 3, 4, 5};
wrapper.GetPropertyValue("Array[5]");
}
[Test]
public void SetIndexedFromArrayProperty()
{
PrimitiveArrayObject to = new PrimitiveArrayObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Array = new int[] {1, 2, 3, 4, 5};
wrapper.SetPropertyValue("Array[2]", 6);
Assert.AreEqual(6, to.Array[2]);
}
[Test]
[ExpectedException(typeof(InvalidPropertyException))]
public void SetIndexOutOfRangeFromArrayProperty()
{
PrimitiveArrayObject to = new PrimitiveArrayObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Array = new int[] {1, 2, 3, 4, 5};
wrapper.SetPropertyValue("Array[5]", 6);
}
/// <summary>
/// Test that we bail when attempting to get an indexed property with some guff for the index
/// </summary>
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetIndexedPropertyValueWithGuffIndexFromArrayProperty()
{
PrimitiveArrayObject to = new PrimitiveArrayObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Array = new int[] {1, 2, 3, 4, 5};
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("Array[HungerHurtsButStarvingWorks]"));
}
/// <summary>
/// Test that we bail when attempting to get an indexed property with some guff for the index
/// </summary>
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetIndexedPropertyValueWithMissingIndexFromArrayProperty()
{
PrimitiveArrayObject to = new PrimitiveArrayObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Array = new int[] {1, 2, 3, 4, 5};
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("Array[]"));
}
#endregion
#region Tests for Indexed List Properties
internal class ListTestObject
{
private IList _list;
private ArrayList _arrayList;
public IList List
{
get { return _list; }
set { _list = value; }
}
public ArrayList ArrayList
{
get { return _arrayList; }
set { _arrayList = value; }
}
}
[Test]
public void GetIndexedFromListProperty()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.List = new ArrayList(new int[] {1, 2, 3, 4, 5});
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("List[0]"));
}
[Test]
public void GetIndexedFromArrayListProperty()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.ArrayList = new ArrayList(new int[] {1, 2, 3, 4, 5});
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("ArrayList[0]"));
}
[Test]
[ExpectedException(typeof(InvalidPropertyException))]
public void GetIndexOutofRangeFromListProperty()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.List = new ArrayList(new int[] {1, 2, 3, 4, 5});
wrapper.GetPropertyValue("List[5]");
}
[Test]
public void SetIndexedFromListProperty()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.List = new ArrayList(new int[] {1, 2, 3, 4, 5});
wrapper.SetPropertyValue("List[0]", 6);
Assert.AreEqual(6, to.List[0]);
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void SetIndexedFromListPropertyUsingMixOfSingleAndDoubleQuotedDelimeters()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.List = new ArrayList(new int[] {1, 2, 3, 4, 5});
wrapper.SetPropertyValue("List['0\"]", 6);
Assert.AreEqual(6, to.List[0]);
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void SetIndexedFromListPropertyUsingNonNumericValueForTheIndex()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.List = new ArrayList(new int[] {1, 2, 3, 4, 5});
wrapper.SetPropertyValue("List[bingo]", 6);
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void SetIndexedFromListPropertyUsingEmptyValueForTheIndex()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.List = new ArrayList(new int[] {1, 2, 3, 4, 5});
wrapper.SetPropertyValue("List[]", 6);
}
[Test]
[Ignore("Addition of elements to the list via index that is out of range is not supported anymore.")]
public void SetIndexOutOfRangeFromListProperty()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.List = new ArrayList(new int[] {1, 2, 3, 4, 5});
wrapper.SetPropertyValue("List[6]", 6);
Assert.AreEqual(6, to.List[6]);
Assert.IsNull(to.List[5]);
wrapper.SetPropertyValue("List[7]", 7);
Assert.AreEqual(7, to.List[7]);
}
/// <summary>
/// Test that we bail when attempting to get an indexed property with some guff for the index
/// </summary>
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetIndexedPropertyValueWithGuffIndexFromListProperty()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.List = new ArrayList(new int[] {1, 2, 3, 4, 5});
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("List[HungerHurtsButStarvingWorks]"));
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetIndexedPropertyValueWithMissingIndexFromListProperty()
{
ListTestObject to = new ListTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.List = new ArrayList(new int[] {1, 2, 3, 4, 5});
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("List[]"));
}
#endregion
#region Tests for Indexed Dictionary Properties
internal class DictionaryTestObject
{
private IDictionary _dictionary;
public IDictionary Dictionary
{
get { return _dictionary; }
set { _dictionary = value; }
}
}
[Test]
public void GetIndexedFromDictionaryProperty()
{
DictionaryTestObject to = new DictionaryTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Dictionary = new Hashtable();
to.Dictionary.Add("key1", "value1");
Assert.AreEqual("value1", (string) wrapper.GetPropertyValue("Dictionary['key1']"));
}
[Test]
public void GetIndexMissingFromDictionaryProperty()
{
DictionaryTestObject to = new DictionaryTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Dictionary = new Hashtable();
Assert.IsNull(wrapper.GetPropertyValue("Dictionary['notthere']"));
}
[Test]
public void SetIndexedFromDictionaryProperty()
{
DictionaryTestObject to = new DictionaryTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Dictionary = new Hashtable();
wrapper.SetPropertyValue("Dictionary['key1']", "value1");
Assert.AreEqual("value1", to.Dictionary["key1"]);
}
[Test]
public void SettingADictionaryPropertyJustAddsTheValuesToTheExistingDictionary()
{
TestObject to = new TestObject();
to.AddPeriodicElement("Hsu", "Feng");
to.AddPeriodicElement("Piao", "Jin");
ObjectWrapper wrapper = GetWrapper(to);
IDictionary elements = new Hashtable();
elements.Add("Weekend", "News");
wrapper.SetPropertyValue("PeriodictabLE", elements);
Assert.AreEqual(3, to.PeriodicTable.Count);
}
#endregion
#region Tests for Indexed Set Properties
internal class SetTestObject
{
private ISet _set;
private HybridSet _aSet;
public ISet Set
{
get { return _set; }
set { _set = value; }
}
public HybridSet HybridSet
{
get { return _aSet; }
set { _aSet = value; }
}
}
[Test]
public void SettingASetPropertyJustAddsTheValuesToTheExistingSet()
{
TestObject to = new TestObject();
to.AddComputerName("Atari 2900");
to.AddComputerName("JCN");
ObjectWrapper wrapper = GetWrapper(to);
wrapper.SetPropertyValue("Computers", new HybridSet(new string[] {"Trusty SNES"}));
Assert.AreEqual(3, to.Computers.Count);
}
[Test]
[ExpectedException(typeof(InvalidPropertyException))]
public void GetIndexFromSetProperty()
{
SetTestObject to = new SetTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Set = new ListSet(new int[] { 1, 2, 3, 4, 5 });
Assert.AreEqual(1, (int)wrapper.GetPropertyValue("Set[1]"));
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetIndexOutofRangeFromSetProperty()
{
SetTestObject to = new SetTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Set = new ListSet(new int[] {1, 2, 3, 4, 5});
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("Set[23]"));
}
/// <summary>
/// Test that we bail when attempting to get an indexed property with some guff for the index
/// </summary>
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetIndexedPropertyValueWithGuffIndexFromSetProperty()
{
SetTestObject to = new SetTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Set = new ListSet(new int[] {1, 2, 3, 4, 5});
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("Set[HungerHurtsButStarvingWorks]"));
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetIndexedPropertyValueWithMissingIndexFromSetProperty()
{
SetTestObject to = new SetTestObject();
IObjectWrapper wrapper = GetWrapper(to);
to.Set = new ListSet(new int[] {1, 2, 3, 4, 5});
object o = wrapper.GetPropertyValue("Set[]");
Assert.AreEqual(1, (int) wrapper.GetPropertyValue("Set[]"));
}
#endregion
#region Test for Enumeration Properties
internal class EnumTestObject
{
private FileMode FileModeEnum;
public FileMode FileMode
{
get { return FileModeEnum; }
set { FileModeEnum = value; }
}
}
[Test]
public void SetEnumProperty()
{
EnumTestObject o = new EnumTestObject();
ObjectWrapper wrapper = GetWrapper(o);
wrapper.SetPropertyValue("FileMode", FileMode.Create);
Assert.AreEqual(FileMode.Create, (FileMode) wrapper.GetPropertyValue("FileMode"));
}
#endregion
[Test]
public void SetTypePropertyWithString()
{
ObjectWithTypeProperty to = new ObjectWithTypeProperty();
IObjectWrapper wrapper = GetWrapper(to);
wrapper.SetPropertyValue("Type", "System.DateTime");
Assert.AreEqual(typeof (DateTime), to.Type);
}
[Test]
[ExpectedException(typeof (InvalidPropertyException))]
public void GetIndexedPropertyValueWithNonIndexedType()
{
TestObject to = new TestObject();
IObjectWrapper wrapper = GetWrapper(to);
wrapper.GetPropertyValue("FileMode[0]");
}
[Test]
[ExpectedException(typeof (NullValueInNestedPathException))]
public void SetPropertyValuesWithUnknownProperty()
{
TestObject to = new TestObject();
to.Doctor = null;
ObjectWrapper wrapper = GetWrapper(to);
wrapper.SetPropertyValue("Doctor.Company", "Bingo");
}
[Test]
[ExpectedException(typeof(InvalidPropertyException))]
public void SetPropertyValuesFailsWhenSettingNonExistantProperty()
{
TestObject to = new TestObject();
ObjectWrapper wrapper = GetWrapper(to);
MutablePropertyValues values = new MutablePropertyValues();
values.Add("JeepersCreepersWhereDidYaGetThosePeepers", "OhThisWeirdBatGuySoldEmToMe...");
values.Add("Age", 19);
// the unknown and ridiculously named property should fail
wrapper.SetPropertyValues(values, false);
}
[Test]
public void SetPropertyValuesDoesNotFailWhenSettingNonExistantPropertyWithIgnorUnknownSetToTrue()
{
TestObject to = new TestObject();
ObjectWrapper wrapper = GetWrapper(to);
MutablePropertyValues values = new MutablePropertyValues();
values.Add("Age", 19);
values.Add("JeepersCreepersWhereDidYaGetThosePeepers", "OhThisWeirdBatGuySoldEmToMe...");
// the unknown and ridiculously named property should fail
wrapper.SetPropertyValues(values, true);
Assert.AreEqual(19, to.Age, "The single good property in the property values should have been set though...");
}
[Test]
[ExpectedException(typeof(NotWritablePropertyException))]
public void SetPropertyValuesFailsWhenSettingReadOnlyProperty()
{
TestObject to = new TestObject();
ObjectWrapper wrapper = GetWrapper(to);
MutablePropertyValues values = new MutablePropertyValues();
values.Add("ReadOnlyObjectNumber", 123);
wrapper.SetPropertyValues(values, false);
}
[Test]
public void SetPropertyValuesDoesNotFailWhenSettingReadOnlyPropertyWithIgnorUnknownSetToTrue()
{
TestObject to = new TestObject();
ObjectWrapper wrapper = GetWrapper(to);
MutablePropertyValues values = new MutablePropertyValues();
values.Add("ObjectNumber", 123);
values.Add("Age", 19);
wrapper.SetPropertyValues(values, true);
Assert.AreEqual(19, to.Age, "The single good property in the property values should have been set though...");
}
[Test]
public void SetArrayPropertyValue()
{
string[] expected = new string[] {"Fedora", "Gacy", "Banjo"};
TestObject to = new TestObject();
ObjectWrapper wrapper = GetWrapper(to);
wrapper.SetPropertyValue("Hats", expected);
Assert.IsNotNull(to.Hats);
Assert.AreEqual(expected.Length, to.Hats.Length);
for (int i = 0; i < expected.Length; ++i)
{
Assert.AreEqual(expected[i], to.Hats[i]);
}
}
[Test]
public void TestToString()
{
ObjectWrapper wrapper = GetWrapper();
Assert.IsTrue(wrapper.ToString().IndexOf("Exception encountered") >= 0);
wrapper.WrappedInstance = new WanPropsClass();
string expected = string.Format(
"{0}: wrapping class [{1}]; IsWan={2}",
wrapper.GetType().Name, wrapper.WrappedType.FullName, "{True}");
Assert.AreEqual(expected, wrapper.ToString());
}
[Test]
[ExpectedException(typeof (FatalObjectException))]
public void GetPropertyInfoWithNullArgument()
{
ObjectWrapper wrapper = GetWrapper(new TestObject());
wrapper.GetPropertyInfo(null);
}
[Test]
[ExpectedException(typeof (FatalReflectionException))]
public void GetPropertyInfoWithNonPropertyExpression()
{
ObjectWrapper wrapper = GetWrapper(new TestObject());
wrapper.GetPropertyInfo("2 + 2");
}
[Test]
[ExpectedException(typeof (FatalObjectException))]
public void GetPropertyInfoWithNonParsableExpression()
{
ObjectWrapper wrapper = GetWrapper(new TestObject());
wrapper.GetPropertyInfo("[");
}
[Test]
public void GetNestedPropertyInfo()
{
RealNestedTestObject o = new RealNestedTestObject();
o.Datum = new TestObject();
o.Datum.Doctor = new NestedTestObject("Modlin");
ObjectWrapper wrapper = GetWrapper(o);
PropertyInfo info = wrapper.GetPropertyInfo("Datum.Doctor.Company");
Assert.IsNotNull(info);
}
[Test(Description="SPRNET-198")]
public void AmbiguousPropertyLookupIsHandledProperlyByLookingAtDerivedClassOnly()
{
ObjectWrapper wrapper = GetWrapper(new DerivedFoo());
wrapper.GetPropertyInfo("Bar");
}
}
}
|