Back to index

lightning-sunbird  0.9+nobinonly
TableContentTest.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <stdio.h>
00039 #include "nscore.h"
00040 #include "nsIAtom.h"
00041 #include "nsStringBuf.h"
00042 #include "nsDocument.h"
00043 #include "nsIPresShell.h"
00044 #include "nsPresContext.h"
00045 #include "nsIContentDelegate.h"
00046 #include "nsIViewManager.h"
00047 #include "nsIView.h"
00048 #include "nsViewsCID.h"
00049 #include "nsIFrame.h"
00050 #include "nsIStyleSet.h"
00051 #include "nsHTMLParts.h"
00052 #include "..\..\..\src\nsTablePart.h"
00053 
00054 #include "nsContentCID.h"
00055 static NS_DEFINE_CID(kStyleSetCID, NS_STYLESET_CID);
00056 
00057 static FILE * out;
00058 
00059 
00060 class BasicTest : public nsDocument // yep, I'm a document
00061 {
00062 public:
00063   BasicTest();
00064   virtual ~BasicTest() {};
00065 
00066   nsresult AppendSimpleSpan(nsIContent* aContainer, const char* aTag, const char* aText);
00067 
00068   void CreateCorrectContent(PRInt32 aRows, PRInt32 aCols);
00069   void CreateCorrectFullContent(PRInt32 aRows, PRInt32 aCols);
00070   void CreateOutOfOrderContent(PRInt32 aRows, PRInt32 aCols);
00071   void CreateIllegalContent(PRInt32 aRows, PRInt32 aCols);
00072 
00073   void VerifyContent(PRInt32 aRows, PRInt32 aCols);
00074 
00075   void TestGeometry();
00076 };
00077 
00078 class GeometryTest
00079 {
00080 public:
00081   GeometryTest(BasicTest *aDoc);
00082 
00083   virtual ~GeometryTest() {};
00084 
00085   void CreateGeometry(BasicTest *aDoc, nsPresContext *aPC);
00086 
00087   void VerifyGeometry(BasicTest *aDoc, nsPresContext *aPC);
00088 
00089   nsIPresShell * mShell;
00090   nsIViewManager * mViewManager;
00091   nsIFrame * mRootFrame;
00092 };
00093 
00094 /* ---------- BasicTest Definitions ---------- */
00095 
00096 BasicTest::BasicTest()
00097   : nsDocument()
00098 {
00099   Init();
00100 
00101   PRInt32 rows = 3;
00102   PRInt32 cols = 4;
00103 
00104   // Build a basic table content model the "right" way
00105   CreateCorrectContent(rows, cols);
00106   VerifyContent(rows, cols);
00107   nsIContent *root;
00108   GetRootContent(&root);
00109   if (nsnull!=root && 1==root->ChildCount())
00110     root->RemoveChildAt(0);
00111   else
00112   {
00113     fprintf(out, "corrupt root after CreateCorrectContent\n");
00114     NS_ASSERTION(PR_FALSE, "");
00115   }
00116 
00117   // Build a content model the "right" way with every kind of table object
00118   CreateCorrectFullContent(rows, cols);
00119   VerifyContent(rows, cols);
00120   GetRootContent(&root);
00121   if (nsnull!=root && 1==root->ChildCount())
00122     root->RemoveChildAt(0);
00123   else
00124   {
00125     fprintf(out, "corrupt root after CreateCorrectFullContent\n");
00126     NS_ASSERTION(PR_FALSE, "");
00127   }
00128 
00129   // Build a content model with things out of order
00130   CreateOutOfOrderContent(rows, cols);
00131   VerifyContent(rows, cols);
00132   GetRootContent(&root);
00133   if (nsnull!=root && 1==root->ChildCount())
00134     root->RemoveChildAt(0);
00135   else
00136   {
00137     fprintf(out, "corrupt root after CreateOutOfOrderContent\n");
00138     NS_ASSERTION(PR_FALSE, "");
00139   }
00140 
00141   // Build a content model with illegal things
00142   /* not ready for prime time...
00143   CreateIllegalContent(rows, cols);
00144   VerifyContent(rows, cols);
00145   GetRootContent(&root);
00146   if (nsnull!=root && 1==root->ChildCount())
00147     root->RemoveChildAt(0);
00148   else
00149   {
00150     fprintf(out, "corrupt root after CreateIllegalContent\n");
00151     NS_ASSERTION(PR_FALSE);
00152   }
00153   */
00154 
00155   TestGeometry();
00156 }
00157 
00158 nsresult BasicTest::AppendSimpleSpan(nsIContent* aContainer, const char* aTag, const char* aText)
00159 {
00160   nsIContent* span;
00161   nsIContent* text;
00162   nsIAtom* atom = NS_NewAtom(aTag);
00163   nsresult rv = NS_NewHTMLContainer(&span, atom);
00164   if (NS_OK == rv) {
00165     nsStringBuf tmp;
00166     tmp.Append(aText);
00167     rv = NS_NewHTMLText(&text, tmp.get(), tmp.Length());
00168     if (NS_OK == rv) {
00169       span->AppendChildTo(text);
00170       NS_RELEASE(text);
00171     }
00172     aContainer->AppendChildTo(span);
00173     NS_RELEASE(span);
00174   }
00175   NS_RELEASE(atom);
00176   return rv;
00177 }
00178 
00179 void BasicTest::CreateCorrectContent(int aRows, int aCols)
00180 {
00181   fprintf(out, "CreateCorrectContent %d %d\n", aRows, aCols);
00182   nsIContent* root;
00183   nsresult rv = NS_NewRootPart(&root, this);  // does a SetRootPart on the returned root object
00184   if (NS_OK != rv) {
00185     fprintf(out, "NS_NewRootPart failed\n");
00186     NS_ASSERTION(PR_FALSE, "NS_NewRootPart failed");
00187   }
00188 
00189   nsIContent* body;
00190   nsIAtom* atom = NS_NewAtom("body");
00191   rv = NS_NewBodyPart(&body, atom);
00192   if (NS_OK != rv) {
00193     fprintf(out, "NS_NewBodyPart failed\n");
00194     NS_ASSERTION(PR_FALSE, "NS_NewBodyPart failed");
00195   }
00196   NS_RELEASE(atom);
00197 
00198   nsIContent* table;
00199   nsIContent* row;
00200   nsIContent* cell;
00201 
00202   nsIAtom* tatom = NS_NewAtom("table");
00203   rv = NS_NewTablePart(&table, tatom);
00204   NS_RELEASE(tatom);
00205   if (NS_OK == rv) {
00206     PRInt32 rowIndex;
00207     for (rowIndex = 0; (NS_OK == rv) && (rowIndex < aRows); rowIndex++) {
00208       nsIAtom* tratom = NS_NewAtom("tr");
00209       rv = NS_NewTableRowPart(&row, tratom);
00210       NS_RELEASE(tratom);
00211       if (NS_OK == rv) {
00212         PRInt32 colIndex;
00213         for (colIndex = 0; (NS_OK == rv) && (colIndex < aCols); colIndex++) {
00214           nsIAtom* tdatom = NS_NewAtom("td");
00215           rv = NS_NewTableCellPart(&cell, tdatom);
00216           NS_RELEASE(tdatom);
00217           if (NS_OK == rv) {
00218             rv = AppendSimpleSpan (cell, "p", "test");   
00219           }
00220           row->AppendChildTo(cell);
00221           NS_RELEASE(cell);
00222         }
00223         table->AppendChildTo(row);
00224         NS_RELEASE(row);
00225       }
00226     }
00227     ((nsTablePart *)table)->GetMaxColumns();  // has important side effect of creating pseudo-columns
00228     body->AppendChildTo(table);
00229     NS_RELEASE(table);
00230   }
00231   root->AppendChildTo(body);
00232   NS_RELEASE(body);
00233 }
00234 
00235 void BasicTest::CreateCorrectFullContent(int aRows, int aCols)
00236 {
00237   fprintf(out, "CreateCorrectFullContent %d %d, 1 caption\n", aRows, aCols);
00238   nsIContent* root;
00239   nsresult rv = NS_NewRootPart(&root, this);  // does a SetRootPart on the returned root object
00240   if (NS_OK != rv) {
00241     fprintf(out, "NS_NewRootPart failed\n");
00242     NS_ASSERTION(PR_FALSE, "NS_NewRootPart failed\n");
00243   }
00244 
00245   nsIContent* body;
00246   nsIAtom* atom = NS_NewAtom("body");
00247   rv = NS_NewBodyPart(&body, atom);
00248   if (NS_OK != rv) {
00249     fprintf(out, "NS_NewBodyPart failed\n");
00250     NS_ASSERTION(PR_FALSE, "NS_NewBodyPart failed\n");
00251   }
00252   NS_RELEASE(atom);
00253 
00254   nsIContent* table;
00255   nsIContent* caption;
00256   nsIContent* colGroup;
00257   nsIContent* col;
00258   nsIContent* row;
00259   nsIContent* cell;
00260 
00261   nsIAtom* tatom = NS_NewAtom("table");
00262   rv = NS_NewTablePart(&table, tatom);
00263   NS_RELEASE(tatom);
00264   
00265   // add caption
00266   nsIAtom* captionAtom = NS_NewAtom("caption");
00267   rv = NS_NewTableCaptionPart(&caption, captionAtom);
00268   NS_RELEASE(captionAtom);
00269   table->AppendChildTo(caption);
00270   
00271   // add column group
00272   PRInt32 colIndex;
00273   nsIAtom* colGroupAtom = NS_NewAtom("colgroup");
00274   rv = NS_NewTableColGroupPart(&colGroup, colGroupAtom);
00275   NS_RELEASE(colGroupAtom);
00276   table->AppendChildTo(colGroup);
00277 
00278   // add columns
00279   nsIAtom* colAtom = NS_NewAtom("col");
00280   for (colIndex = 0; (NS_OK == rv) && (colIndex < aCols); colIndex++) {
00281     rv = NS_NewTableColPart(&col, colAtom);
00282     colGroup->AppendChildTo(col);
00283   }
00284   NS_RELEASE(colAtom);
00285 
00286   // add rows and cells
00287   if (NS_OK == rv) {
00288     PRInt32 rowIndex;
00289     for (rowIndex = 0; (NS_OK == rv) && (rowIndex < aRows); rowIndex++) {
00290       nsIAtom* tratom = NS_NewAtom("tr");
00291       rv = NS_NewTableRowPart(&row, tratom);
00292       NS_RELEASE(tratom);
00293       if (NS_OK == rv) {
00294         for (colIndex = 0; (NS_OK == rv) && (colIndex < aCols); colIndex++) {
00295           nsIAtom* tdatom = NS_NewAtom("td");
00296           rv = NS_NewTableCellPart(&cell, tdatom);
00297           NS_RELEASE(tdatom);
00298           if (NS_OK == rv) {
00299             rv = AppendSimpleSpan (cell, "P", "test");   
00300           }
00301           row->AppendChildTo(cell);
00302           NS_RELEASE(cell);
00303         }
00304         table->AppendChildTo(row);
00305         NS_RELEASE(row);
00306       }
00307     }
00308     body->AppendChildTo(table);
00309     NS_RELEASE(table);
00310   }
00311   root->AppendChildTo(body);
00312   NS_RELEASE(body);
00313 }
00314 
00315 
00316 void BasicTest::CreateOutOfOrderContent(int aRows, int aCols)
00317 {
00318   fprintf(out, "CreateOutOfOrderContent %d %d, 2 captions\n", aRows, aCols);
00319   nsIContent* root;
00320   nsresult rv = NS_NewRootPart(&root, this);  // does a SetRootPart on the returned root object
00321   if (NS_OK != rv) {
00322     fprintf(out, "NS_NewRootPart failed\n");
00323     NS_ASSERTION(PR_FALSE, "NS_NewRootPart failed\n");
00324   }
00325 
00326   nsIContent* body;
00327   nsIAtom* atom = NS_NewAtom("body");
00328   rv = NS_NewBodyPart(&body, atom);
00329   if (NS_OK != rv) {
00330     fprintf(out, "NS_NewBodyPart failed\n");
00331     NS_ASSERTION(PR_FALSE, "NS_NewBodyPart failed\n");
00332   }
00333   NS_RELEASE(atom);
00334 
00335   nsIContent* table;
00336   nsIContent* caption;
00337   nsIContent* colGroup;
00338   nsIContent* col;
00339   nsIContent* row;
00340   nsIContent* cell;
00341 
00342   nsIAtom* tatom = NS_NewAtom("table");
00343   rv = NS_NewTablePart(&table, tatom);
00344   NS_RELEASE(tatom);
00345   
00346   // add rows and cells
00347   if (NS_OK == rv) {
00348     PRInt32 rowIndex;
00349     for (rowIndex = 0; (NS_OK == rv) && (rowIndex < aRows); rowIndex++) {
00350       nsIAtom* tratom = NS_NewAtom("tr");
00351       rv = NS_NewTableRowPart(&row, tratom);
00352       NS_RELEASE(tratom);
00353       if (NS_OK == rv) {
00354         for (PRInt32 colIndex = 0; (NS_OK == rv) && (colIndex < aCols); colIndex++) {
00355           nsIAtom* tdatom = NS_NewAtom("td");
00356           rv = NS_NewTableCellPart(&cell, tdatom);
00357           NS_RELEASE(tdatom);
00358           if (NS_OK == rv) {
00359             rv = AppendSimpleSpan (cell, "p", "test");   
00360           }
00361           row->AppendChildTo(cell);
00362           NS_RELEASE(cell);
00363           if (1==rowIndex && 0==colIndex)
00364           {
00365             // add column after cell[1,0], force implicit column group to be built
00366             PRInt32 colIndex;
00367             nsIAtom* colGroupAtom = NS_NewAtom("colgroup");
00368             rv = NS_NewTableColGroupPart(&colGroup, colGroupAtom);
00369             NS_RELEASE(colGroupAtom);
00370             table->AppendChildTo(colGroup);
00371           }
00372         }
00373         table->AppendChildTo(row);
00374         NS_RELEASE(row);
00375       }
00376     }
00377     ((nsTablePart *)table)->GetMaxColumns();  // has important side effect of creating pseudo-columns
00378     body->AppendChildTo(table);
00379   }
00380   root->AppendChildTo(body);
00381 
00382   // add caption in middle
00383   nsIAtom* captionAtom = NS_NewAtom("caption");
00384   rv = NS_NewTableCaptionPart(&caption, captionAtom);
00385   NS_RELEASE(captionAtom);
00386   table->AppendChildTo(caption);
00387 
00388   // add columns
00389   nsIAtom* colAtom = NS_NewAtom("col");
00390   for (PRInt32 colIndex = 0; (NS_OK == rv) && (colIndex < aCols); colIndex++) {
00391     rv = NS_NewTableColPart(&col, colAtom);
00392     colGroup->AppendChildTo(col);
00393   }
00394   NS_RELEASE(colAtom);
00395 
00396   // add caption at end
00397   captionAtom = NS_NewAtom("caption");
00398   rv = NS_NewTableCaptionPart(&caption, captionAtom);
00399   NS_RELEASE(captionAtom);
00400   table->AppendChildTo(caption);
00401 
00402   NS_RELEASE(table);
00403   NS_RELEASE(body);
00404 }
00405 
00406 void BasicTest::CreateIllegalContent(int aRows, int aCols)
00407 {
00408 }
00409 
00410 void BasicTest::VerifyContent(PRInt32 aRows, PRInt32 aCols)
00411 {
00412   nsIContent* root;
00413   GetRootContent(&root);
00414   if (nsnull==root)
00415   {
00416     fprintf(out, "GetRootContent failed\n");
00417     NS_ASSERTION(PR_FALSE, "GetRootContent failed\n");
00418   }
00419   fprintf(out, "VerifyContent for rows=%d, cols=%d\n", aRows, aCols);
00420   root->List(out);
00421 }
00422 
00423 void BasicTest::TestGeometry()
00424 {
00425   GeometryTest test(this);
00426 }
00427 
00428 /* ---------- GeometryTest Definitions ---------- */
00429 
00430 GeometryTest::GeometryTest(BasicTest *aDoc)
00431 {
00432   PRInt32 rows = 4;
00433   PRInt32 cols = 3;
00434 
00435 #if 0
00436   NS_InitToolkit(PR_GetCurrentThread());
00437 
00438   //NS_NewDeviceContext(&scribbleData.mContext);
00439   NS_NewWindow(NULL, NS_GET_IID(nsIWidget), nsnull);
00440 
00441 #endif
00442 
00443   nsIDeviceContext *dx;
00444   
00445   static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID);
00446 
00447   nsresult rv = CallCreateInstance(kDeviceContextCID, &dx);
00448 
00449   if (NS_OK == rv) {
00450     dx->Init(nsnull);
00451     dx->SetDevUnitsToAppUnits(dx->DevUnitsToTwips());
00452     dx->SetAppUnitsToDevUnits(dx->TwipsToDevUnits());
00453   }
00454 
00455   nsPresContext * pc = nsnull;
00456   nsresult status = NS_NewGalleyContext(&pc);
00457   if ((NS_FAILED(status)) ||  nsnull==pc)
00458   {
00459     fprintf(out, "bad galley pc");
00460     NS_ASSERTION(PR_FALSE, "bad galley pc");
00461   }
00462 
00463   pc->Init(dx, nsnull);
00464 
00465   // create a view manager
00466   nsIViewManager * vm = nsnull;
00467 
00468   static NS_DEFINE_IID(kViewManagerCID, NS_VIEW_MANAGER_CID);
00469 
00470   status = CallCreateInstance(kViewManagerCID, &vm);
00471 
00472   if ((NS_FAILED(status)) ||  nsnull==vm)
00473   {
00474     fprintf(out, "bad view manager");
00475     NS_ASSERTION(PR_FALSE, "bad view manager");
00476   }
00477   vm->Init(pc);
00478 
00479   nsRect bounds(0, 0, 10000, 10000);
00480   nsIScrollableView * rootView = vm->CreateScrollableView(bounds, nsnull);
00481 
00482   if ((NS_FAILED(status)) ||  nsnull==rootView)
00483   {
00484     fprintf(out, "bad view");
00485     NS_ASSERTION(PR_FALSE, "bad view");
00486   }
00487   vm->SetRootView(rootView->View());
00488 
00489   nsCOMPtr<nsIStyleSet> ss(do_CreateInstance(kStyleSetCID,&status));
00490   if ((NS_FAILED(status)))
00491   {
00492     fprintf(out, "bad style set");
00493     NS_ASSERTION(PR_FALSE, "bad style set");
00494   }
00495 
00496   mShell = nsnull;
00497   status = NS_NewPresShell(&mShell);
00498   if ((NS_FAILED(status)) ||  nsnull==mShell)
00499   {
00500     fprintf(out, "bad presentation shell.");
00501     NS_ASSERTION(PR_FALSE, "");
00502   }
00503   mShell->Init(aDoc, pc, vm, ss);
00504 
00505   aDoc->CreateCorrectContent(rows, cols);
00506   CreateGeometry(aDoc, pc);
00507   VerifyGeometry(aDoc, pc);
00508 
00509   aDoc->CreateCorrectFullContent(rows, cols);
00510   CreateGeometry(aDoc, pc);
00511   VerifyGeometry(aDoc, pc);
00512 
00513   /* paginated tests not ready yet...
00514   NS_RELEASE(pc);
00515   pc = nsnull;
00516   status = NS_NewPrintPreviewContext(&pc);
00517   if ((NS_FAILED(status)) ||  nsnull==pc)
00518   {
00519     fprintf(out, "bad paginated pc");
00520     NS_ASSERTION(PR_FALSE, "");
00521   }
00522   pc->Init(dx, nsnull);
00523   aDoc->CreateCorrectContent(rows, cols);
00524   CreateGeometry(aDoc, pc);
00525   VerifyGeometry(aDoc, pc);
00526 
00527   aDoc->CreateCorrectFullContent(rows, cols);
00528   CreateGeometry(aDoc, pc);
00529   VerifyGeometry(aDoc, pc);
00530   */
00531 }
00532 
00534 void GeometryTest::CreateGeometry(BasicTest * aDoc, nsPresContext *aPC)
00535 {
00536   nsIContent *root;
00537   aDoc->GetRootContent(&root);
00538   nsIContentDelegate* cd = root->GetDelegate(aPC);
00539   if (nsnull != cd) {
00540     mRootFrame = cd->CreateFrame(aPC, root, -1, nsnull);
00541     NS_RELEASE(cd);
00542     if (nsnull==mRootFrame)
00543     {
00544       fprintf(out, "mRootFrame failed\n");
00545       NS_ASSERTION(PR_FALSE, "mRootFrame failed\n");
00546     }
00547 
00548     // Bind root frame to root view (and root window)
00549     mViewManager = mShell->GetViewManager();
00550     if (nsnull==mViewManager)
00551     {
00552       fprintf(out, "bad view manager");
00553       NS_ASSERTION(PR_FALSE, "");
00554     }
00555     nsIView* rootView = mViewManager->GetRootView();
00556     NS_ASSERTION(nsnull!=rootView, "bad root view");
00557     mRootFrame->SetView(rootView);
00558     NS_RELEASE(rootView);
00559   }
00560   else {
00561     fprintf(out, "ERROR: no root delegate\n");
00562     NS_ASSERTION(PR_FALSE, "no root delegate");
00563   }
00564   NS_RELEASE(root);
00565 
00566   nsHTMLReflowMetrics desiredSize;
00567   nsSize          maxSize(400, 600);
00568   nsSize          maxElementSize;
00569 
00570 
00571   mRootFrame->ResizeReflow(aPC, desiredSize, maxSize, &maxElementSize);
00572 
00573   
00574 }
00575 
00576 void GeometryTest::VerifyGeometry(BasicTest *aDoc, nsPresContext *aPC)
00577 {
00578   mRootFrame->List(out);
00579 }
00580 
00581 
00582 /* ---------- Global Functions ---------- */
00583 
00584 void main (int argc, char **argv)
00585 {
00586   out = fopen("TableContentTest.txt", "w+t");
00587   if (nsnull==out)
00588   {
00589     fprintf(out, "test failed to open output file\n");
00590     NS_ASSERTION(PR_FALSE, "test failed to open output file\n");
00591   }
00592   fprintf(out, "Test starting...\n\n");
00593   BasicTest basicTest;
00594   fprintf(out, "\nTest completed.\n");
00595 }
00596 
00597 
00598 
00599 
00600 
00601