Back to index

lightning-sunbird  0.9+nobinonly
TestUICommandCollector.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* vim:set ts=2 sw=2 sts=2 et cindent: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is the Metrics extension.
00017  *
00018  * The Initial Developer of the Original Code is Google Inc.
00019  * Portions created by the Initial Developer are Copyright (C) 2007
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *  Brian Ryner <bryner@gmail.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 // Unit test for nsUICommandCollector
00040 
00041 #include <stdio.h>
00042 
00043 #include "TestCommon.h"
00044 #include "nsXPCOM.h"
00045 #include "nsCOMPtr.h"
00046 #include "nsAutoPtr.h"
00047 #include "nsIDOMDocument.h"
00048 #include "nsIDOMDocumentEvent.h"
00049 #include "nsIDOMElement.h"
00050 #include "nsIDOMEvent.h"
00051 #include "nsIDOMEventTarget.h"
00052 #include "nsIDOMText.h"
00053 #include "nsIDOMXULCommandEvent.h"
00054 #include "nsIPrivateDOMEvent.h"
00055 #include "nsComponentManagerUtils.h"
00056 #include "nsUICommandCollector.h"
00057 #include "nsMetricsService.h"
00058 
00059 // This is a little unconventional, but it lets us register the metrics
00060 // components statically so that they can initialize properly in the test
00061 // environment, while still allowing us access to non-interface methods.
00062 #include "nsMetricsModule.cpp"
00063 
00064 static int gTotalTests = 0;
00065 static int gPassedTests = 0;
00066 
00067 class UICommandCollectorTest
00068 {
00069  public:
00070   UICommandCollectorTest() {}
00071   ~UICommandCollectorTest() {}
00072 
00073   void SetUp();
00074   void TestGetEventTargets();
00075   void TestGetEventKeyId();
00076 
00077  private:
00078   nsRefPtr<nsUICommandCollector> mCollector;
00079   nsCOMPtr<nsIDOMDocument> mDocument;
00080   nsCOMPtr<nsIPrivateDOMEvent> mDOMEvent;
00081   nsString kXULNS;
00082 };
00083 
00084 void UICommandCollectorTest::SetUp()
00085 {
00086   ++gTotalTests;
00087   mCollector = new nsUICommandCollector();
00088   mDocument = do_CreateInstance("@mozilla.org/xml/xml-document;1");
00089   kXULNS.Assign(NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"));
00090 }
00091 
00092 void UICommandCollectorTest::TestGetEventTargets()
00093 {
00094   nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(mDocument);
00095   nsCOMPtr<nsIDOMEvent> event;
00096   docEvent->CreateEvent(NS_LITERAL_STRING("xulcommandevents"),
00097                         getter_AddRefs(event));
00098 
00099   // The private event interface lets us directly set the target
00100   // and original target for easier testing.
00101   nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
00102   ASSERT_TRUE(privateEvent);
00103 
00104   nsCOMPtr<nsIDOMElement> buttonElement;
00105   mDocument->CreateElementNS(kXULNS, NS_LITERAL_STRING("button"),
00106                             getter_AddRefs(buttonElement));
00107   ASSERT_TRUE(buttonElement);
00108   buttonElement->SetAttribute(NS_LITERAL_STRING("id"),
00109                               NS_LITERAL_STRING("btn1"));
00110 
00111   // First test the simple case where we have only explicit content.
00112   // Note that originalTarget == target unless set otherwise.
00113   privateEvent->SetTarget(
00114       nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(buttonElement)));
00115 
00116   nsString targetId, targetAnonId;
00117   nsresult rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
00118   ASSERT_TRUE(NS_SUCCEEDED(rv));
00119   ASSERT_TRUE(targetId.Equals(NS_LITERAL_STRING("btn1")));
00120   ASSERT_TRUE(targetAnonId.IsEmpty());
00121 
00122   // If there was an anonid, it should be ignored
00123   buttonElement->SetAttribute(NS_LITERAL_STRING("anonid"),
00124                               NS_LITERAL_STRING("abc"));
00125   rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
00126   ASSERT_TRUE(NS_SUCCEEDED(rv));
00127   ASSERT_TRUE(targetId.Equals(NS_LITERAL_STRING("btn1")));
00128   ASSERT_TRUE(targetAnonId.IsEmpty());
00129 
00130   // If the target has no id, GetEventTargets should fail
00131   buttonElement->RemoveAttribute(NS_LITERAL_STRING("id"));
00132   rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
00133   ASSERT_TRUE(NS_FAILED(rv));
00134 
00135   // The same should be true with no anonid
00136   buttonElement->RemoveAttribute(NS_LITERAL_STRING("anonid"));
00137   rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
00138   ASSERT_TRUE(NS_FAILED(rv));
00139 
00140   // Empty attributes should work the same as no attributes
00141   buttonElement->SetAttribute(NS_LITERAL_STRING("id"), nsString());
00142   rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
00143   ASSERT_TRUE(NS_FAILED(rv));
00144 
00145   // Now test some cases where the originalTarget is different
00146   nsCOMPtr<nsIDOMElement> anonChild;
00147   mDocument->CreateElementNS(kXULNS, NS_LITERAL_STRING("hbox"),
00148                             getter_AddRefs(anonChild));
00149   ASSERT_TRUE(anonChild);
00150 
00151   privateEvent->SetOriginalTarget(
00152       nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(anonChild)));
00153 
00154   // This is the typical id/anonid case for anonymous content
00155   buttonElement->SetAttribute(NS_LITERAL_STRING("id"),
00156                               NS_LITERAL_STRING("btn1"));
00157   anonChild->SetAttribute(NS_LITERAL_STRING("anonid"),
00158                           NS_LITERAL_STRING("box1"));
00159   targetId.SetLength(0);
00160   targetAnonId.SetLength(0);
00161   rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
00162   ASSERT_TRUE(NS_SUCCEEDED(rv));
00163   ASSERT_TRUE(targetId.Equals(NS_LITERAL_STRING("btn1")));
00164   ASSERT_TRUE(targetAnonId.Equals(NS_LITERAL_STRING("box1")));
00165 
00166   // If there is no id or anonid, it should fail
00167   anonChild->RemoveAttribute(NS_LITERAL_STRING("anonid"));
00168   rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
00169   ASSERT_TRUE(NS_FAILED(rv));
00170 
00171   // Test the failure case where the target/originalTarget is not an element
00172   privateEvent->SetOriginalTarget(nsnull);  // now mirrors target again
00173   nsCOMPtr<nsIDOMText> textNode;
00174   mDocument->CreateTextNode(NS_LITERAL_STRING("blah"),
00175                            getter_AddRefs(textNode));
00176   ASSERT_TRUE(textNode);
00177   privateEvent->SetTarget(
00178       nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(textNode)));
00179   rv = mCollector->GetEventTargets(event, targetId, targetAnonId);
00180   ASSERT_TRUE(NS_FAILED(rv));
00181 
00182   ++gPassedTests;
00183 }
00184 
00185 void UICommandCollectorTest::TestGetEventKeyId()
00186 {
00187   nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(mDocument);
00188   nsCOMPtr<nsIDOMEvent> event;
00189   docEvent->CreateEvent(NS_LITERAL_STRING("xulcommandevents"),
00190                         getter_AddRefs(event));
00191 
00192   // The private event interface lets us directly set the target
00193   // and original target for easier testing.
00194   nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
00195   ASSERT_TRUE(privateEvent);
00196 
00197   nsCOMPtr<nsIDOMElement> elem;
00198   mDocument->CreateElementNS(kXULNS, NS_LITERAL_STRING("hbox"),
00199                              getter_AddRefs(elem));
00200   ASSERT_TRUE(elem);
00201 
00202   privateEvent->SetTarget(
00203       nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(elem)));
00204 
00205   // In its initial state, the command event will have no source event.
00206   // GetEventKeyId should leave keyId empty.
00207   nsString keyId;
00208   mCollector->GetEventKeyId(event, keyId);
00209   ASSERT_TRUE(keyId.IsEmpty());
00210 
00211   // Now set up a source event
00212   nsCOMPtr<nsIDOMEvent> sourceEvent;
00213   docEvent->CreateEvent(NS_LITERAL_STRING("Events"),
00214                         getter_AddRefs(sourceEvent));
00215   nsCOMPtr<nsIPrivateDOMEvent> privateSource = do_QueryInterface(sourceEvent);
00216   ASSERT_TRUE(privateSource);
00217 
00218   nsCOMPtr<nsIDOMXULCommandEvent> xcEvent = do_QueryInterface(event);
00219   ASSERT_TRUE(xcEvent);
00220   nsresult rv = xcEvent->InitCommandEvent(NS_LITERAL_STRING("command"),
00221                                           PR_TRUE, PR_TRUE, nsnull, 0,
00222                                           PR_FALSE, PR_FALSE, PR_FALSE,
00223                                           PR_FALSE, sourceEvent);
00224   ASSERT_TRUE(NS_SUCCEEDED(rv));
00225 
00226   // The source event will initially point to a non-key element
00227   privateSource->SetTarget(
00228       nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(elem)));
00229 
00230   mCollector->GetEventKeyId(event, keyId);
00231   ASSERT_TRUE(keyId.IsEmpty());
00232 
00233   // Create a key element and point the source event there
00234   nsCOMPtr<nsIDOMElement> keyElem;
00235   mDocument->CreateElementNS(kXULNS, NS_LITERAL_STRING("key"),
00236                              getter_AddRefs(keyElem));
00237   ASSERT_TRUE(keyElem);
00238   keyElem->SetAttribute(NS_LITERAL_STRING("id"), NS_LITERAL_STRING("keyFoo"));
00239   privateSource->SetTarget(
00240       nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(keyElem)));
00241 
00242   mCollector->GetEventKeyId(event, keyId);
00243   ASSERT_TRUE(keyId.Equals(NS_LITERAL_STRING("keyFoo")));
00244 
00245   // Make sure we don't crash if the source event target is a non-element
00246   nsCOMPtr<nsIDOMText> textNode;
00247   mDocument->CreateTextNode(NS_LITERAL_STRING("blah"),
00248                             getter_AddRefs(textNode));
00249   ASSERT_TRUE(textNode);
00250   privateSource->SetTarget(
00251       nsCOMPtr<nsIDOMEventTarget>(do_QueryInterface(textNode)));
00252   keyId.SetLength(0);
00253   mCollector->GetEventKeyId(event, keyId);
00254   ASSERT_TRUE(keyId.IsEmpty());
00255 
00256   ++gPassedTests;
00257 }
00258 
00259 int main(int argc, char *argv[])
00260 {
00261   nsStaticModuleInfo staticComps = { "metrics", &NSGetModule };
00262   NS_InitXPCOM3(nsnull, nsnull, nsnull, &staticComps, 1);
00263   // Pre-initialize the metrics service since it's assumed to exist
00264   nsMetricsService::get();
00265 
00266   // Use a separate instantiation of the test objects for each test
00267   {
00268     UICommandCollectorTest test;
00269     test.SetUp();
00270     test.TestGetEventTargets();
00271   }
00272   {
00273     UICommandCollectorTest test;
00274     test.SetUp();
00275     test.TestGetEventKeyId();
00276   }
00277 
00278   NS_ShutdownXPCOM(nsnull);
00279 
00280   printf("%d/%d tests passed\n", gPassedTests, gTotalTests);
00281   return 0;
00282 }