2010-04-07 Marek Habersack <mhabersack@novell.com>
authorMarek Habersack <grendel@twistedcode.net>
Wed, 7 Apr 2010 13:14:11 +0000 (13:14 -0000)
committerMarek Habersack <grendel@twistedcode.net>
Wed, 7 Apr 2010 13:14:11 +0000 (13:14 -0000)
* Control.cs: control cache must be filled using the local
_controls collection instead of the virtual Controls
property. Fixes bug #594238
Check if _controls isn't null before using it.

2010-04-07  Marek Habersack  <mhabersack@novell.com>

* ControlTest.cs: added test for bug #594238

2010-04-07  Marek Habersack  <mhabersack@novell.com>

* Makefile: moved App_* test resources to separate variables -
whatever is contained in those variables is preprocessed before
embedding as resource to include appropriate resource name prefix
(App_Code/, App_GlobalResources/ for now). This is used in WebTest
to automatically populate the relevant directories when running
the test suite.

2010-04-07  Marek Habersack  <mhabersack@novell.com>

* WebTest.cs: introduced concept of prefixed resources and added
an API which handles them - CopyPrefixedResources. All the
manifest resource names are checked for match with the given
prefix, and all the matching ones are copied to the specified
subdirectory of the test directory.

svn path=/trunk/mcs/; revision=154948

mcs/class/System.Web/ChangeLog
mcs/class/System.Web/Makefile
mcs/class/System.Web/System.Web.UI/ChangeLog
mcs/class/System.Web/System.Web.UI/Control.cs
mcs/class/System.Web/Test/System.Web.UI/ChangeLog
mcs/class/System.Web/Test/System.Web.UI/ControlTest.cs
mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/ChangeLog
mcs/class/System.Web/Test/mainsoft/NunitWeb/NunitWeb/WebTest.cs
mcs/class/System.Web/Test/mainsoft/NunitWebResources/App_Code/MyContainer.cs [new file with mode: 0644]
mcs/class/System.Web/Test/mainsoft/NunitWebResources/OverridenControlsPropertyAndPostBack_Bug594238.aspx [new file with mode: 0644]

index 44a1a6b4a0f81e8948c353b3e24e4d49f97f7aa7..a3f6b8668c688c1230c6565d09efd11164332079 100644 (file)
@@ -1,3 +1,12 @@
+2010-04-07  Marek Habersack  <mhabersack@novell.com>
+
+       * Makefile: moved App_* test resources to separate variables -
+       whatever is contained in those variables is preprocessed before
+       embedding as resource to include appropriate resource name prefix
+       (App_Code/, App_GlobalResources/ for now). This is used in WebTest
+       to automatically populate the relevant directories when running
+       the test suite.
+
 2010-02-18  Marek Habersack  <mhabersack@novell.com>
 
        * Makefile (TEST_RESOURCE_FILES): added
index 9c4c88c926c170c3936a4804e10ca793b895cd73..7db50ad0f2989ca455e89d88ef87d409960ebbb0 100644 (file)
@@ -74,6 +74,15 @@ RESOURCE_FILES_2 = \
        System.Web.UI.WebControls/Menu.js
 
 OTHER_RES = $(RESOURCE_FILES_1)
+TEST_APP_CODE_FILES = \
+       Test/mainsoft/NunitWebResources/App_Code/EnumConverterControl.cs \
+       Test/mainsoft/NunitWebResources/App_Code/MyContainer.cs
+
+TEST_APP_GLOBALRESOURCES_FILES = \
+       Test/mainsoft/NunitWebResources/App_GlobalResources/Common.resx \
+       Test/mainsoft/NunitWebResources/App_GlobalResources/Common.fr-FR.resx \
+       Test/mainsoft/NunitWebResources/App_GlobalResources/Resource1.resx
+
 TEST_RESOURCE_FILES = \
        Test/mainsoft/NunitWeb/NunitWeb/Resources/Global.asax \
        Test/mainsoft/NunitWeb/NunitWeb/Resources/My.ashx \
@@ -93,10 +102,6 @@ TEST_RESOURCE_FILES = \
        Test/mainsoft/NunitWeb/NunitWeb/Resources/test_map_07.sitemap \
        Test/mainsoft/NunitWeb/NunitWeb/Resources/test_map_08.sitemap \
        Test/mainsoft/NunitWeb/NunitWeb/Resources/test_map_09.sitemap \
-       Test/mainsoft/NunitWebResources/App_GlobalResources/Common.resx \
-       Test/mainsoft/NunitWebResources/App_GlobalResources/Common.fr-FR.resx \
-       Test/mainsoft/NunitWebResources/App_GlobalResources/Resource1.resx \
-       Test/mainsoft/NunitWebResources/App_Code/EnumConverterControl.cs \
        Test/mainsoft/NunitWebResources/menuclass.aspx \
        Test/mainsoft/NunitWebResources/FormView.aspx \
        Test/mainsoft/NunitWebResources/PostBackMenuTest.aspx \
@@ -208,7 +213,8 @@ TEST_RESOURCE_FILES = \
        Test/mainsoft/NunitWebResources/EnumConverter_Bug578586.aspx \
        Test/mainsoft/NunitWebResources/ButtonColor_Bug325489.aspx \
        Test/mainsoft/NunitWebResources/SqlDataSource_OnInit_Bug572781.aspx \
-       Test/mainsoft/NunitWebResources/FormViewPagerVisibility.aspx
+       Test/mainsoft/NunitWebResources/FormViewPagerVisibility.aspx \
+       Test/mainsoft/NunitWebResources/OverridenControlsPropertyAndPostBack_Bug594238.aspx
 
 RESX_DIST =  resources/TranslationResources.resx
 ifneq (1, $(FRAMEWORK_VERSION_MAJOR))
@@ -216,6 +222,9 @@ RESX_RES = $(RESX_DIST:.resx=.resources)
 endif
 
 NUNIT_RESOURCE_FILES = $(TEST_RESOURCE_FILES)
+NUNIT_APP_CODE_FILES = $(TEST_APP_CODE_FILES)
+NUNIT_APP_GLOBALRESOURCES_FILES = $(TEST_APP_GLOBALRESOURCES_FILES)
+
 ifneq (1, $(FRAMEWORK_VERSION_MAJOR))
 OTHER_RES += $(RESOURCE_FILES_2)
 OTHER_LIB_MCS_FLAGS = -d:INSIDE_SYSTEM_WEB -nowarn:618 -r:System.Configuration.dll -r:Mono.Data.Sqlite.dll
@@ -253,7 +262,11 @@ echo-warning-systemcore:
 endif
 endif
 
-TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -doc:$(test_lib:.dll=.xml) -nowarn:219,169,1591 $(NUNIT_RESOURCE_FILES:%=/resource:%) -r:SystemWebTestShim.dll
+TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -doc:$(test_lib:.dll=.xml) -nowarn:219,169,1591 -r:SystemWebTestShim.dll \
+       $(NUNIT_RESOURCE_FILES:%=/resource:%) \
+       $(foreach file,$(NUNIT_APP_CODE_FILES),$(shell echo $(file) | sed -e 's;\(.*\)/\(.*\);/resource:\1/\2,App_Code/\2 ;g')) \
+       $(foreach file,$(NUNIT_APP_GLOBALRESOURCES_FILES),$(shell echo $(file) | sed -e 's;\(.*\)/\(.*\);/resource:\1/\2,App_GlobalResources/\2 ;g'))
+
 ifeq (net_2_0, $(PROFILE))
 TEST_MCS_FLAGS += -r:System.Web.Extensions.dll
 endif
@@ -262,6 +275,8 @@ EXTRA_DISTFILES = \
        $(RESOURCE_FILES_2) \
        $(RESOURCE_FILES_1) \
        $(TEST_RESOURCE_FILES) \
+       $(TEST_APP_CODE_FILES) \
+       $(TEST_APP_GLOBALRESOURCES_FILES) \
        UplevelHelperDefinitions.xml \
        $(RESX_DIST) \
        SQLiteProviders_DatabaseSchema.sql \
index 508fde1c882d277aeb118861c5c779846ae1d8eb..9cba914bcc6c21e370f5d46924613515f09217bb 100644 (file)
@@ -1,3 +1,10 @@
+2010-04-07  Marek Habersack  <mhabersack@novell.com>
+
+       * Control.cs: control cache must be filled using the local
+       _controls collection instead of the virtual Controls
+       property. Fixes bug #594238
+       Check if _controls isn't null before using it.
+
 2010-04-06  Marek Safar  <marek.safar@gmail.com>
 
        * FileLevelControlBuilderAttribute.cs: Use reference comparison.
index ff8e9075332e14b642d9e8f754e4ff69541c7278..59c13c3127e485822c8d608abe8f761ab9a21383 100644 (file)
@@ -452,8 +452,9 @@ namespace System.Web.UI
                        get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
                        set {
                                if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
-                                       if (_controls != null)
-                                               _controls.Clear ();
+                                       ControlCollection cc = Controls;
+                                       if (cc != null)
+                                               cc.Clear ();
                                }
 
                                SetMask (CHILD_CONTROLS_CREATED, value);
@@ -765,12 +766,15 @@ namespace System.Web.UI
                                return;
 
                        InitControlsCache ();
-                       FillControlCache (Controls);
 
+                       FillControlCache (_controls);
                }
 
                void FillControlCache (ControlCollection controls)
                {
+                       if (controls == null || controls.Count == 0)
+                               return;
+                       
                        foreach (Control c in controls) {
                                try {
                                        if (c._userId != null)
@@ -789,7 +793,7 @@ namespace System.Web.UI
 
                protected bool IsLiteralContent ()
                {
-                       if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
+                       if (_controls != null && _controls.Count == 1 && _controls [0] is LiteralControl)
                                return true;
 
                        return false;
@@ -1044,19 +1048,23 @@ namespace System.Web.UI
                {
                        if (_renderMethodDelegate != null) {
                                _renderMethodDelegate (writer, this);
-                       } else if (_controls != null) {
-                               int len = _controls.Count;
-                               Control c;
-                               for (int i = 0; i < len; i++) {
-                                       c = _controls [i];
-                                       if (c == null)
-                                               continue;
-                                       ControlAdapter tmp = c.Adapter;
-                                       if (tmp != null)
-                                               c.RenderControl (writer, tmp);
-                                       else
-                                               c.RenderControl (writer);
-                               }
+                               return;
+                       }
+
+                       if (_controls == null)
+                               return;
+
+                       int len = _controls.Count;
+                       Control c;
+                       for (int i = 0; i < len; i++) {
+                               c = _controls [i];
+                               if (c == null)
+                                       continue;
+                               ControlAdapter tmp = c.Adapter;
+                               if (tmp != null)
+                                       c.RenderControl (writer, tmp);
+                               else
+                                       c.RenderControl (writer);
                        }
                }
 
@@ -1178,7 +1186,7 @@ namespace System.Web.UI
                        if (!HasControls ())
                                return;
 
-                       int len = _controls.Count;
+                       int len = _controls != null ? _controls.Count : 0;
                        for (int i = 0; i < len; i++) {
                                Control c = _controls [i];
                                c.DataBind ();
@@ -1189,7 +1197,7 @@ namespace System.Web.UI
                {
                        return (_controls != null && _controls.Count > 0);
                }
-
+               
                public virtual void RenderControl (HtmlTextWriter writer)
                {
                        if (this.adapter != null) {
@@ -1341,12 +1349,10 @@ namespace System.Web.UI
                                Adapter.OnLoad (EventArgs.Empty);
                        else
                                OnLoad (EventArgs.Empty);
-                       if (HasControls ()) {
-                               int len = _controls.Count;
-                               for (int i = 0; i < len; i++) {
-                                       Control c = _controls [i];
-                                       c.LoadRecursive ();
-                               }
+                       int ccount = _controls != null ? _controls.Count : 0;
+                       for (int i = 0; i < ccount; i++) {
+                               Control c = _controls [i];
+                               c.LoadRecursive ();
                        }
 
 #if MONO_TRACE
@@ -1366,12 +1372,10 @@ namespace System.Web.UI
                                trace.Write ("control", String.Concat ("UnloadRecursive ", _userId, " ", type_name));
                        }
 #endif
-                       if (HasControls ()) {
-                               int len = _controls.Count;
-                               for (int i = 0; i < len; i++) {
-                                       Control c = _controls [i];
-                                       c.UnloadRecursive (dispose);
-                               }
+                       int ccount = _controls != null ? _controls.Count : 0;
+                       for (int i = 0; i < ccount; i++) {
+                               Control c = _controls [i];
+                               c.UnloadRecursive (dispose);
                        }
 
 #if MONO_TRACE
@@ -1410,7 +1414,7 @@ namespace System.Web.UI
                                if (!HasControls ())
                                        return;
 
-                               int len = _controls.Count;
+                               int len = _controls != null ? _controls.Count : 0;
                                for (int i = 0; i < len; i++) {
                                        Control c = _controls [i];
                                        c.PreRenderRecursiveInternal ();
@@ -1441,7 +1445,7 @@ namespace System.Web.UI
                                if ((stateMask & IS_NAMING_CONTAINER) != 0)
                                        namingContainer = this;
 
-                               int len = _controls.Count;
+                               int len = _controls != null ? _controls.Count : 0;
                                for (int i = 0; i < len; i++) {
                                        Control c = _controls [i];
                                        c.InitRecursive (namingContainer);
@@ -1481,7 +1485,7 @@ namespace System.Web.UI
                        ArrayList controlStates = null;
                        bool byId = LoadViewStateByID;
                        if (HasControls ()) {
-                               int len = _controls.Count;
+                               int len = _controls != null ? _controls.Count : 0;
                                for (int i = 0; i < len; i++) {
                                        Control ctrl = _controls [i];
                                        object ctrlState = ctrl.SaveViewStateRecursive ();
index 1e6a577df86bd991e66b51c11dd994ffa88e1e52..2c4b89c477d2a8c7736b8597511f4c02ace5de01 100644 (file)
@@ -1,3 +1,7 @@
+2010-04-07  Marek Habersack  <mhabersack@novell.com>
+
+       * ControlTest.cs: added test for bug #594238
+
 2009-12-18  Marek Habersack  <mhabersack@novell.com>
 
        * ObjectStateFormatterTest.cs: added.
index e52699b5137f39b97ef0255784910e39902d0c1e..9da9eaed5c0e95e8f5d22469a86c77017c05d9e0 100644 (file)
@@ -39,6 +39,7 @@ using System.Web;
 using System.Web.UI;
 using System.Web.UI.WebControls;
 using MonoTests.SystemWeb.Framework;
+using MonoTests.stand_alone.WebHarness;
 
 #if NET_2_0
 using System.Web.UI.Adapters;
@@ -978,6 +979,26 @@ namespace MonoTests.System.Web.UI
                }
 
 #if NET_2_0
+               [Test (Description="Bug #594238")]
+               public void OverridenControlsPropertyAndPostBack_Bug594238 ()
+               {
+                       WebTest t = new WebTest ("OverridenControlsPropertyAndPostBack_Bug594238.aspx");
+                       t.Run ();
+
+                       FormRequest fr = new FormRequest (t.Response, "form1");
+                       fr.Controls.Add ("__EVENTTARGET");
+                       fr.Controls.Add ("__EVENTARGUMENT");
+                       fr.Controls ["__EVENTTARGET"].Value = "container$children$lb";
+                       fr.Controls ["__EVENTARGUMENT"].Value = String.Empty;
+                       t.Request = fr;
+
+                       string originalHtml = @"<span id=""container""><a href=""javascript:__doPostBack('container$children$lb','')"" id=""container_children_lb"">Woot! I got clicked!</a></span><hr/>";
+                       string pageHtml = t.Run ();
+                       string renderedHtml = HtmlDiff.GetControlFromPageHtml (pageHtml);
+
+                       HtmlDiff.AssertAreEqual (originalHtml, renderedHtml, "#A1");
+               }
+               
                [TestFixtureTearDown]
                public void Tear_down ()
                {
@@ -989,6 +1010,7 @@ namespace MonoTests.System.Web.UI
                {
                        WebTest.CopyResource (GetType (), "ResolveUrl.aspx", "ResolveUrl.aspx");
                        WebTest.CopyResource (GetType (), "ResolveUrl.ascx", "Folder/ResolveUrl.ascx");
+                       WebTest.CopyResource (GetType (), "OverridenControlsPropertyAndPostBack_Bug594238.aspx", "OverridenControlsPropertyAndPostBack_Bug594238.aspx");
                }
 
 #endif
index 125a21bbc9f56847b37ee585ebd8b3d19841767a..e1f8ed657cea743edbaa1789cc20f54bd61b7547 100644 (file)
@@ -1,3 +1,11 @@
+2010-04-07  Marek Habersack  <mhabersack@novell.com>
+
+       * WebTest.cs: introduced concept of prefixed resources and added
+       an API which handles them - CopyPrefixedResources. All the
+       manifest resource names are checked for match with the given
+       prefix, and all the matching ones are copied to the specified
+       subdirectory of the test directory.
+
 2010-02-11  Marek Habersack  <mhabersack@novell.com>
 
        * WebTest.cs: test environment setup enhancements. Contributed by
index 223f21ccded2b396a5b86779add7fce9ee692022..152b15fe79043ebfe3a38aa711446a6382f331be 100644 (file)
@@ -302,6 +302,8 @@ namespace MonoTests.SystemWeb.Framework
                /// <example><code>CopyResource (GetType (), "Default.skin", "App_Themes/Black/Default.skin");</code></example>
                public static void CopyResource (Type type, string resourceName, string targetUrl)
                {
+                       if (type == null)
+                               throw new ArgumentNullException ("type");
 #if !TARGET_JVM
                        using (Stream source = type.Assembly.GetManifestResourceStream (resourceName)) {
                                if (source == null)
@@ -313,6 +315,26 @@ namespace MonoTests.SystemWeb.Framework
 #endif
                }
 
+               public static void CopyPrefixedResources (Type type, string namePrefix, string targetDir)
+               {
+                       if (type == null)
+                               throw new ArgumentNullException ("type");
+                       
+                       string[] manifestResources = type.Assembly.GetManifestResourceNames ();
+                       if (manifestResources == null || manifestResources.Length == 0)
+                               return;
+
+                       foreach (string resource in manifestResources) {
+                               if (resource == null || resource.Length == 0)
+                                       continue;
+                               
+                               if (!resource.StartsWith (namePrefix))
+                                       continue;
+                               
+                               CopyResource (type, resource, Path.Combine (targetDir, resource.Substring (namePrefix.Length)));
+                       }
+               }
+               
                /// <summary>
                /// Copy a chunk of data as a file into the web application.
                /// </summary>
@@ -570,23 +592,23 @@ namespace MonoTests.SystemWeb.Framework
 
                public static void CopyResources ()
                {
-                       CopyResource (typeof (WebTest), "My.ashx", "My.ashx");
-                       CopyResource (typeof (WebTest), "Global.asax", "Global.asax");
+                       Type myself = typeof (WebTest);
+                       
+                       CopyResource (myself, "My.ashx", "My.ashx");
+                       CopyResource (myself, "Global.asax", "Global.asax");
 #if NET_2_0
 #if INSIDE_SYSTEM_WEB
-                       CopyResource (typeof (WebTest), "Common.resx", "App_GlobalResources/Common.resx");
-                       CopyResource (typeof (WebTest), "Common.fr-FR.resx", "App_GlobalResources/Common.fr-FR.resx");
-                       CopyResource (typeof (WebTest), "Resource1.resx", "App_GlobalResources/Resource1.resx");
-                       CopyResource (typeof (WebTest), "EnumConverterControl.cs", "App_Code/EnumConverterControl.cs");
+                       CopyPrefixedResources (myself, "App_GlobalResources/", "App_GlobalResources");
+                       CopyPrefixedResources (myself, "App_Code/", "App_Code");
 #endif
-                       CopyResource (typeof (WebTest), "Web.mono.config", "Web.config");
+                       CopyResource (myself, "Web.mono.config", "Web.config");
 #else
-                       CopyResource (typeof (WebTest), "Web.mono.config.1.1", "Web.config");
+                       CopyResource (myself, "Web.mono.config.1.1", "Web.config");
 #endif
-                       CopyResource (typeof (WebTest), "MyPage.aspx", "MyPage.aspx");
-                       CopyResource (typeof (WebTest), "MyPage.aspx.cs", "MyPage.aspx.cs");
-                       CopyResource (typeof (WebTest), "MyPageWithMaster.aspx", "MyPageWithMaster.aspx");
-                       CopyResource (typeof (WebTest), "My.master", "My.master");
+                       CopyResource (myself, "MyPage.aspx", "MyPage.aspx");
+                       CopyResource (myself, "MyPage.aspx.cs", "MyPage.aspx.cs");
+                       CopyResource (myself, "MyPageWithMaster.aspx", "MyPageWithMaster.aspx");
+                       CopyResource (myself, "My.master", "My.master");
                }
 #endif
        }
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/App_Code/MyContainer.cs b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/App_Code/MyContainer.cs
new file mode 100644 (file)
index 0000000..a2a9c1f
--- /dev/null
@@ -0,0 +1,36 @@
+// Bug #594238
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+namespace TestNamedHolders
+{
+       public class MyContainer : WebControl, INamingContainer
+       {
+               Control whereTheChildrenPlay;
+               
+               // can't do this if it is an INamingContainer
+               public override ControlCollection Controls 
+               {
+                       get { return whereTheChildrenPlay.Controls;     }
+               }
+               
+               public MyContainer()
+               {
+                       whereTheChildrenPlay = new Content();
+                       whereTheChildrenPlay.ID = "children";
+               }
+
+               protected override void OnLoad (EventArgs e)
+               {
+                       base.OnLoad (e);
+                       
+                       // would normally put other stuff here
+                       
+                       base.Controls.Add(whereTheChildrenPlay);
+
+                       // and possibly here
+               }
+
+       }
+}
diff --git a/mcs/class/System.Web/Test/mainsoft/NunitWebResources/OverridenControlsPropertyAndPostBack_Bug594238.aspx b/mcs/class/System.Web/Test/mainsoft/NunitWebResources/OverridenControlsPropertyAndPostBack_Bug594238.aspx
new file mode 100644 (file)
index 0000000..7d361d7
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<%@ Page Language="C#" CodeFile="MyPage.aspx.cs" Inherits="MyPage" %>
+<%@ Register Assembly="App_Code" Namespace="TestNamedHolders" TagPrefix="tnh" %>
+<script runat="server">
+       protected override void OnLoad (EventArgs e)
+       {
+               base.OnLoad (e);
+               LinkButton lb = new LinkButton();
+               lb.ID = "lb";
+               lb.Text = "Click me!";
+               lb.Click += delegate {
+                       lb.Text = "Woot! I got clicked!";
+               };
+               this.container.Controls.Add(lb);
+       }
+</script>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+       <title>Default</title>
+</head>
+<body>
+       <form id="form1" runat="server">
+       <div>
+               <%= MonoTests.stand_alone.WebHarness.HtmlDiff.BEGIN_TAG %><tnh:MyContainer id="container" runat="server">
+               </tnh:MyContainer><hr/><%= MonoTests.stand_alone.WebHarness.HtmlDiff.END_TAG %>
+       </div>
+       </form>
+</body>
+</html>
\ No newline at end of file