1 //
2 // "$Id: unittests.cxx 7903 2010-11-28 21:06:39Z matt $"
3 //
4 // Unit tests for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2010 by Bill Spitzak and others.
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // Library General Public License for more details.
17 //
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 // USA.
22 //
23 // Please report all bugs and problems on the following page:
24 //
25 //     http://www.fltk.org/str.php
26 //
27 // Fltk unit tests
28 // v0.1 - Greg combines Matthias + Ian's tests
29 // v0.2 - Ian's 02/12/09 fixes applied
30 // v0.3 - Fixes to circle desc, augmented extent tests, fixed indents, added show(argc,argv)
31 // v1.0 - Submit for svn
32 // v1.1 - Matthias seperated all tests into multiple source files for hopefully easier handling
33 
34 #include <FL/Fl.H>
35 #include <FL/Fl_Double_Window.H>
36 #include <FL/Fl_Hold_Browser.H>
37 #include <FL/Fl_Help_View.H>
38 #include <FL/Fl_Group.H>
39 #include <FL/Fl_Box.H>
40 #include <FL/fl_draw.H>		// fl_text_extents()
41 
42 // WINDOW/WIDGET SIZES
43 #define MAINWIN_W	700				// main window w()
44 #define MAINWIN_H	400				// main window h()
45 #define BROWSER_X	10				// browser x()
46 #define BROWSER_Y	25				// browser y()
47 #define BROWSER_W	150				// browser w()
48 #define BROWSER_H	MAINWIN_H-35			// browser h()
49 #define TESTAREA_X	(BROWSER_W + 20)		// test area x()
50 #define TESTAREA_Y	25				// test area y()
51 #define TESTAREA_W	(MAINWIN_W - BROWSER_W - 30)	// test area w()
52 #define TESTAREA_H	BROWSER_H			// test area h()
53 
54 typedef void (*UnitTestCallback)(const char*,Fl_Group*);
55 
56 class MainWindow *mainwin = 0;
57 Fl_Hold_Browser *browser = 0;
58 
59 // This class helps to automagically register a new test with the unittest app.
60 // Please see the examples on how this is used.
61 class UnitTest {
62 public:
UnitTest(const char * label,Fl_Widget * (* create)())63   UnitTest(const char *label, Fl_Widget* (*create)()) :
64     fWidget(0L)
65   {
66     fLabel = strdup(label);
67     fCreate = create;
68     add(this);
69   }
~UnitTest()70   ~UnitTest() {
71     delete fWidget;
72     free(fLabel);
73   }
label()74   const char *label() {
75     return fLabel;
76   }
create()77   void create() {
78     fWidget = fCreate();
79     if (fWidget) fWidget->hide();
80   }
show()81   void show() {
82     if (fWidget) fWidget->show();
83   }
hide()84   void hide() {
85     if (fWidget) fWidget->hide();
86   }
numTest()87   static int numTest() { return nTest; }
test(int i)88   static UnitTest *test(int i) { return fTest[i]; }
89 private:
90   char *fLabel;
91   Fl_Widget *(*fCreate)();
92   Fl_Widget *fWidget;
93 
add(UnitTest * t)94   static void add(UnitTest *t) {
95     fTest[nTest] = t;
96     nTest++;
97   }
98   static int nTest;
99   static UnitTest *fTest[200];
100 };
101 
102 int UnitTest::nTest = 0;
103 UnitTest *UnitTest::fTest[];
104 
105 
106 // The main window needs an additional drawing feature in order to support
107 // the viewport alignment test.
108 class MainWindow : public Fl_Double_Window {
109 public:
MainWindow(int w,int h,const char * l=0L)110   MainWindow(int w, int h, const char *l=0L) :
111     Fl_Double_Window(w, h, l),
112     fTestAlignment(0)
113   { }
114   // this code is used by the viewport alignment test
drawAlignmentIndicators()115   void drawAlignmentIndicators() {
116     const int sze = 16;
117     // top left corner
118     fl_color(FL_GREEN); fl_yxline(0, sze, 0, sze);
119     fl_color(FL_RED);   fl_yxline(-1, sze, -1, sze);
120     fl_color(FL_WHITE); fl_rectf(3, 3, sze-2, sze-2);
121     fl_color(FL_BLACK); fl_rect(3, 3, sze-2, sze-2);
122     // bottom left corner
123     fl_color(FL_GREEN); fl_yxline(0, h()-sze-1, h()-1, sze);
124     fl_color(FL_RED);   fl_yxline(-1, h()-sze-1, h(), sze);
125     fl_color(FL_WHITE); fl_rectf(3, h()-sze-1, sze-2, sze-2);
126     fl_color(FL_BLACK); fl_rect(3, h()-sze-1, sze-2, sze-2);
127     // bottom right corner
128     fl_color(FL_GREEN); fl_yxline(w()-1, h()-sze-1, h()-1, w()-sze-1);
129     fl_color(FL_RED);   fl_yxline(w(), h()-sze-1, h(), w()-sze-1);
130     fl_color(FL_WHITE); fl_rectf(w()-sze-1, h()-sze-1, sze-2, sze-2);
131     fl_color(FL_BLACK); fl_rect(w()-sze-1, h()-sze-1, sze-2, sze-2);
132     // top right corner
133     fl_color(FL_GREEN); fl_yxline(w()-1, sze, 0, w()-sze-1);
134     fl_color(FL_RED);   fl_yxline(w(), sze, -1, w()-sze-1);
135     fl_color(FL_WHITE); fl_rectf(w()-sze-1, 3, sze-2, sze-2);
136     fl_color(FL_BLACK); fl_rect(w()-sze-1, 3, sze-2, sze-2);
137   }
draw()138   void draw() {
139     Fl_Double_Window::draw();
140     if (fTestAlignment) {
141       drawAlignmentIndicators();
142     }
143   }
testAlignment(int v)144   void testAlignment(int v) {
145     fTestAlignment = v;
146     redraw();
147   }
148   int fTestAlignment;
149 };
150 
151 //------- include the various unit tests as inline code -------
152 
153 #include "unittest_about.cxx"
154 #include "unittest_points.cxx"
155 #include "unittest_lines.cxx"
156 #include "unittest_rects.cxx"
157 #include "unittest_circles.cxx"
158 #include "unittest_text.cxx"
159 #include "unittest_images.cxx"
160 #include "unittest_viewport.cxx"
161 #include "unittest_scrollbarsize.cxx"
162 
163 
164 // callback whenever the browser value changes
Browser_CB(Fl_Widget *,void *)165 void Browser_CB(Fl_Widget*, void*) {
166   for ( int t=1; t<=browser->size(); t++ ) {
167     UnitTest *ti = (UnitTest*)browser->data(t);
168     if ( browser->selected(t) ) {
169       ti->show();
170     } else {
171       ti->hide();
172     }
173   }
174 }
175 
176 
177 // this is the main call. It creates the window and adds all previously
178 // registered tests to the browser widget.
main(int argc,char ** argv)179 int main(int argc, char **argv) {
180   Fl::args(argc,argv);
181   Fl::visual(FL_RGB);
182   mainwin = new MainWindow(MAINWIN_W, MAINWIN_H, "Fltk Unit Tests");
183   browser = new Fl_Hold_Browser(BROWSER_X, BROWSER_Y, BROWSER_W, BROWSER_H, "Unit Tests");
184   browser->align(FL_ALIGN_TOP|FL_ALIGN_LEFT);
185   browser->when(FL_WHEN_CHANGED);
186   browser->callback(Browser_CB);
187 
188   int i, n = UnitTest::numTest();
189   for (i=0; i<n; i++) {
190     UnitTest *t = UnitTest::test(i);
191     mainwin->begin();
192     t->create();
193     mainwin->end();
194     browser->add(t->label(), (void*)t);
195   }
196 
197   /////
198   mainwin->resizable(mainwin);
199   mainwin->show(argc,argv);
200   // Select first test in browser, and show that test.
201   browser->select(1);
202   Browser_CB(browser,0);
203   return(Fl::run());
204 }
205 
206 //
207 // End of "$Id: unittests.cxx 7903 2010-11-28 21:06:39Z matt $".
208 //
209