diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj index 2cf1e3776c..10a1a3de86 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj @@ -80,6 +80,7 @@ + @@ -89,6 +90,7 @@ + diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs new file mode 100644 index 0000000000..a317322bf5 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCodeDeserializer.cs @@ -0,0 +1,51 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel.Design; +using System.Reflection; +using IronPython.Compiler.Ast; + +namespace ICSharpCode.PythonBinding +{ + /// + /// Creates objects from python code. + /// + public class PythonCodeDeserializer + { + IDesignerHost designerHost; + const BindingFlags propertyBindingFlags = BindingFlags.Public | BindingFlags.GetField | BindingFlags.Static | BindingFlags.Instance; + + public PythonCodeDeserializer(IDesignerHost designerHost) + { + this.designerHost = designerHost; + } + + /// + /// Creates or gets the object specified in the python AST. + /// + /// + /// Null if the node cannot be deserialized. + /// + public object Deserialize(Node node) + { + if (node == null) { + throw new ArgumentNullException("node"); + } + + PythonControlFieldExpression field = PythonControlFieldExpression.Create(node as MemberExpression); + Type type = designerHost.GetType(PythonControlFieldExpression.GetPrefix(field.FullMemberName)); + if (type != null) { + PropertyInfo propertyInfo = type.GetProperty(field.MemberName, propertyBindingFlags); + if (propertyInfo != null) { + return propertyInfo.GetValue(type, null); + } + } + return null; + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlCursorProperty.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlCursorProperty.cs new file mode 100644 index 0000000000..222071d709 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlCursorProperty.cs @@ -0,0 +1,28 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows.Forms; + +namespace ICSharpCode.PythonBinding +{ + public class PythonControlCursorProperty : PythonControlProperty + { + public PythonControlCursorProperty() + { + } + + public override bool IsDefaultValue(object propertyValue) + { + Cursor cursor = propertyValue as Cursor; + if (cursor != null) { + return cursor == Cursors.Default; + } + return false; + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlDefaultPropertyValues.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlDefaultPropertyValues.cs index 5bfb6425a2..42878943b6 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlDefaultPropertyValues.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlDefaultPropertyValues.cs @@ -30,6 +30,7 @@ namespace ICSharpCode.PythonBinding defaultPropertyValues.Add("DoubleBuffered", new PythonControlBooleanProperty(false)); defaultPropertyValues.Add("ImeMode", new PythonControlImeModeProperty()); defaultPropertyValues.Add("RightToLeft", new PythonControlRightToLeftProperty()); + defaultPropertyValues.Add("Cursor", new PythonControlCursorProperty()); } /// @@ -115,9 +116,6 @@ namespace ICSharpCode.PythonBinding return true; } else if (propertyInfo.Name == "VerticalScroll") { return true; - } else if (propertyInfo.Name == "Cursor") { - // Cursors.Default - return true; } else if (propertyInfo.Name == "Font") { // Default is Control.DefaultFont return true; diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs index 2a57b161bb..64d618179e 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs @@ -29,10 +29,16 @@ namespace ICSharpCode.PythonBinding this.fullMemberName = fullMemberName; } + /// + /// From a member expression of the form: self._textBox1.Name this property will return "Name". + /// public string MemberName { get { return memberName; } } + /// + /// From a member expression of the form: self._textBox1.Name this property will return "self._textBox1.Name". + /// public string FullMemberName { get { return fullMemberName; } } @@ -70,6 +76,19 @@ namespace ICSharpCode.PythonBinding } return name; } + + /// + /// From a name such as "System.Windows.Forms.Cursors.AppStarting" this method returns: + /// "System.Windows.Forms.Cursors" + /// + public static string GetPrefix(string name) + { + int index = name.LastIndexOf('.'); + if (index > 0) { + return name.Substring(0, index); + } + return name; + } /// /// Gets the variable name of the control being added. diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs index b6950e7ade..b590d1991f 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs @@ -91,7 +91,7 @@ namespace ICSharpCode.PythonBinding { // Create designer root object. this.serializationManager = serializationManager; - PythonFormWalker visitor = new PythonFormWalker(this); + PythonFormWalker visitor = new PythonFormWalker(this, base.LoaderHost); visitor.CreateForm(generator.ViewContent.DesignerCodeFileContent); } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs index 8f283743ae..314eaec585 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs @@ -143,7 +143,7 @@ namespace ICSharpCode.PythonBinding /// void AppendProperty(object obj, PropertyDescriptor propertyDescriptor) { - if (propertyDescriptor.Name == "RightToLeft") { + if (propertyDescriptor.Name == "Cursor") { Console.WriteLine("ImeMode"); } object propertyValue = propertyDescriptor.GetValue(obj); diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs index a0bc969093..717bd723d5 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.ComponentModel.Design; using System.Drawing; using System.Reflection; using System.Text; @@ -28,10 +29,12 @@ namespace ICSharpCode.PythonBinding bool walkingAssignment; Dictionary createdObjects = new Dictionary(); string formName = String.Empty; + PythonCodeDeserializer deserializer; - public PythonFormWalker(IComponentCreator componentCreator) + public PythonFormWalker(IComponentCreator componentCreator, IDesignerHost designerHost) { this.componentCreator = componentCreator; + deserializer = new PythonCodeDeserializer(designerHost); } /// @@ -78,8 +81,11 @@ namespace ICSharpCode.PythonBinding MemberExpression rhsMemberExpression = node.Right as MemberExpression; if (rhsMemberExpression != null) { - string name = PythonControlFieldExpression.GetMemberName(rhsMemberExpression); - SetPropertyValue(fieldExpression.MemberName, name); + object propertyValue = deserializer.Deserialize(rhsMemberExpression); + if (propertyValue == null) { + propertyValue = PythonControlFieldExpression.GetMemberName(rhsMemberExpression); + } + SetPropertyValue(fieldExpression.MemberName, propertyValue); } else { walkingAssignment = true; node.Right.Walk(this); @@ -174,8 +180,8 @@ namespace ICSharpCode.PythonBinding if (propertyDescriptor.PropertyType != propertyValue.GetType()) { if (propertyDescriptor.PropertyType.IsEnum) { return Enum.Parse(propertyDescriptor.PropertyType, GetUnqualifiedEnumValue(propertyValue as String)); - } - return Convert.ChangeType(propertyValue, propertyDescriptor.PropertyType); + } + return propertyDescriptor.Converter.ConvertFrom(propertyValue); } return propertyValue; } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs index 77eda84b84..23a378d694 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs @@ -8,6 +8,7 @@ using System; using System.Drawing; using System.Windows.Forms; +using System.Reflection; namespace ICSharpCode.PythonBinding { @@ -39,8 +40,21 @@ namespace ICSharpCode.PythonBinding return size.GetType().FullName + "(" + size.Width + ", " + size.Height + ")"; } else if (propertyType.IsEnum) { return propertyType.FullName + "." + propertyValue.ToString(); + } else if (propertyType == typeof(Cursor)) { + return GetCursorToString(propertyValue as Cursor); } return propertyValue.ToString(); } + + static string GetCursorToString(Cursor cursor) + { + foreach (PropertyInfo propertyInfo in typeof(Cursors).GetProperties(BindingFlags.Public | BindingFlags.Static)) { + Cursor standardCursor = (Cursor)propertyInfo.GetValue(null, null); + if (standardCursor == cursor) { + return typeof(Cursors).FullName + "." + propertyInfo.Name; + } + } + return String.Empty; + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/CursorTypeResolutionTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/CursorTypeResolutionTestFixture.cs new file mode 100644 index 0000000000..a4e026f299 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/CursorTypeResolutionTestFixture.cs @@ -0,0 +1,66 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using IronPython.Compiler.Ast; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + /// + /// Tests that the string "System.Windows.Forms.Cursors.AppStarting" can be resolved by the + /// PythonCodeDeserializer. + /// + [TestFixture] + public class CursorTypeResolutionTestFixture + { + string pythonCode = "self.Cursors = System.Windows.Forms.Cursors.AppStarting"; + Node rhsAssignmentNode; + object obj; + MockDesignerLoaderHost mockDesignerLoaderHost; + MockTypeResolutionService typeResolutionService; + + [TestFixtureSetUp] + public void SetUpFixture() + { + PythonParser parser = new PythonParser(); + PythonAst ast = parser.CreateAst(@"snippet.py", pythonCode); + SuiteStatement suiteStatement = (SuiteStatement)ast.Body; + AssignmentStatement assignment = suiteStatement.Statements[0] as AssignmentStatement; + rhsAssignmentNode = assignment.Right; + + mockDesignerLoaderHost = new MockDesignerLoaderHost(); + typeResolutionService = mockDesignerLoaderHost.TypeResolutionService; + PythonCodeDeserializer deserializer = new PythonCodeDeserializer(mockDesignerLoaderHost); + obj = deserializer.Deserialize(rhsAssignmentNode); + } + + [Test] + public void RhsAssignmentNodeExists() + { + Assert.IsNotNull(rhsAssignmentNode); + } + + [Test] + public void DeserializedObjectIsCursorsAppStarting() + { + Assert.AreEqual(Cursors.AppStarting, obj); + } + + [Test] + public void CursorsTypeResolved() + { + Assert.AreEqual("System.Windows.Forms.Cursors", typeResolutionService.LastTypeNameResolved); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateCursorFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateCursorFormTestFixture.cs new file mode 100644 index 0000000000..727ce358cb --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateCursorFormTestFixture.cs @@ -0,0 +1,53 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Drawing; +using System.Windows.Forms; +using ICSharpCode.PythonBinding; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + [TestFixture] + public class GenerateCursorFormTestFixture + { + string generatedPythonCode; + + [TestFixtureSetUp] + public void SetUpFixture() + { + using (Form form = new Form()) { + form.Name = "MainForm"; + form.ClientSize = new Size(284, 264); + form.Cursor = Cursors.Help; + + string indentString = " "; + PythonForm pythonForm = new PythonForm(indentString); + generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form); + } + } + + [Test] + public void GeneratedCode() + { + string expectedCode = "def InitializeComponent(self):\r\n" + + " self.SuspendLayout()\r\n" + + " # \r\n" + + " # MainForm\r\n" + + " # \r\n" + + " self.ClientSize = System.Drawing.Size(284, 264)\r\n" + + " self.Cursor = System.Windows.Forms.Cursors.Help\r\n" + + " self.Name = \"MainForm\"\r\n" + + " self.ResumeLayout(False)\r\n" + + " self.PerformLayout()\r\n"; + + Assert.AreEqual(expectedCode, generatedPythonCode); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IsDefaultPropertyValueTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IsDefaultPropertyValueTests.cs index 876e957aec..daff1d4a76 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IsDefaultPropertyValueTests.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/IsDefaultPropertyValueTests.cs @@ -110,5 +110,19 @@ namespace PythonBinding.Tests.Designer Assert.IsTrue(defaultPropertyValues.IsDefaultValue("DoubleBuffered", form)); } + + [Test] + public void CursorDefaultIsCursorsDefault() + { + form.Cursor = Cursors.Default; + Assert.IsTrue(defaultPropertyValues.IsDefaultValue("Cursor", form)); + } + + [Test] + public void HelpCursorIsNotDefaultValue() + { + form.Cursor = Cursors.Help; + Assert.IsFalse(defaultPropertyValues.IsDefaultValue("Cursor", form)); + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadAccessibleRoleTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadAccessibleRoleTestFixture.cs index 5a0f688914..2dc3836612 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadAccessibleRoleTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadAccessibleRoleTestFixture.cs @@ -34,7 +34,7 @@ namespace PythonBinding.Tests.Designer [TestFixtureSetUp] public void SetUpFixture() { - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); form = walker.CreateForm(pythonCode); } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadCursorTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadCursorTestFixture.cs new file mode 100644 index 0000000000..2a38166251 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadCursorTestFixture.cs @@ -0,0 +1,53 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Windows.Forms; + +using ICSharpCode.PythonBinding; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + [TestFixture] + public class LoadCursorTestFixture : LoadFormTestFixtureBase + { + string pythonCode = "class TestForm(System.Windows.Forms.Form):\r\n" + + " def InitializeComponent(self):\r\n" + + " self.SuspendLayout()\r\n" + + " # \r\n" + + " # TestForm\r\n" + + " # \r\n" + + " self.Cursor = System.Windows.Forms.Cursors.Hand\r\n" + + " self.Name = \"TestForm\"\r\n" + + " self.ResumeLayout(False)\r\n"; + Form form; + + [TestFixtureSetUp] + public void SetUpFixture() + { + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); + form = walker.CreateForm(pythonCode); + } + + [TestFixtureTearDown] + public void TearDownFixture() + { + form.Dispose(); + } + + [Test] + public void FormCursorIsHand() + { + Assert.AreEqual(Cursors.Hand, form.Cursor); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormWithBooleanPropertiesSetTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormWithBooleanPropertiesSetTestFixture.cs index c2b5f460b8..643470c7b3 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormWithBooleanPropertiesSetTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormWithBooleanPropertiesSetTestFixture.cs @@ -35,7 +35,7 @@ namespace PythonBinding.Tests.Designer [TestFixtureSetUp] public void SetUpFixture() { - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); form = walker.CreateForm(pythonCode); } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadSimpleFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadSimpleFormTestFixture.cs index f17222e3f7..698b875cc9 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadSimpleFormTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadSimpleFormTestFixture.cs @@ -37,7 +37,7 @@ namespace PythonBinding.Tests.Designer [TestFixtureSetUp] public void SetUpFixture() { - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); form = walker.CreateForm(pythonCode); if (CreatedComponents.Count > 0) { diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxTestFixture.cs index ca960c39b7..f5d15e662d 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadTextBoxTestFixture.cs @@ -41,7 +41,7 @@ namespace PythonBinding.Tests.Designer [TestFixtureSetUp] public void SetUpFixture() { - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); form = walker.CreateForm(pythonCode); if (form.Controls.Count > 0) { textBox = form.Controls[0] as TextBox; diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs index 9b53443c29..f57cf815d3 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs @@ -38,7 +38,7 @@ namespace PythonBinding.Tests.Designer [ExpectedException(typeof(PythonFormWalkerException))] public void PythonFormWalkerExceptionThrown() { - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); walker.CreateForm(pythonCode); Assert.Fail("Exception should have been thrown before this."); } @@ -50,7 +50,7 @@ namespace PythonBinding.Tests.Designer public void ClassWithNoBody() { ClassDefinition classDef = new ClassDefinition(new SymbolId(10), null, null); - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); walker.Walk(classDef); } @@ -63,7 +63,7 @@ namespace PythonBinding.Tests.Designer { List lhs = new List(); AssignmentStatement assign = new AssignmentStatement(lhs.ToArray(), null); - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); walker.Walk(assign); } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeDeserializerTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeDeserializerTests.cs new file mode 100644 index 0000000000..6d125ae1fe --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonCodeDeserializerTests.cs @@ -0,0 +1,58 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.PythonBinding; +using IronPython.Compiler.Ast; +using NUnit.Framework; +using PythonBinding.Tests.Utils; + +namespace PythonBinding.Tests.Designer +{ + [TestFixture] + public class PythonCodeDeserializerTests + { + PythonCodeDeserializer deserializer; + + [TestFixtureSetUp] + public void SetUpFixture() + { + deserializer = new PythonCodeDeserializer(new MockDesignerLoaderHost()); + } + + [Test] + [ExpectedException(typeof(ArgumentNullException))] + public void NullIronPythonAstNode() + { + deserializer.Deserialize(null); + } + + [Test] + public void UnknownTypeName() + { + string pythonCode = "self.Cursors = System.Windows.Forms.UnknownType.AppStarting"; + PythonParser parser = new PythonParser(); + PythonAst ast = parser.CreateAst(@"snippet.py", pythonCode); + SuiteStatement suiteStatement = (SuiteStatement)ast.Body; + AssignmentStatement assignment = suiteStatement.Statements[0] as AssignmentStatement; + + Assert.IsNull(deserializer.Deserialize(assignment.Right)); + } + + [Test] + public void UnknownPropertyName() + { + string pythonCode = "self.Cursors = System.Windows.Forms.Cursors.UnknownCursorsProperty"; + PythonParser parser = new PythonParser(); + PythonAst ast = parser.CreateAst(@"snippet.py", pythonCode); + SuiteStatement suiteStatement = (SuiteStatement)ast.Body; + AssignmentStatement assignment = suiteStatement.Statements[0] as AssignmentStatement; + + Assert.IsNull(deserializer.Deserialize(assignment.Right)); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs index 4688afefba..e10a085b84 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs @@ -51,10 +51,10 @@ namespace PythonBinding.Tests.Designer // Begin load. mockDesignerLoaderHost = new MockDesignerLoaderHost(); + mockTypeResolutionService = mockDesignerLoaderHost.TypeResolutionService; + mockExtenderProviderService = new MockExtenderProviderService(); mockDesignerLoaderHost.AddService(typeof(IExtenderProviderService), mockExtenderProviderService); - mockTypeResolutionService = new MockTypeResolutionService(); - mockDesignerLoaderHost.AddService(typeof(ITypeResolutionService), mockTypeResolutionService); System.Console.WriteLine("Before BeginLoad"); loader.BeginLoad(mockDesignerLoaderHost); System.Console.WriteLine("After BeginLoad"); diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/TextBoxNotAddedToFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/TextBoxNotAddedToFormTestFixture.cs index 3cd170e0db..21e0871a40 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/TextBoxNotAddedToFormTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/TextBoxNotAddedToFormTestFixture.cs @@ -45,7 +45,7 @@ namespace PythonBinding.Tests.Designer [TestFixtureSetUp] public void SetUpFixture() { - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); form = walker.CreateForm(pythonCode); } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/UnknownTypeTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/UnknownTypeTestFixture.cs index d5e70dc5a7..a83ed74b22 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/UnknownTypeTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/UnknownTypeTestFixture.cs @@ -38,7 +38,7 @@ namespace PythonBinding.Tests.Designer [ExpectedException(typeof(PythonFormWalkerException))] public void PythonFormWalkerExceptionThrown() { - PythonFormWalker walker = new PythonFormWalker(this); + PythonFormWalker walker = new PythonFormWalker(this, new MockDesignerLoaderHost()); walker.CreateForm(pythonCode); Assert.Fail("Exception should have been thrown before this."); } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj index f998e5efae..36cf8806b9 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj @@ -145,11 +145,13 @@ + + @@ -160,6 +162,7 @@ + @@ -168,6 +171,7 @@ + diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockDesignerLoaderHost.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockDesignerLoaderHost.cs index 3bc26a63d5..fedf47f70b 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockDesignerLoaderHost.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockDesignerLoaderHost.cs @@ -22,10 +22,12 @@ namespace PythonBinding.Tests.Utils ServiceContainer serviceContainer = new ServiceContainer(); List createdComponents = new List(); IComponent rootComponent; + MockTypeResolutionService typeResolutionService = new MockTypeResolutionService(); public MockDesignerLoaderHost() { AddService(typeof(IServiceContainer), serviceContainer); + AddService(typeof(ITypeResolutionService), typeResolutionService); } public event EventHandler Activated; @@ -43,6 +45,10 @@ namespace PythonBinding.Tests.Utils get { return createdComponents; } } + public MockTypeResolutionService TypeResolutionService { + get { return typeResolutionService; } + } + public bool Loading { get { throw new NotImplementedException(); @@ -128,10 +134,7 @@ namespace PythonBinding.Tests.Utils public Type GetType(string typeName) { System.Console.WriteLine("DesignerLoaderHost.GetType: " + typeName); - if (typeName == "Form") { - return typeof(System.Windows.Forms.Form); - } - return Type.GetType(typeName); + return typeResolutionService.GetType(typeName); } public void AddService(Type serviceType, object serviceInstance) diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockTypeResolutionService.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockTypeResolutionService.cs index 6794eca518..7c056c3d02 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockTypeResolutionService.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockTypeResolutionService.cs @@ -8,6 +8,7 @@ using System; using System.ComponentModel.Design; using System.Reflection; +using System.Windows.Forms; namespace PythonBinding.Tests.Utils { @@ -16,10 +17,19 @@ namespace PythonBinding.Tests.Utils /// public class MockTypeResolutionService : ITypeResolutionService { + string lastTypeNameResolved; + public MockTypeResolutionService() { } + /// + /// Returns the last type name passed to the GetType method. + /// + public string LastTypeNameResolved { + get { return lastTypeNameResolved; } + } + public Assembly GetAssembly(AssemblyName name) { throw new NotImplementedException(); @@ -33,9 +43,16 @@ namespace PythonBinding.Tests.Utils public Type GetType(string name) { System.Console.WriteLine("TypeResolutionService.GetType: " + name); + lastTypeNameResolved = name; if (name == "Form") { - return typeof(System.Windows.Forms.Form); + return typeof(Form); + } + + Type type = typeof(Form).Assembly.GetType(name, false); + if (type != null) { + return type; } + return Type.GetType(name); }