# Licensed to the .NET Foundation under one or more agreements.
# The .NET Foundation licenses this file to you under the Apache 2.0 License.
# See the LICENSE file in the project root for more information.

'''
Operations on property.
'''
#------------------------------------------------------------------------------
import unittest

from iptest import IronPythonTestCase, run_test

# from Merlin.Testing import *
# from Merlin.Testing.Property import *  #Merlin 315120 - please do not remove/modify this line
# from Merlin.Testing.TypeSample import *

class PropertyTest(IronPythonTestCase):
    def setUp(self):
        super(PropertyTest, self).setUp()
        self.add_clr_assemblies("propertydefinitions", "typesamples")

    def test_explicitly_implemented_property(self):
        from Merlin.Testing import Flag
        from Merlin.Testing.Property import ClassExplicitlyImplement, ClassExplicitlyReadOnly, IData, IReadOnlyData, IWriteOnlyData, StructExplicitlyImplement, StructExplicitlyWriteOnly
        from Merlin.Testing.TypeSample import SimpleClass, SimpleStruct
        for t in [
                    ClassExplicitlyImplement, 
                    StructExplicitlyImplement,
                ]:
            x = t()

            self.assertTrue(hasattr(x, 'Number'))
            
            d = IData.Number
            d.SetValue(x, 20)
            self.assertEqual(d.GetValue(x), 20)
            
            d.__set__(x, 30)
            self.assertEqual(d.__get__(x), 30)
            
        x = ClassExplicitlyReadOnly()

        d = IReadOnlyData.Number
        self.assertRaisesMessage(SystemError, "cannot set property", lambda: d.SetValue(x, "abc"))
        self.assertEqual(d.GetValue(x), "python")
        #self.assertRaisesMessage(AttributeError, "ddd", lambda: d.__set__(x, "abc"))    # bug 362857
        self.assertEqual(d.__get__(x), "python")
        
        x = StructExplicitlyWriteOnly()
        
        d = IWriteOnlyData.Number
        d.SetValue(x, SimpleStruct(3)); 
        Flag.Check(13)
        self.assertRaisesMessage(AttributeError, "unreadable property", lambda: d.GetValue(x))
        
        d.__set__(x, SimpleStruct(4)); 
        Flag.Check(14)
        self.assertRaisesMessage(AttributeError, "unreadable property", lambda: d.__get__(x))
    
    
    def test_readonly(self):
        from Merlin.Testing import Flag
        from Merlin.Testing.Property import ClassWithReadOnly
        x = ClassWithReadOnly()
        
        self.assertEqual(x.InstanceProperty, 9)