Browse Source

Converting value to POCO types automatically

Sebastien Ros 11 years ago
parent
commit
70f49e9e1d

+ 41 - 1
Jint.Tests/Runtime/InteropTests.cs

@@ -181,10 +181,50 @@ namespace Jint.Tests.Runtime
             ");
         }
 
+        [Fact]
+        public void EcmaValuesAreAutomaticallyConvertedWhenSetInPoco()
+        {
+            var p = new Person
+            {
+                Name = "foo",
+            };
+
+            _engine.SetValue("p", p);
+
+            RunTest(@"
+                assert(p.Name === 'foo');
+                assert(p.Age === 0);
+                p.Name = 'bar';
+                p.Age = 10;
+            ");
+
+            Assert.Equal("bar", p.Name);
+            Assert.Equal(10, p.Age);
+        }
+
+        [Fact]
+        public void EcmaValuesAreAutomaticallyConvertedToBestMatchWhenSetInPoco()
+        {
+            var p = new Person
+            {
+                Name = "foo",
+            };
+
+            _engine.SetValue("p", p);
+
+            RunTest(@"
+                p.Name = 10;
+                p.Age = '20';
+            ");
+
+            Assert.Equal("10", p.Name);
+            Assert.Equal(20, p.Age);
+        }
         public class Person
         {
             public string Name { get; set; }
-
+            public int Age { get; set; }
+            
             public override string ToString()
             {
                 return Name;

+ 12 - 2
Jint/Runtime/Descriptors/Specialized/ClrDataDescriptor.cs

@@ -1,4 +1,6 @@
-using System.Reflection;
+using System;
+using System.Globalization;
+using System.Reflection;
 using Jint.Native;
 
 namespace Jint.Runtime.Descriptors.Specialized
@@ -27,7 +29,15 @@ namespace Jint.Runtime.Descriptors.Specialized
 
             set
             {
-                _propertyInfo.SetValue(_item, value.GetValueOrDefault().ToObject(), null);
+                // attempt to convert the JsValue to the target type
+                // todo: this could be made extensible to support custom type conversion
+                var obj = value.GetValueOrDefault().ToObject();
+                if (obj.GetType() != _propertyInfo.PropertyType)
+                {
+                    obj = Convert.ChangeType(obj, _propertyInfo.PropertyType, CultureInfo.InvariantCulture);
+                }
+                
+                _propertyInfo.SetValue(_item, obj, null);
             }
         }
     }