// 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 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Copyright (c) 2007 Novell, Inc. (http://www.novell.com) // // Authors: // Chris Toshok (toshok@ximian.com) // using System; using System.Windows; using System.Windows.Media; using NUnit.Framework; namespace MonoTests.System.Windows { class TestDepObj : DependencyObject { public static readonly DependencyProperty TestProp1 = DependencyProperty.Register ("property1", typeof (string), typeof (TestDepObj)); public static readonly DependencyProperty TestProp2 = DependencyProperty.Register ("property2", typeof (string), typeof (TestDepObj)); public static readonly DependencyProperty TestProp3 = DependencyProperty.Register ("property3", typeof (string), typeof (TestDepObj)); public static readonly DependencyProperty TestProp4 = DependencyProperty.Register ("property4", typeof (string), typeof (TestDepObj), new PropertyMetadata ("default", changed, coerce)); static void changed (DependencyObject d, DependencyPropertyChangedEventArgs e) { } static object coerce (DependencyObject d, object baseValue) { return baseValue; } } class TestSubclass : TestDepObj { } public class PropertyMetadataPoker : PropertyMetadata { public bool BaseIsSealed { get { return base.IsSealed; } } public void CallApply () { OnApply (TestDepObj.TestProp1, typeof (TestDepObj)); } public void CallMerge (PropertyMetadata baseMetadata, DependencyProperty dp) { Merge (baseMetadata, dp); } protected override void Merge (PropertyMetadata baseMetadata, DependencyProperty dp) { Console.WriteLine (Environment.StackTrace); base.Merge (baseMetadata, dp); } protected override void OnApply (DependencyProperty dp, Type targetType) { base.OnApply (dp, targetType); Console.WriteLine ("IsSealed in OnApply? {0}", IsSealed); Console.WriteLine (Environment.StackTrace); } } [TestFixture] public class PropertyMetadataTest { [Test] public void DefaultValues () { PropertyMetadataPoker m = new PropertyMetadataPoker (); Assert.AreEqual (null, m.DefaultValue); Assert.AreEqual (null, m.PropertyChangedCallback); Assert.AreEqual (null, m.CoerceValueCallback); } [Test] public void IsSealed () { PropertyMetadataPoker m; Console.WriteLine (1); // calling OnApply isn't what sets the metadata to be sealed m = new PropertyMetadataPoker(); Assert.IsFalse (m.BaseIsSealed); m.CallApply (); Assert.IsFalse (m.BaseIsSealed); Console.WriteLine (2); // calling OverrideMetadata does, however m = new PropertyMetadataPoker (); TestDepObj.TestProp1.OverrideMetadata (typeof (TestSubclass), m); Assert.IsTrue (m.BaseIsSealed); Console.WriteLine (3); // calling DependencyProperty.AddOwner does too, but only because it calls OverrideMetadata m = new PropertyMetadataPoker (); TestDepObj.TestProp2.AddOwner (typeof (TestSubclass), m); Assert.IsTrue (m.BaseIsSealed); Console.WriteLine (4); // lastly, calling DependencyProperty.Register does. m = new PropertyMetadataPoker (); DependencyProperty.Register ("xxx", typeof (string), typeof (TestDepObj), m); Assert.IsTrue (m.BaseIsSealed); } [Test] public void TestAddOwnerResult() { PropertyMetadataPoker m = new PropertyMetadataPoker (); DependencyProperty p = TestDepObj.TestProp3.AddOwner (typeof (TestSubclass), m); // they're the same object Assert.AreSame (p, TestDepObj.TestProp3); } [Test] [ExpectedException (typeof (InvalidOperationException))] public void ModifyAfterSealed1 () { PropertyMetadataPoker m = new PropertyMetadataPoker (); DependencyProperty.Register ("p1", typeof (string), typeof (TestDepObj), m); Assert.IsTrue (m.BaseIsSealed); m.CoerceValueCallback = null; } [Test] [ExpectedException (typeof (InvalidOperationException))] public void ModifyAfterSealed2 () { PropertyMetadataPoker m = new PropertyMetadataPoker (); DependencyProperty.Register ("p2", typeof (string), typeof (TestDepObj), m); Assert.IsTrue (m.BaseIsSealed); m.PropertyChangedCallback = null; } [Test] [ExpectedException (typeof (InvalidOperationException))] public void ModifyAfterSealed3 () { PropertyMetadataPoker m = new PropertyMetadataPoker (); DependencyProperty.Register ("p3", typeof (string), typeof (TestDepObj), m); Assert.IsTrue (m.BaseIsSealed); m.DefaultValue = "hi"; } [Test] public void TestMerge () { PropertyMetadataPoker m = new PropertyMetadataPoker (); m.CallMerge (TestDepObj.TestProp4.GetMetadata (typeof (TestDepObj)), TestDepObj.TestProp4); Assert.AreEqual ("default", m.DefaultValue); Assert.IsNotNull (m.CoerceValueCallback); Assert.IsNotNull (m.PropertyChangedCallback); m = new PropertyMetadataPoker (); m.DefaultValue = "non-default"; m.CallMerge (TestDepObj.TestProp4.GetMetadata (typeof (TestDepObj)), TestDepObj.TestProp4); Assert.AreEqual ("non-default", m.DefaultValue); Assert.IsNotNull (m.CoerceValueCallback); Assert.IsNotNull (m.PropertyChangedCallback); // XXX should check overriding of coerce and // property changed callbacks, but we'll trust // they behave the same.. } [Test] [ExpectedException (typeof (ArgumentException))] // "Default value cannot be 'Unset'." public void TestSetDefaultToUnsetValue () { PropertyMetadata m = new PropertyMetadata (); m.DefaultValue = DependencyProperty.UnsetValue; } [Test] [ExpectedException (typeof (ArgumentException))] // "Default value cannot be 'Unset'." public void TestInitDefaultToUnsetValue () { new PropertyMetadata (DependencyProperty.UnsetValue); } } }