public void AmbiguousPropertyAccess()
        {
            DerivedPropertyAccessFodder o = new DerivedPropertyAccessFodder();

            AbstractConstraint constraint = Property.Value("Property", "4");

            // This will fail with an AmbiguousMatchException because 'Property' is not
            // unique: there are two public Property properties.
            Assert.Throws <AmbiguousMatchException>(() => Assert.True(constraint.Eval(o)));
        }
        public void DisambiguatedPropertyIsNotNullAccess()
        {
            DerivedPropertyAccessFodder o = new DerivedPropertyAccessFodder();

            AbstractConstraint constraint;

            constraint = Property.IsNotNull(typeof(BasePropertyAccessFodder), "Property");
            Assert.True(constraint.Eval(o), "Base True");

            constraint = Property.IsNotNull(typeof(IPropertyAccessFodder2), "Property");
            Assert.False(constraint.Eval(o), "Interface2 False");
        }
        public void DisambiguatedPropertyConstraintAccess()
        {
            DerivedPropertyAccessFodder o = new DerivedPropertyAccessFodder();

            AbstractConstraint constraint;

            constraint = Property.ValueConstraint(typeof(BasePropertyAccessFodder), "Property", Is.Equal(1));
            Assert.True(constraint.Eval(o), "Base True");
            constraint = Property.ValueConstraint(typeof(BasePropertyAccessFodder), "Property", Is.Equal(0));
            Assert.False(constraint.Eval(o), "Base False");

            constraint = Property.ValueConstraint(typeof(IPropertyAccessFodder1), "Property", Is.Equal(2));
            Assert.True(constraint.Eval(o), "Interface1 True");
            constraint = Property.ValueConstraint(typeof(IPropertyAccessFodder1), "Property", Is.Equal(0));
            Assert.False(constraint.Eval(o), "Interface1 False");

            constraint = Property.ValueConstraint(typeof(IPropertyAccessFodder2), "Property", Is.Equal(null));
            Assert.True(constraint.Eval(o), "Interface2 True");
            constraint = Property.ValueConstraint(typeof(IPropertyAccessFodder2), "Property", Is.Equal(0));
            Assert.False(constraint.Eval(o), "Interface2 False");

            constraint = Property.ValueConstraint(typeof(DerivedPropertyAccessFodder), "Property", Is.Equal("4"));
            Assert.True(constraint.Eval(o), "Derived True");
            constraint = Property.ValueConstraint(typeof(DerivedPropertyAccessFodder), "Property", Is.Equal("0"));
            Assert.False(constraint.Eval(o), "Derived False");

            // Also test that we can use the disambiguation to access private properties
            constraint = Property.ValueConstraint(typeof(BasePropertyAccessFodder), "PrivateProperty", Is.Equal(5));
            Assert.True(constraint.Eval(o), "BasePrivate True");
            constraint = Property.ValueConstraint(typeof(BasePropertyAccessFodder), "PrivateProperty", Is.Equal(0));
            Assert.False(constraint.Eval(o), "BasePrivate False");

            constraint = Property.ValueConstraint(typeof(DerivedPropertyAccessFodder), "PrivateProperty", Is.Equal(6));
            Assert.True(constraint.Eval(o), "DerivedPrivate True");
            constraint = Property.ValueConstraint(typeof(DerivedPropertyAccessFodder), "PrivateProperty", Is.Equal(0));
            Assert.False(constraint.Eval(o), "DerivedPrivate False");
        }
        public void DisambiguatedPropertyConstraintAccess()
        {
            DerivedPropertyAccessFodder o = new DerivedPropertyAccessFodder();

            AbstractConstraint constraint;

            constraint = Property.ValueConstraint(typeof(BasePropertyAccessFodder), "Property", Is.Equal(1));
            Assert.IsTrue(constraint.Eval(o), "Base True");
            constraint = Property.ValueConstraint(typeof(BasePropertyAccessFodder), "Property", Is.Equal(0));
            Assert.IsFalse(constraint.Eval(o), "Base False");

            constraint = Property.ValueConstraint(typeof(IPropertyAccessFodder1), "Property", Is.Equal(2));
            Assert.IsTrue(constraint.Eval(o), "Interface1 True");
            constraint = Property.ValueConstraint(typeof(IPropertyAccessFodder1), "Property", Is.Equal(0));
            Assert.IsFalse(constraint.Eval(o), "Interface1 False");

            constraint = Property.ValueConstraint(typeof(IPropertyAccessFodder2), "Property", Is.Equal(null));
            Assert.IsTrue(constraint.Eval(o), "Interface2 True");
            constraint = Property.ValueConstraint(typeof(IPropertyAccessFodder2), "Property", Is.Equal(0));
            Assert.IsFalse(constraint.Eval(o), "Interface2 False");

            constraint = Property.ValueConstraint(typeof(DerivedPropertyAccessFodder), "Property", Is.Equal("4"));
            Assert.IsTrue(constraint.Eval(o), "Derived True");
            constraint = Property.ValueConstraint(typeof(DerivedPropertyAccessFodder), "Property", Is.Equal("0"));
            Assert.IsFalse(constraint.Eval(o), "Derived False");

            // Also test that we can use the disambiguation to access private properties
            constraint = Property.ValueConstraint(typeof(BasePropertyAccessFodder), "PrivateProperty", Is.Equal(5));
            Assert.IsTrue(constraint.Eval(o), "BasePrivate True");
            constraint = Property.ValueConstraint(typeof(BasePropertyAccessFodder), "PrivateProperty", Is.Equal(0));
            Assert.IsFalse(constraint.Eval(o), "BasePrivate False");

            constraint = Property.ValueConstraint(typeof(DerivedPropertyAccessFodder), "PrivateProperty", Is.Equal(6));
            Assert.IsTrue(constraint.Eval(o), "DerivedPrivate True");
            constraint = Property.ValueConstraint(typeof(DerivedPropertyAccessFodder), "PrivateProperty", Is.Equal(0));
            Assert.IsFalse(constraint.Eval(o), "DerivedPrivate False");
        }
        public void AmbiguousPropertyAccess()
        {
            DerivedPropertyAccessFodder o = new DerivedPropertyAccessFodder();

            AbstractConstraint constraint = Property.Value("Property", "4");

            // This will fail with an AmbiguousMatchException because 'Property' is not
            // unique: there are two public Property properties.
            Assert.IsTrue(constraint.Eval(o));
        }
        public void DisambiguatedPropertyIsNullAccess()
        {
            DerivedPropertyAccessFodder o = new DerivedPropertyAccessFodder();

            AbstractConstraint constraint;

            constraint = Property.IsNull(typeof(BasePropertyAccessFodder), "Property");
            Assert.IsFalse(constraint.Eval(o), "Base False");

            constraint = Property.IsNull(typeof(IPropertyAccessFodder2), "Property");
            Assert.IsTrue(constraint.Eval(o), "Interface2 True");
        }
        public void DisambiguatedPropertyEqualAccess()
        {
            DerivedPropertyAccessFodder o = new DerivedPropertyAccessFodder();

            AbstractConstraint constraint;
            
            constraint = Property.Value(typeof(BasePropertyAccessFodder), "Property", 1);
            Assert.True(constraint.Eval(o), "Base True");
            constraint = Property.Value(typeof(BasePropertyAccessFodder), "Property", 0);
            Assert.False(constraint.Eval(o), "Base False");

            constraint = Property.Value(typeof(IPropertyAccessFodder1), "Property", 2);
            Assert.True(constraint.Eval(o), "Interface1 True");
            constraint = Property.Value(typeof(IPropertyAccessFodder1), "Property", 0);
            Assert.False(constraint.Eval(o), "Interface1 False");

            constraint = Property.Value(typeof(IPropertyAccessFodder2), "Property", null);
            Assert.True(constraint.Eval(o), "Interface2 True");
            constraint = Property.Value(typeof(IPropertyAccessFodder2), "Property", 0);
            Assert.False(constraint.Eval(o), "Interface2 False");

            constraint = Property.Value(typeof(DerivedPropertyAccessFodder), "Property", "4");
            Assert.True(constraint.Eval(o), "Derived True");
            constraint = Property.Value(typeof(DerivedPropertyAccessFodder), "Property", "0");
            Assert.False(constraint.Eval(o), "Derived False");

            // Also test that we can use the disambiguation to access private properties
            constraint = Property.Value(typeof(BasePropertyAccessFodder), "PrivateProperty", 5);
            Assert.True(constraint.Eval(o), "BasePrivate True");
            constraint = Property.Value(typeof(BasePropertyAccessFodder), "PrivateProperty", 0);
            Assert.False(constraint.Eval(o), "BasePrivate False");

            constraint = Property.Value(typeof(DerivedPropertyAccessFodder), "PrivateProperty", 6);
            Assert.True(constraint.Eval(o), "DerivedPrivate True");
            constraint = Property.Value(typeof(DerivedPropertyAccessFodder), "PrivateProperty", 0);
            Assert.False(constraint.Eval(o), "DerivedPrivate False");
        }