@@ -8,7 +8,11 @@ Developers guide for QGIS
8
8
%! preproc : TUT_URL https://qgis.org
9
9
%! PostProc(html): '(?i)(<pre>)' '<div class="code">\1'
10
10
%! PostProc(html): '(?i)(</pre>)' '\1</div>'
11
+ % Next line will replace tabs with 2 spaces in txt generated outputs
12
+ %! PostProc(txt): '(?i)(\t)' ' '
11
13
%! encoding: iso-8859-1
14
+
15
+
12
16
% These are comments and will not be generated in any output
13
17
% -------------------
14
18
@@ -41,14 +45,16 @@ Developers guide for QGIS
41
45
%
42
46
%/!\ **Note:** Please do not remove this notice.
43
47
%
44
- %(!) This document was generated using text2tags from INSTALL.t2t in the QGIS sources. Make your
45
- % edits to that file and use t2t to regenerate in moinmoin %format, then paste the procedure in below.
46
- %I have instated these changes so that we can have a single central document that contains all the
47
- %instructions developers contributing to QGIS. This page should always reflect the most current SVN trunk build
48
- %procedure - for release versions the CODING document in the sources will be generated according
49
- %to the current build procedure at the time.
48
+ % (!) This document was generated using text2tags from CODING.t2t in the QGIS
49
+ % sources. Make your edits to that file and use t2t to regenerate in moinmoin
50
+ % format, then paste the procedure in below. I have instated these changes so
51
+ % that we can have a single central document that contains all the instructions
52
+ % developers contributing to QGIS. This page should always reflect the most
53
+ % current SVN trunk build procedure - for release versions the CODING document
54
+ % in the sources will be generated according to the current build procedure at
55
+ % the time.
50
56
51
- %Tim Sutton 2007
57
+ % Tim Sutton 2007
52
58
53
59
%-----------------------------------------------------------------
54
60
% Preamble ends
@@ -60,63 +66,80 @@ Developers guide for QGIS
60
66
These standards should be followed by all QGIS developers.
61
67
62
68
== Classes ==
69
+
63
70
=== Names ===
64
71
Class in QGIS begin with Qgs and are formed using mixed case.
65
72
```
66
73
Examples:
67
- QgsPoint
68
- QgsMapCanvas
69
- QgsRasterLayer
74
+ QgsPoint
75
+ QgsMapCanvas
76
+ QgsRasterLayer
70
77
```
71
78
72
79
=== Members ===
73
- Class member names begin with a lower case //m// and are formed using mixed case.
80
+ Class member names begin with a lower case //m// and are formed using mixed
81
+ case.
74
82
```
75
- mMapCanvas
76
- mCurrentExtent
83
+ mMapCanvas
84
+ mCurrentExtent
77
85
```
78
86
79
87
All class members should be private.
80
88
**Public class members are STRONGLY discouraged**
89
+
81
90
=== Accessor Functions ===
82
- Class member values should be obtained through accesssor functions. The function should be named without a //get// prefix. Accessor functions for the two private members above would be:
91
+ Class member values should be obtained through accesssor functions. The
92
+ function should be named without a //get// prefix. Accessor functions for the
93
+ two private members above would be:
83
94
```
84
- mapCanvas()
85
- currentExtent()
95
+ mapCanvas()
96
+ currentExtent()
86
97
```
87
98
88
99
=== Functions ===
89
- Function names begin with a lowercase letter and are formed using mixed case. The function name should convey something about the purpose of the function.
100
+ Function names begin with a lowercase letter and are formed using mixed case.
101
+ The function name should convey something about the purpose of the function.
90
102
```
91
- updateMapExtent()
92
- setUserOptions()
103
+ updateMapExtent()
104
+ setUserOptions()
93
105
```
94
106
95
107
== Qt Designer ==
96
108
=== Generated Classes ===
97
- QGIS classes that are generated from Qt Designer (ui) files should have a //Base// suffix. This identifies the class as a generated base class.
109
+ QGIS classes that are generated from Qt Designer (ui) files should have a
110
+ //Base// suffix. This identifies the class as a generated base class.
98
111
```
99
112
Examples:
100
- QgsPluginMangerBase
101
- QgsUserOptionsBase
113
+ QgsPluginMangerBase
114
+ QgsUserOptionsBase
102
115
```
103
116
=== Dialogs ===
104
117
All dialogs should implement the following:
105
118
* Tooltip help for all toolbar icons and other relevant widgets
106
119
* WhatsThis help for **all** widgets on the dialog
107
- * An optional (though highly recommended) context sensitive //Help// button that directs the user to the appropriate help page by launching their web browser
120
+ * An optional (though highly recommended) context sensitive //Help// button
121
+ that directs the user to the appropriate help page by launching their web
122
+ browser
123
+
108
124
== C++ Files ==
109
125
=== Names ===
110
- C++ implementation and header files should be have a .cpp and .h extension respectively.
111
- Filename should be all lowercase and, in the case of classes, match the class name.
126
+ C++ implementation and header files should be have a .cpp and .h extension
127
+ respectively. Filename should be all lowercase and, in the case of classes,
128
+ match the class name.
112
129
```
113
130
Example:
114
- Class QgsFeatureAttribute source files are
115
- qgsfeatureattribute.cpp and qgsfeatureattribute.h
131
+ Class QgsFeatureAttribute source files are
132
+ qgsfeatureattribute.cpp and qgsfeatureattribute.h
116
133
```
117
134
135
+ /!\ **Note:** in case it is not clear from the statement above, for a filename
136
+ to match a class name it implicitly means that each class should be declared
137
+ and implemented in its own file. This makes it much easier for newcomers to
138
+ identify where the code is relating to specific class.
139
+
118
140
=== Standard Header and License ===
119
- Each source file should contain a header section patterned after the following example:
141
+ Each source file should contain a header section patterned after the following
142
+ example:
120
143
```
121
144
/***************************************************************************
122
145
qgsfield.cpp - Describes a field in a layer or table
@@ -134,21 +157,25 @@ Each source file should contain a header section patterned after the following e
134
157
***************************************************************************/
135
158
```
136
159
137
- === CVS Keyword ===
138
- Each source file should contain the $Id$ keyword. This will be expanded by CVS to contain useful information about the file, revision, last committer, and date/time of last checkin.
160
+ === SVN Keyword ===
161
+ Each source file should contain the $Id$ keyword. This will be expanded by CVS
162
+ to contain useful information about the file, revision, last committer, and
163
+ date/time of last checkin.
139
164
140
- Place the keyword right after the standard header/license that is found at the top of each source file:
165
+ Place the keyword right after the standard header/license that is found at the
166
+ top of each source file:
141
167
```
142
- /* $Id$ */
168
+ /* $Id$ */
143
169
```
144
170
145
171
== Variable Names ==
146
172
Variable names begin with a lower case letter and are formed using mixed case.
147
173
```
148
174
Examples:
149
- mapCanvas
150
- currentExtent
175
+ mapCanvas
176
+ currentExtent
151
177
```
178
+
152
179
== Enumerated Types ==
153
180
154
181
Enumerated types should be named in CamelCase with a leading capital e.g.:
@@ -163,8 +190,8 @@ Enumerated types should be named in CamelCase with a leading capital e.g.:
163
190
} ;
164
191
```
165
192
166
- Do not use generic type names that will conflict with other types. e.g. use "UnkownUnit" rather
167
- than "Unknown"
193
+ Do not use generic type names that will conflict with other types. e.g. use
194
+ "UnkownUnit" rather than "Unknown"
168
195
169
196
== Global Constants ==
170
197
@@ -175,26 +202,31 @@ const long GEOCRS_ID = 3344;
175
202
```
176
203
177
204
== Editing ==
178
- Any text editor/IDE can be used to edit QGIS code, providing the following requirements are met.
205
+ Any text editor/IDE can be used to edit QGIS code, providing the following
206
+ requirements are met.
179
207
180
208
=== Tabs ===
181
- Set your editor to emulate tabs with spaces. Tab spacing should be set to 2 spaces.
209
+ Set your editor to emulate tabs with spaces. Tab spacing should be set to 2
210
+ spaces.
182
211
183
212
=== Indentation ===
184
- Source code should be indented to improve readability. There is a .indent.pro file in the QGIS src directory that contains the switches to be used when indenting code using the GNU indent program. If you don't use GNU indent, you should emulate these settings.
213
+ Source code should be indented to improve readability. There is a .indent.pro
214
+ file in the QGIS src directory that contains the switches to be used when
215
+ indenting code using the GNU indent program. If you don't use GNU indent, you
216
+ should emulate these settings.
185
217
186
218
=== Braces ===
187
219
Braces should start on the line following the expression:
188
220
```
189
- if(foo == 1)
190
- {
191
- // do stuff
192
- ...
193
- }else
194
- {
195
- // do something else
196
- ...
197
- }
221
+ if(foo == 1)
222
+ {
223
+ // do stuff
224
+ ...
225
+ }else
226
+ {
227
+ // do something else
228
+ ...
229
+ }
198
230
```
199
231
200
232
== API Compatibility ==
@@ -227,20 +259,21 @@ class Foo
227
259
228
260
== Coding Style ==
229
261
230
- Here are described some programming hints and tips that will hopefully reduce errors, development time, and maintenance.
262
+ Here are described some programming hints and tips that will hopefully reduce
263
+ errors, development time, and maintenance.
231
264
232
265
233
266
=== Where-ever Possible Generalize Code ===
234
267
```
235
- If you are cut-n-pasting code, or otherwise writing the same thing more than once, consider consolidating the code
236
- into a single function.
268
+ If you are cut-n-pasting code, or otherwise writing the same thing more than
269
+ once, consider consolidating the code into a single function.
237
270
```
238
271
239
272
This will:
240
273
* allow changes to be made in one location instead of in multiple places
241
274
* help prevent code bloat
242
- * make it more difficult for multiple copies to evolve differences over time, thus making it harder to understand and
243
- maintain for others
275
+ * make it more difficult for multiple copies to evolve differences over time,
276
+ thus making it harder to understand and maintain for others
244
277
245
278
=== Prefer Having Constants First in Predicates ===
246
279
@@ -249,13 +282,15 @@ Prefer to put constants first in predicates.
249
282
"0 == value" instead of "value == 0"
250
283
```
251
284
252
- This will help prevent programmers from accidentally using "=" when they meant to use "==", which can introduce very subtle
253
- logic bugs. The compiler will generate an error if you accidentally use "=" instead of "==" for comparisons since constants
254
- inherently cannot be assigned values.
285
+ This will help prevent programmers from accidentally using "=" when they meant
286
+ to use "==", which can introduce very subtle logic bugs. The compiler will
287
+ generate an error if you accidentally use "=" instead of "==" for comparisons
288
+ since constants inherently cannot be assigned values.
255
289
256
290
=== Whitespace Can Be Your Friend ===
257
291
258
- Adding spaces between operators, statements, and functions makes it easier for humans to parse code.
292
+ Adding spaces between operators, statements, and functions makes it easier for
293
+ humans to parse code.
259
294
260
295
261
296
Which is easier to read, this:
@@ -272,28 +307,32 @@ if ( ! a && b )
272
307
273
308
=== Add Trailing Identifying Comments ===
274
309
275
- Adding comments at the end of function, struct and class implementations makes it easier to find them later.
310
+ Adding comments at the end of function, struct and class implementations makes
311
+ it easier to find them later.
276
312
277
313
278
- Consider that you're at the bottom of a source file and need to find a very long function -- without these kinds of trailing
279
- comments you will have to page up past the body of the function to find its name. Of course this is ok if you wanted to find
280
- the beginning of the function; but what if you were interested at code near its end? You'd have to page up and then back down
281
- again to the desired part.
314
+ Consider that you're at the bottom of a source file and need to find a very
315
+ long function -- without these kinds of trailing comments you will have to page
316
+ up past the body of the function to find its name. Of course this is ok if you
317
+ wanted to find the beginning of the function; but what if you were interested
318
+ at code near its end? You'd have to page up and then back down again to the
319
+ desired part.
282
320
283
- E .g.,
321
+ e .g.,
284
322
285
323
```
286
324
void foo::bar()
287
325
{
288
326
// ... imagine a lot of code here
289
- } // foo::bar()
327
+ } // foo::bar()
290
328
```
291
329
292
330
293
331
=== Use Braces Even for Single Line Statements ===
294
332
295
- Using braces for code in if/then blocks or similar code structures even for single line statements means that adding another
296
- statement is less likely to generate broken code.
333
+ Using braces for code in if/then blocks or similar code structures even for
334
+ single line statements means that adding another statement is less likely to
335
+ generate broken code.
297
336
298
337
299
338
Consider:
@@ -305,8 +344,9 @@ Consider:
305
344
baz();
306
345
```
307
346
308
- Adding code after bar() or baz() without adding enclosing braces would create broken code. Though most programmers would
309
- naturally do that, some may forget to do so in haste.
347
+ Adding code after bar() or baz() without adding enclosing braces would create
348
+ broken code. Though most programmers would naturally do that, some may forget
349
+ to do so in haste.
310
350
311
351
So, prefer this:
312
352
@@ -324,11 +364,11 @@ So, prefer this:
324
364
325
365
=== Book recommendations ===
326
366
327
- * [Effective C++ http://www.awprofessional.com/title/0321334876], Scott Meyers
328
- * [More Effective C++ http://www.awprofessional.com/bookstore/product.asp?isbn=020163371X&rl=1], Scott Meyers
329
- * [Effective STL http://www.awprofessional.com/title/0201749629], Scott Meyers
330
- * [Design Patterns http://www.awprofessional.com/title/0201634988], GoF
331
-
367
+ - [Effective C++ http://www.awprofessional.com/title/0321334876], Scott Meyers
368
+ - [More Effective C++ http://www.awprofessional.com/bookstore/product.asp?isbn=020163371X&rl=1], Scott Meyers
369
+ - [Effective STL http://www.awprofessional.com/title/0201749629], Scott Meyers
370
+ - [Design Patterns http://www.awprofessional.com/title/0201634988], GoF
371
+ -
332
372
333
373
You should also really read this article from Qt Quarterly on
334
374
[http://doc.trolltech.com/qq/qq13-apis.html designing Qt style APIs]
@@ -347,29 +387,36 @@ To check out QGIS HEAD:
347
387
348
388
349
389
== Anonymous Access ==
350
- You can use the following commands to perform an anonymous checkout from the QGIS Subversion repository.
351
- Note we recommend checking out the trunk (unless you are a developer or really HAVE to have the latest
352
- changes and dont mind lots of crashing!).
390
+ You can use the following commands to perform an anonymous checkout from the
391
+ QGIS Subversion repository. Note we recommend checking out the trunk (unless
392
+ you are a developer or really HAVE to have the latest changes and dont mind
393
+ lots of crashing!).
353
394
354
- You must have a subversion client installed prior to checking out the code. See the Subversion website
355
- for more information. The Links page contains a good selection of SVN clients for various platforms.
395
+ You must have a subversion client installed prior to checking out the code. See
396
+ the Subversion website for more information. The Links page contains a good
397
+ selection of SVN clients for various platforms.
356
398
357
399
To check out a branch
358
400
```
359
401
svn co https://svn.osgeo.org/qgis/branches/<branch name>
360
402
```
403
+
361
404
To check out SVN stable trunk:
405
+
362
406
```
363
407
svn co https://svn.osgeo.org/qgis/trunk/qgis qgis_trunk
364
408
```
365
409
366
- /!\ **Note:** If you are behind a proxy server, edit your ~/subversion/servers file to specify
367
- your proxy settings first!
410
+ /!\ **Note:** If you are behind a proxy server, edit your ~/subversion/servers
411
+ file to specify your proxy settings first!
368
412
369
- /!\ **Note:** In QGIS we keep our most stable code in trunk. Periodically we will tag a release
370
- off trunk, and then continue stabilisation and selective incorporation of new features into trunk.
413
+ /!\ **Note:** In QGIS we keep our most stable code in the version 1_0 branch.
414
+ Trunk contains code for the so called 'unstable' release series. Periodically
415
+ we will tag a release off trunk, and then continue stabilisation and selective
416
+ incorporation of new features into trunk.
371
417
372
- See the INSTALL file in the source tree for specific instructions on building development versions.
418
+ See the INSTALL file in the source tree for specific instructions on building
419
+ development versions.
373
420
374
421
== QGIS documentation sources ==
375
422
@@ -380,50 +427,67 @@ If you're interested in checking out Quantum GIS documentation sources:
380
427
381
428
You can also take a look at DocumentationWritersCorner for more information.
382
429
383
- == Documentation ==
430
+ == SVN Documentation ==
431
+
384
432
The repository is organized as follows:
385
433
386
434
http://wiki.qgis.org/images/repo.png
387
435
388
- See the Subversion book http://svnbook.red-bean.com for information on becoming a SVN master.
436
+ See the Subversion book http://svnbook.red-bean.com for information on becoming
437
+ a SVN master.
389
438
390
439
391
440
392
441
393
442
== Development in branches ==
394
443
395
444
=== Purpose ===
396
- The complexity of the QGIS source code has increased considerably during the last years. Therefore it is hard
397
- to anticipate the side effects that the addition of a feature will have. In the past, the QGIS project had very
398
- long release cycles because it was a lot of work to reetablish the stability of the software system after new
399
- features were added. To overcome these problems, QGIS switched to a development model where new features are
400
- coded in svn branches first and merged to trunk (the main branch) when they are finished and stable. This section
401
- describes the procedure for branching and merging in the QGIS project.
445
+ The complexity of the QGIS source code has increased considerably during the
446
+ last years. Therefore it is hard to anticipate the side effects that the
447
+ addition of a feature will have. In the past, the QGIS project had very long
448
+ release cycles because it was a lot of work to reetablish the stability of the
449
+ software system after new features were added. To overcome these problems, QGIS
450
+ switched to a development model where new features are coded in svn branches
451
+ first and merged to trunk (the main branch) when they are finished and stable.
452
+ This section describes the procedure for branching and merging in the QGIS
453
+ project.
402
454
403
455
404
456
=== Procedure ===
405
- * Initial announcement on mailing list
406
- Before starting, make an announcement on the developer mailing list to see if another developer is
407
- already working on the same feature. Also contact the technical advisor of the project steering committee
408
- (PSC). If the new feature requires any changes to the QGIS architecture, a request for comment (RFC) is needed.
409
- * Create a branch
410
- Create a new svn branch for the development of the new feature (see UsingSubversion for the svn syntax). Now
411
- you can start developing.
412
- * Merge from trunk regularly
413
- It is recommended to merge the changes in trunk to the branch on a regular basis. This makes it easier to merge
414
- the branch back to trunk later.
415
- * Documentation on wiki
416
- It is also recommended to document the intended changes and the current status of the work on a wiki page.
417
- * Testing before merging back to trunk
418
- When you are finished with the new feature and happy with the stability, make an announcement on the developer list.
419
- Before merging back, the changes will be tested by developers and users. Binary packages (especially for OsX and Windows)
420
- will be generated to also involve non-developers. In trac, a new Component will be opened to file tickets against.
421
- Once there are no remaining issues left, the technical advisor of the PSC merges the changes into trunk.
457
+
458
+ - **Initial announcement on mailing list:**
459
+ Before starting, make an announcement on the developer mailing list to see if
460
+ another developer is already working on the same feature. Also contact the
461
+ technical advisor of the project steering committee (PSC). If the new feature
462
+ requires any changes to the QGIS architecture, a request for comment (RFC) is
463
+ needed.
464
+
465
+ - **Create a branch:**
466
+ Create a new svn branch for the development of the new feature (see
467
+ UsingSubversion for the svn syntax). Now you can start developing.
468
+
469
+ - **Merge from trunk regularly:**
470
+ It is recommended to merge the changes in trunk to the branch on a regular
471
+ basis. This makes it easier to merge the branch back to trunk later.
472
+
473
+ - **Documentation on wiki:**
474
+ It is also recommended to document the intended changes and the current status
475
+ of the work on a wiki page.
476
+
477
+ - **Testing before merging back to trunk:**
478
+ When you are finished with the new feature and happy with the stability, make
479
+ an announcement on the developer list. Before merging back, the changes will
480
+ be tested by developers and users. Binary packages (especially for OsX and
481
+ Windows) will be generated to also involve non-developers. In trac, a new
482
+ Component will be opened to file tickets against. Once there are no remaining
483
+ issues left, the technical advisor of the PSC merges the changes into trunk.
484
+
485
+ -
422
486
423
487
=== Creating a branch ===
424
488
425
- We prefer that new feature developments happen out of trunk so that trunk remains in a
426
- stable state. To create a branch use the following command:
489
+ We prefer that new feature developments happen out of trunk so that trunk
490
+ remains in a stable state. To create a branch use the following command:
427
491
428
492
```
429
493
svn copy https://svn.osgeo.org/qgis/trunk/qgis https://svn.osgeo.org/qgis/branches/qgis_newfeature
@@ -432,9 +496,10 @@ svn commit -m "New feature branch"
432
496
433
497
=== Merge regularly from trunk to branch ===
434
498
435
- When working in a branch you should regularly merge trunk into it so that your branch does not diverge more
436
- than necessary. In the top level dir of your branch, first type ```svn info``` to determine the revision
437
- numbers of your branch which will produce output something like this:
499
+ When working in a branch you should regularly merge trunk into it so that your
500
+ branch does not diverge more than necessary. In the top level dir of your
501
+ branch, first type ```svn info``` to determine the revision numbers of your
502
+ branch which will produce output something like this:
438
503
439
504
```
440
505
timlinux@timlinux-desktop:~/dev/cpp/qgis_raster_transparency_branch$ svn info
@@ -451,14 +516,16 @@ Data da Última Mudança: 2007-02-02 09:29:47 -0200 (Sex, 02 Fev 2007)
451
516
Propriedades da Última Mudança: 2007-01-09 11:32:55 -0200 (Ter, 09 Jan 2007)
452
517
```
453
518
454
- The second revision number shows the revision number of the start revision of your branch and the first the
455
- current revision. You can do a dry run of the merge like this:
519
+ The second revision number shows the revision number of the start revision of
520
+ your branch and the first the current revision. You can do a dry run of the
521
+ merge like this:
456
522
457
523
```
458
524
svn merge --dry-run -r 6495:6546 https://svn.osgeo.org/qgis/trunk/qgis
459
525
```
460
526
461
- After you are happy with the changes that will be made do the merge for real like this:
527
+ After you are happy with the changes that will be made do the merge for real
528
+ like this:
462
529
463
530
```
464
531
svn merge -r 6495:6546 https://svn.osgeo.org/qgis/trunk/qgis
@@ -468,23 +535,26 @@ svn commit -m "Merged upstream changes from trunk to my branch"
468
535
469
536
== Submitting Patches ==
470
537
471
- There are a few guidelines that will help you to get your patches into QGIS easily, and help us
472
- deal with the patches that are sent to use easily.
538
+ There are a few guidelines that will help you to get your patches into QGIS
539
+ easily, and help us deal with the patches that are sent to use easily.
473
540
474
541
=== Patch file naming ===
475
542
476
- If the patch is a fix for a specific bug, please name the file with the bug number in it e.g.
477
- **bug777fix.diff**, and attach it to the original bug report in trac (https://trac.osgeo.org/qgis/).
543
+ If the patch is a fix for a specific bug, please name the file with the bug
544
+ number in it e.g. **bug777fix.diff**, and attach it to the original bug report
545
+ in trac (https://trac.osgeo.org/qgis/).
478
546
479
- If the bug is an enhancement or new feature, its usually a good idea to create a ticket in
480
- trac (https://trac.osgeo.org/qgis/) first and then attach you
547
+ If the bug is an enhancement or new feature, its usually a good idea to create
548
+ a ticket in trac (https://trac.osgeo.org/qgis/) first and then attach you
481
549
482
550
=== Create your patch in the top level QGIS source dir ===
483
551
484
- This makes it easier for us to apply the patches since we don't need to navigate to a specific
485
- place in the source tree to apply the patch. Also when I receive patches I usually evaluate them
486
- using kompare, and having the patch from the top level dir makes this much easier. Below is an
487
- example of you you can include multiple changed files into your patch from the top level directory:
552
+ This makes it easier for us to apply the patches since we don't need to
553
+ navigate to a specific place in the source tree to apply the patch. Also when I
554
+ receive patches I usually evaluate them using kompare, and having the patch
555
+ from the top level dir makes this much easier. Below is an example of you you
556
+ can include multiple changed files into your patch from the top level
557
+ directory:
488
558
489
559
```
490
560
cd qgis
@@ -493,8 +563,9 @@ svn diff src/ui/somefile.ui src/app/somefile2.cpp > bug872fix.diff
493
563
494
564
=== Including non version controlled files in your patch ===
495
565
496
- If your improvements include new files that don't yet exist in the repository, you should indicate
497
- to svn that they need to be added before generating your patch e.g.
566
+ If your improvements include new files that don't yet exist in the repository,
567
+ you should indicate to svn that they need to be added before generating your
568
+ patch e.g.
498
569
499
570
```
500
571
cd qgis
@@ -504,28 +575,35 @@ svn diff > bug7887fix.diff
504
575
505
576
=== Getting your patch noticed ===
506
577
507
- QGIS developers are busy folk. We do scan the incoming patches on bug reports but sometimes we miss things.
508
- Don't be offended or alarmed. Try to identify a developer to help you - using the ["Project Organigram"] and
509
- contact them asking them if they can look at your patch. If you dont get any response, you can escalate your
510
- query to one of the Project Steering Committee members (contact details also available on the ["Project Organigram"]).
578
+ QGIS developers are busy folk. We do scan the incoming patches on bug reports
579
+ but sometimes we miss things. Don't be offended or alarmed. Try to identify a
580
+ developer to help you - using the ["Project Organigram"] and contact them
581
+ asking them if they can look at your patch. If you dont get any response, you
582
+ can escalate your query to one of the Project Steering Committee members
583
+ (contact details also available on the ["Project Organigram"]).
511
584
512
585
=== Due Diligence ===
513
586
514
- QGIS is licensed under the GPL. You should make every effort to ensure you only submit patches which are
515
- unencumbered by conflicting intellectual property rights. Also do not submit code that you are not happy to
516
- have made available under the GPL.
587
+ QGIS is licensed under the GPL. You should make every effort to ensure you only
588
+ submit patches which are unencumbered by conflicting intellectual property
589
+ rights. Also do not submit code that you are not happy to have made available
590
+ under the GPL.
517
591
518
592
519
593
520
594
== Obtaining SVN Write Access ==
521
595
522
- Write access to QGIS source tree is by invitation. Typically when a person submits several (there is no fixed
523
- number here) substantial patches that demonstrate basic competance and understanding of C++ and QGIS coding
524
- conventions, one of the PSC members or other existing developers can nominate that person to the PSC for granting
525
- of write access. The nominator should give a basic promotional paragraph of why they think that person should gain
526
- write access. In some cases we will grant write access to non C++ developers e.g. for translators and documentors.
527
- In these cases, the person should still have demonstrated ability to submit patches and should ideally have submtted
528
- several substantial patches that demonstrate their understanding of modifying the code base without breaking things, etc.
596
+ Write access to QGIS source tree is by invitation. Typically when a person
597
+ submits several (there is no fixed number here) substantial patches that
598
+ demonstrate basic competance and understanding of C++ and QGIS coding
599
+ conventions, one of the PSC members or other existing developers can nominate
600
+ that person to the PSC for granting of write access. The nominator should give
601
+ a basic promotional paragraph of why they think that person should gain write
602
+ access. In some cases we will grant write access to non C++ developers e.g. for
603
+ translators and documentors. In these cases, the person should still have
604
+ demonstrated ability to submit patches and should ideally have submtted several
605
+ substantial patches that demonstrate their understanding of modifying the code
606
+ base without breaking things, etc.
529
607
530
608
531
609
@@ -555,19 +633,21 @@ Make your edits
555
633
cd ..
556
634
```
557
635
558
- Make your changes in sources. Always check that everything compiles before making any commits.
559
- Try to be aware of possible breakages your commits may cause for people building on other
560
- platforms and with older / newer versions of libraries.
636
+ Make your changes in sources. Always check that everything compiles before
637
+ making any commits. Try to be aware of possible breakages your commits may
638
+ cause for people building on other platforms and with older / newer versions of
639
+ libraries.
561
640
562
641
563
- Add files (if you added any new files). The svn status command can be used to quickly see
564
- if you have added new files.
642
+ Add files (if you added any new files). The svn status command can be used to
643
+ quickly see if you have added new files.
565
644
566
645
```
567
646
svn status src/pluguns/grass/modules
568
647
```
569
648
570
- Files listed with ? in front are not in SVN and possibly need to be added by you:
649
+ Files listed with ? in front are not in SVN and possibly need to be added by
650
+ you:
571
651
572
652
```
573
653
svn add src/pluguns/grass/modules/foo.xml
@@ -579,77 +659,85 @@ Commit your changes
579
659
svn commit src/pluguns/grass/modules/foo.xml
580
660
```
581
661
582
- Your editor (as defined in $EDITOR environment variable) will appear and you should make a
583
- comment at the top of the file (above the area that says 'dont change this'. Put a
584
- descriptive comment and rather do several small commits if the changes across a number of
585
- files are unrelated. Conversely we prefer you to group related changes into a single commit.
662
+ Your editor (as defined in $EDITOR environment variable) will appear and you
663
+ should make a comment at the top of the file (above the area that says 'dont
664
+ change this'. Put a descriptive comment and rather do several small commits if
665
+ the changes across a number of files are unrelated. Conversely we prefer you to
666
+ group related changes into a single commit.
586
667
587
- Save and close in your editor. The first time you do this, you should be prompted to
588
- put in your username and password. Just use the same ones as your trac account.
668
+ Save and close in your editor. The first time you do this, you should be
669
+ prompted to put in your username and password. Just use the same ones as your
670
+ trac account.
589
671
590
672
591
673
= Unit Testing =
592
674
593
- As of November 2007 we require all new features going into trunk to be accompanied with
594
- a unit test. Initially we have limited this requirement to qgis_core, and we will extend
595
- this requirement to other parts of the code base once people are familiar with the
596
- procedures for unit testing explained in the sections that follow.
675
+ As of November 2007 we require all new features going into trunk to be
676
+ accompanied with a unit test. Initially we have limited this requirement to
677
+ **qgis_core**, and we will extend this requirement to other parts of the code base
678
+ once people are familiar with the procedures for unit testing explained in the
679
+ sections that follow.
597
680
598
681
== The QGIS testing framework - an overview ==
599
682
600
- Unit testing is carried out using a combination of QTestLib (the Qt testing library) and
601
- CTest (a framework for compiling and running tests as part of the CMake build process).
602
- Lets take an overview of the process before I delve into the details:
603
-
604
- * **There is some code you want to test**, e.g. a class or function. Extreme programming
605
- advocates suggest that the code should not even be written yet when you start
606
- building your tests, and then as you implement your code you can immediately validate
607
- each new functional part you add with your test. In practive you will probably
608
- need to write tests for pre-existing code in QGIS since we are starting with a testing
609
- framework well after much application logic has already been implemented.
610
-
611
- * **You create a unit test.** This happens under <QGIS Source Dir>/tests/src/core
612
- in the case of the core lib. The test is basically a client that creates an instance
613
- of a class and calls some methods on that class. It will check the return from each
614
- method to make sure it matches the expected value. If any one of the calls fails,
615
- the unit will fail.
616
-
617
- * **You include QtTestLib macros in your test class.** This macro is processed by
618
- the Qt meta object compiler (moc) and expands your test class into a runnable application.
619
-
620
- * **You add a section to the CMakeLists.txt** in your tests directory that will
683
+ Unit testing is carried out using a combination of QTestLib (the Qt testing
684
+ library) and CTest (a framework for compiling and running tests as part of the
685
+ CMake build process). Lets take an overview of the process before I delve into
686
+ the details:
687
+
688
+ - **There is some code you want to test**, e.g. a class or function. Extreme
689
+ programming advocates suggest that the code should not even be written yet
690
+ when you start building your tests, and then as you implement your code you can
691
+ immediately validate each new functional part you add with your test. In
692
+ practive you will probably need to write tests for pre-existing code in QGIS
693
+ since we are starting with a testing framework well after much application
694
+ logic has already been implemented.
695
+
696
+ - **You create a unit test.** This happens under <QGIS Source Dir>/tests/src/core
697
+ in the case of the core lib. The test is basically a client that creates an
698
+ instance of a class and calls some methods on that class. It will check the
699
+ return from each method to make sure it matches the expected value. If any
700
+ one of the calls fails, the unit will fail.
701
+
702
+ - **You include QtTestLib macros in your test class.** This macro is processed by
703
+ the Qt meta object compiler (moc) and expands your test class into a
704
+ runnable application.
705
+
706
+ - **You add a section to the CMakeLists.txt** in your tests directory that will
621
707
build your test.
622
708
623
- * **You ensure you have ENABLE_TESTING enabled in ccmake / cmakesetup.** This
709
+ - **You ensure you have ENABLE_TESTING enabled in ccmake / cmakesetup.** This
624
710
will ensure your tests actually get compiled when you type make.
625
711
626
- * **You optionally add test data to <QGIS Source Dir>/tests/testdata** if your
627
- test is data driven (e.g. needs to load a shapefile). These test data should be
628
- as small as possible and wherever possible you should use the existing datasets
629
- already there. Your tests should never modify this data in situ, but rather
630
- may a temporary copy somewhere if needed.
712
+ - **You optionally add test data to <QGIS Source Dir>/tests/testdata** if your
713
+ test is data driven (e.g. needs to load a shapefile). These test data should
714
+ be as small as possible and wherever possible you should use the existing
715
+ datasets already there. Your tests should never modify this data in situ,
716
+ but rather may a temporary copy somewhere if needed.
631
717
632
- * **You compile your sources and install.** Do this using normal make && (sudo)
718
+ - **You compile your sources and install.** Do this using normal make && (sudo)
633
719
make install procedure.
634
720
635
- * **You run your tests.** This is normally done simply by doing **make test**
636
- after the make install step, though I will explain other aproaches that offer more
637
- fine grained control over running tests.
721
+ - **You run your tests.** This is normally done simply by doing **make test**
722
+ after the make install step, though I will explain other aproaches that offer
723
+ more fine grained control over running tests.
638
724
639
- Right with that overview in mind, I will delve into a bit of detail. I've already
640
- done much of the configuration for you in CMake and other places in the source tree
641
- so all you need to do are the easy bits - writing unit tests!
725
+ -
726
+
727
+ Right with that overview in mind, I will delve into a bit of detail. I've
728
+ already done much of the configuration for you in CMake and other places in the
729
+ source tree so all you need to do are the easy bits - writing unit tests!
642
730
643
731
== Creating a unit test ==
644
732
645
- Creating a unit test is easy - typically you will do this by just creating a
733
+ Creating a unit test is easy - typically you will do this by just creating a
646
734
single .cpp file (not .h file is used) and implement all your test methods as
647
- public methods that return void. I'll use a simple test class for QgsRasterLayer
648
- throughout the section that follows to illustrate. By convention we will name our
649
- test with the same name as the class they are testing but prefixed with 'Test'.
650
- So our test implementation goes in a file called testqgsrasterlayer.cpp and
651
- the class itself will be TestQgsRasterLayer. First we add our standard copyright
652
- banner:
735
+ public methods that return void. I'll use a simple test class for
736
+ QgsRasterLayer throughout the section that follows to illustrate. By convention
737
+ we will name our test with the same name as the class they are testing but
738
+ prefixed with 'Test'. So our test implementation goes in a file called
739
+ testqgsrasterlayer.cpp and the class itself will be TestQgsRasterLayer. First
740
+ we add our standard copyright banner:
653
741
654
742
```
655
743
/***************************************************************************
@@ -693,11 +781,11 @@ in whatever headers you may need:
693
781
#include <qgsapplication.h>
694
782
```
695
783
696
- Since we are combining both class declaration and implementation in a single
697
- file the class declaration comes next. We start with our doxygen documentation.
698
- Every test case should be properly documented. We use the doxygen **ingroup**
699
- directive so that all the UnitTests appear as a module in the generated
700
- Doxygen documentation. After that comes a short description of the unit test:
784
+ Since we are combining both class declaration and implementation in a single
785
+ file the class declaration comes next. We start with our doxygen documentation.
786
+ Every test case should be properly documented. We use the doxygen **ingroup**
787
+ directive so that all the UnitTests appear as a module in the generated Doxygen
788
+ documentation. After that comes a short description of the unit test:
701
789
702
790
```
703
791
/** \ingroup UnitTests
@@ -713,109 +801,103 @@ class TestQgsRasterLayer: public QObject
713
801
Q_OBJECT;
714
802
```
715
803
716
- All our test methods are implemented as **private slots**. The QtTest framework
717
- will sequentially call each private slot method in the test class. There are
718
- four 'special' methods which if implemented will be called at the start of
719
- the unit test (**initTestCase**), at the end of the unit test (**cleanupTestCase**).
720
- Before each test method is called, the **init()** method will be called and
721
- after each test method is called the **cleanup()** method is called. These
722
- methods are handy in that they allow you to allocate and cleanup resources
723
- prior to running each test, and the test unit as a whole.
804
+ All our test methods are implemented as **private slots**. The QtTest framework
805
+ will sequentially call each private slot method in the test class. There are
806
+ four 'special' methods which if implemented will be called at the start of the
807
+ unit test (**initTestCase**), at the end of the unit test
808
+ (**cleanupTestCase**). Before each test method is called, the **init()**
809
+ method will be called and after each test method is called the **cleanup()**
810
+ method is called. These methods are handy in that they allow you to allocate
811
+ and cleanup resources prior to running each test, and the test unit as a whole.
724
812
725
813
726
814
```
727
815
private slots:
728
- // will be called before the first testfunction is executed.
729
- void initTestCase();
730
- // will be called after the last testfunction was executed.
731
- void cleanupTestCase(){};
732
- // will be called before each testfunction is executed.
733
- void init(){};
734
- // will be called after every testfunction.
735
- void cleanup();
736
- ```
737
-
738
- Then come your test methods, all of which should take **no parameters** and
739
- should **return void**. The methods will be called in order of declaration.
740
- I am implementing two methods here which illustrates to types of testing. In
741
- the first case I want to generally test the various parts of the class are
742
- working, I can use a **functional testing** approach. Once again, extreme
743
- programmers would advocate writing these tests **before** implementing the
744
- class. Then as you work your way through your class implementation you
745
- iteratively run your unit tests. More and more test functions should complete
746
- sucessfully as your class implementation work progresses, and when the whole
747
- unit test passes, your new class is done and is now complete with a repeatable
748
- way to validate it.
749
-
750
- Typically your unit tests would only cover the **public** API of your
751
- class, and normally you do not need to write tests for accessors and mutators.
752
- If it should happen that an acccessor or mutator is not working as expected
753
- you would normally implement a **regression** test to check for this (see
754
- lower down).
755
-
756
- ```
757
- //
758
- // Functional Testing
759
- //
760
-
761
- /** Check if a raster is valid. */
762
- void isValid();
763
-
764
- // more functional tests here ...
765
- ```
766
-
767
- Next we implement our **regression tests**. Regression tests should be
768
- implemented to replicate the conditions of a particular bug. For example
769
- I recently received a report by email that the cell count by rasters was
770
- off by 1, throwing off all the statistics for the raster bands. I opened
771
- a bug (ticket #832) and then created a regression test that replicated
772
- the bug using a small test dataset (a 10x10 raster). Then I ran the test
773
- and ran it, verifying that it did indeed fail (the cell count was 99
774
- instead of 100). Then I went to fix the bug and reran the unit test and
775
- the regression test passed. I committed the regression test along with
776
- the bug fix. Now if anybody breakes this in the source code again in the
777
- future, we can immediatly identify that the code has regressed. Better
778
- yet before committing any changes in the future, running our tests will
779
- ensure our changes dont have unexpected side effects - like breaking
816
+ // will be called before the first testfunction is executed.
817
+ void initTestCase();
818
+ // will be called after the last testfunction was executed.
819
+ void cleanupTestCase(){};
820
+ // will be called before each testfunction is executed.
821
+ void init(){};
822
+ // will be called after every testfunction.
823
+ void cleanup();
824
+ ```
825
+
826
+ Then come your test methods, all of which should take **no parameters** and
827
+ should **return void**. The methods will be called in order of declaration. I
828
+ am implementing two methods here which illustrates to types of testing. In the
829
+ first case I want to generally test the various parts of the class are working,
830
+ I can use a **functional testing** approach. Once again, extreme programmers
831
+ would advocate writing these tests **before** implementing the class. Then as
832
+ you work your way through your class implementation you iteratively run your
833
+ unit tests. More and more test functions should complete sucessfully as your
834
+ class implementation work progresses, and when the whole unit test passes, your
835
+ new class is done and is now complete with a repeatable way to validate it.
836
+
837
+ Typically your unit tests would only cover the **public** API of your class,
838
+ and normally you do not need to write tests for accessors and mutators. If it
839
+ should happen that an acccessor or mutator is not working as expected you would
840
+ normally implement a **regression** test to check for this (see lower down).
841
+
842
+ ```
843
+ //
844
+ // Functional Testing
845
+ //
846
+
847
+ /** Check if a raster is valid. */
848
+ void isValid();
849
+
850
+ // more functional tests here ...
851
+ ```
852
+
853
+ Next we implement our **regression tests**. Regression tests should be
854
+ implemented to replicate the conditions of a particular bug. For example I
855
+ recently received a report by email that the cell count by rasters was off by
856
+ 1, throwing off all the statistics for the raster bands. I opened a bug (ticket
857
+ #832) and then created a regression test that replicated the bug using a small
858
+ test dataset (a 10x10 raster). Then I ran the test and ran it, verifying that
859
+ it did indeed fail (the cell count was 99 instead of 100). Then I went to fix
860
+ the bug and reran the unit test and the regression test passed. I committed the
861
+ regression test along with the bug fix. Now if anybody breakes this in the
862
+ source code again in the future, we can immediatly identify that the code has
863
+ regressed. Better yet before committing any changes in the future, running our
864
+ tests will ensure our changes dont have unexpected side effects - like breaking
780
865
existing functionality.
781
866
782
- There is one more benifit to regression tests - they can save you time.
783
- If you ever fixed a bug that involved making changes to the source,
784
- and then running the application and performing a series of convoluted
785
- steps to replicate the issue, it will be immediately apparent that
786
- simply implementing your regression test **before** fixing the bug
787
- will let you automate the testing for bug resolution in an efficient
788
- manner.
789
-
790
- To implement your regression test, you should follow the naming
791
- convention of regression<TicketID> for your test functions. If no
792
- trac ticket exists for the regression, you should create one first.
793
- Using this approach allows the person running a failed regression
794
- test easily go and find out more information.
795
-
796
- ```
797
- //
798
- // Regression Testing
799
- //
800
-
801
- /** This is our second test case...to check if a raster
802
- reports its dimensions properly. It is a regression test
803
- for ticket #832 which was fixed with change r7650.
804
- */
805
- void regression832();
867
+ There is one more benifit to regression tests - they can save you time. If you
868
+ ever fixed a bug that involved making changes to the source, and then running
869
+ the application and performing a series of convoluted steps to replicate the
870
+ issue, it will be immediately apparent that simply implementing your regression
871
+ test **before** fixing the bug will let you automate the testing for bug
872
+ resolution in an efficient manner.
873
+
874
+ To implement your regression test, you should follow the naming convention of
875
+ regression<TicketID> for your test functions. If no trac ticket exists for the
876
+ regression, you should create one first. Using this approach allows the person
877
+ running a failed regression test easily go and find out more information.
878
+
879
+ ```
880
+ //
881
+ // Regression Testing
882
+ //
883
+
884
+ /** This is our second test case...to check if a raster
885
+ reports its dimensions properly. It is a regression test
886
+ for ticket #832 which was fixed with change r7650.
887
+ */
888
+ void regression832();
806
889
807
- // more regression tests go here ...
890
+ // more regression tests go here ...
808
891
```
809
892
810
- Finally in our test class declaration you can declare privately
811
- any data members and helper methods your unit test may need. In our
812
- case I will declare a QgsRasterLayer * which can be used by any
813
- of our test methods. The raster layer will be created in the
814
- initTestCase() function which is run before any other tests, and then
815
- destroyed using cleanupTestCase() which is run after all tests. By
816
- declaring helper methods (which may be called by various test
817
- functions) privately, you can ensure that they wont be automatically
818
- run by the QTest executeable that is created when we compile our test.
893
+ Finally in our test class declaration you can declare privately any data
894
+ members and helper methods your unit test may need. In our case I will declare
895
+ a QgsRasterLayer * which can be used by any of our test methods. The raster
896
+ layer will be created in the initTestCase() function which is run before any
897
+ other tests, and then destroyed using cleanupTestCase() which is run after all
898
+ tests. By declaring helper methods (which may be called by various test
899
+ functions) privately, you can ensure that they wont be automatically run by the
900
+ QTest executeable that is created when we compile our test.
819
901
820
902
```
821
903
private:
@@ -826,8 +908,8 @@ run by the QTest executeable that is created when we compile our test.
826
908
827
909
```
828
910
829
- That ends our class declaration. The implementation is simply
830
- inlined in the same file lower down. First our init and cleanup functions:
911
+ That ends our class declaration. The implementation is simply inlined in the
912
+ same file lower down. First our init and cleanup functions:
831
913
832
914
```
833
915
void TestQgsRasterLayer::initTestCase()
@@ -878,11 +960,10 @@ Qt also provides some other interesting mechanisms for data driven
878
960
testing, so if you are interested to know more on the topic, consult
879
961
the Qt documentation.
880
962
881
- Next lets look at our functional test. The isValid() test simply
882
- checks the raster layer was correctly loaded in the initTestCase.
883
- QVERIFY is a Qt macro that you can use to evaluate a test condition.
884
- There are a few other use macros Qt provide for use in your tests
885
- including:
963
+ Next lets look at our functional test. The isValid() test simply checks the
964
+ raster layer was correctly loaded in the initTestCase. QVERIFY is a Qt macro
965
+ that you can use to evaluate a test condition. There are a few other use
966
+ macros Qt provide for use in your tests including:
886
967
887
968
```
888
969
QCOMPARE ( actual, expected )
@@ -899,8 +980,8 @@ QVERIFY ( condition )
899
980
QWARN ( message )
900
981
```
901
982
902
- Some of these macros are useful only when using the Qt framework
903
- for data driven testing (see the Qt docs for more detail).
983
+ Some of these macros are useful only when using the Qt framework for data
984
+ driven testing (see the Qt docs for more detail).
904
985
905
986
```
906
987
void TestQgsRasterLayer::isValid()
@@ -909,13 +990,13 @@ void TestQgsRasterLayer::isValid()
909
990
}
910
991
```
911
992
912
- Normally your functional tests would cover all the range of
913
- functionality of your classes public API where feasible. With our
914
- functional tests out the way, we can look at our regression test example.
993
+ Normally your functional tests would cover all the range of functionality of
994
+ your classes public API where feasible. With our functional tests out the way,
995
+ we can look at our regression test example.
915
996
916
- Since the issue in bug #832 is a misreported cell count, writing
917
- our test if simply a matter of using QVERIFY to check that the
918
- cell count meets the expected value:
997
+ Since the issue in bug #832 is a misreported cell count, writing our test if
998
+ simply a matter of using QVERIFY to check that the cell count meets the
999
+ expected value:
919
1000
920
1001
```
921
1002
void TestQgsRasterLayer::regression832()
@@ -928,25 +1009,24 @@ void TestQgsRasterLayer::regression832()
928
1009
}
929
1010
```
930
1011
931
- With all the unit test functions implemented, there one final thing we
932
- need to add to our test class:
1012
+ With all the unit test functions implemented, there one final thing we need to
1013
+ add to our test class:
933
1014
934
1015
```
935
1016
QTEST_MAIN(TestQgsRasterLayer)
936
1017
#include "moc_testqgsrasterlayer.cxx"
937
1018
```
938
1019
939
- The purpose of these two lines is to signal to Qt's moc that his is a
940
- QtTest (it will generate a main method that in turn calls each test funtion.
941
- The last line is the include for the MOC generated sources. You should
942
- replace 'testqgsrasterlayer' with the name of your class in lower case.
1020
+ The purpose of these two lines is to signal to Qt's moc that his is a QtTest
1021
+ (it will generate a main method that in turn calls each test funtion. The last
1022
+ line is the include for the MOC generated sources. You should replace
1023
+ 'testqgsrasterlayer' with the name of your class in lower case.
943
1024
944
1025
== Adding your unit test to CMakeLists.txt ==
945
1026
946
- Adding your unit test to the build system is simply a matter of editing
947
- the CMakeLists.txt in the test directory, cloning one of the existing
948
- test blocks, and then search and replacing your test class name into it.
949
- For example:
1027
+ Adding your unit test to the build system is simply a matter of editing the
1028
+ CMakeLists.txt in the test directory, cloning one of the existing test blocks,
1029
+ and then search and replacing your test class name into it. For example:
950
1030
951
1031
```
952
1032
#
@@ -963,23 +1043,23 @@ INSTALL(TARGETS qgis_rasterlayertest RUNTIME DESTINATION ${QGIS_BIN_DIR})
963
1043
ADD_TEST(qgis_rasterlayertest ${QGIS_BIN_DIR}/qgis_rasterlayertest)
964
1044
```
965
1045
966
- I'll run through these lines briefly to explain what they do, but if
967
- you are not interested, just clone the block, search and replace e.g.
1046
+ I'll run through these lines briefly to explain what they do, but if you are
1047
+ not interested, just clone the block, search and replace e.g.
968
1048
969
1049
```
970
1050
:'<,'>s/rasterlayer/mynewtest/g
971
1051
```
972
1052
973
- Lets look a little more in detail at the individual lines. First we
974
- define the list of sources for our test. Since we have only one source file
975
- (following the methodology I described above where class declaration and
976
- definition are in the same file) its a simple statement:
1053
+ Lets look a little more in detail at the individual lines. First we define the
1054
+ list of sources for our test. Since we have only one source file (following the
1055
+ methodology I described above where class declaration and definition are in the
1056
+ same file) its a simple statement:
977
1057
978
1058
```
979
1059
SET(qgis_rasterlayertest_SRCS testqgsrasterlayer.cpp)
980
1060
```
981
1061
982
- Since our test class needs to be run through the Qt meta object compiler (moc)
1062
+ Since our test class needs to be run through the Qt meta object compiler (moc)
983
1063
we need to provide a couple of lines to make that happen too:
984
1064
985
1065
```
@@ -988,68 +1068,65 @@ QT4_WRAP_CPP(qgis_rasterlayertest_MOC_SRCS ${qgis_rasterlayertest_MOC_CPPS})
988
1068
ADD_CUSTOM_TARGET(qgis_rasterlayertestmoc ALL DEPENDS ${qgis_rasterlayertest_MOC_SRCS})
989
1069
```
990
1070
991
- Next we tell cmake that it must make an executeable from the test class.
992
- Remember in the previous section on the last line of the class implementation
993
- I included the moc outputs directly into our test class, so that will
994
- give it (among other things) a main method so the class can be
995
- compiled as an executeable:
1071
+ Next we tell cmake that it must make an executeable from the test class.
1072
+ Remember in the previous section on the last line of the class implementation I
1073
+ included the moc outputs directly into our test class, so that will give it
1074
+ (among other things) a main method so the class can be compiled as an
1075
+ executeable:
996
1076
997
1077
```
998
1078
ADD_EXECUTABLE(qgis_rasterlayertest ${qgis_rasterlayertest_SRCS})
999
1079
ADD_DEPENDENCIES(qgis_rasterlayertest qgis_rasterlayertestmoc)
1000
1080
```
1001
1081
1002
- Next we need to specify any library dependencies. At the moment classes
1003
- have been implemented with a catch-all QT_LIBRARIES dependency, but I will
1004
- be working to replace that with the specific Qt libraries that each class
1005
- needs only. Of course you also need to link to the relevant qgis
1006
- libraries as required by your unit test.
1082
+ Next we need to specify any library dependencies. At the moment classes have
1083
+ been implemented with a catch-all QT_LIBRARIES dependency, but I will be
1084
+ working to replace that with the specific Qt libraries that each class needs
1085
+ only. Of course you also need to link to the relevant qgis libraries as
1086
+ required by your unit test.
1007
1087
1008
1088
```
1009
1089
TARGET_LINK_LIBRARIES(qgis_rasterlayertest ${QT_LIBRARIES} qgis_core)
1010
1090
```
1011
1091
1012
- Next I tell cmake to the same place as the qgis binaries itself. This
1013
- is something I plan to remove in the future so that the tests can
1014
- run directly from inside the source tree.
1092
+ Next I tell cmake to the same place as the qgis binaries itself. This is
1093
+ something I plan to remove in the future so that the tests can run directly
1094
+ from inside the source tree.
1015
1095
1016
1096
```
1017
1097
INSTALL(TARGETS qgis_rasterlayertest RUNTIME DESTINATION ${QGIS_BIN_DIR})
1018
1098
```
1019
1099
1020
- Finally here is where the best magic happens - we register the class with
1021
- ctest. If you recall in the overview I gave in the beginning of this
1022
- section we are using both QtTest and CTest together. To recap, **QtTest** adds a
1023
- main method to your test unit and handles calling your test methods within
1024
- the class. It also provides some macros like QVERIFY that you can use as
1025
- to test for failure of the tests using conditions. The output from
1026
- a QtTest unit test is an executeable which you can run from the command line.
1027
- However when you have a suite of tests and you want to run each executeable
1028
- in turn, and better yet integrate running tests into the build process,
1029
- the **CTest** is what we use. The next line registers the unit test with
1030
- CMake / CTest.
1100
+ Finally here is where the best magic happens - we register the class with
1101
+ ctest. If you recall in the overview I gave in the beginning of this section we
1102
+ are using both QtTest and CTest together. To recap, **QtTest** adds a main
1103
+ method to your test unit and handles calling your test methods within the
1104
+ class. It also provides some macros like QVERIFY that you can use as to test
1105
+ for failure of the tests using conditions. The output from a QtTest unit test
1106
+ is an executeable which you can run from the command line. However when you
1107
+ have a suite of tests and you want to run each executeable in turn, and
1108
+ better yet integrate running tests into the build process, the **CTest** is
1109
+ what we use. The next line registers the unit test with CMake / CTest.
1031
1110
1032
1111
```
1033
1112
ADD_TEST(qgis_rasterlayertest ${QGIS_BIN_DIR}/qgis_rasterlayertest)
1034
1113
```
1035
1114
1036
- The last thing I should add is that if your test requires optional
1037
- parts of the build process (e.g. Postgresql support, GSL libs, GRASS etc.),
1038
- you should take care to enclose you test block inside a IF () block
1039
- in the CMakeLists.txt file.
1115
+ The last thing I should add is that if your test requires optional parts of the
1116
+ build process (e.g. Postgresql support, GSL libs, GRASS etc.), you should take
1117
+ care to enclose you test block inside a IF () block in the CMakeLists.txt file.
1040
1118
1041
1119
1042
1120
== Building your unit test ==
1043
1121
1044
- To build the unit test you need only to make sure that ENABLE_TESTS=true
1045
- in the cmake configuration. There are two ways to do this:
1122
+ To build the unit test you need only to make sure that ENABLE_TESTS=true in the
1123
+ cmake configuration. There are two ways to do this:
1046
1124
1047
1125
1. Run ccmake .. (cmakesetup .. under windows) and interactively set
1048
1126
the ENABLE_TESTS flag to ON.
1049
1127
1. Add a command line flag to cmake e.g. cmake -DENABLE_TESTS=true ..
1050
1128
1051
- Other than that, just build QGIS as per normal and the tests should build
1052
- too.
1129
+ Other than that, just build QGIS as per normal and the tests should build too.
1053
1130
1054
1131
== Run your tests ==
1055
1132
@@ -1059,9 +1136,9 @@ The simplest way to run the tests is as part of your normal build process:
1059
1136
make && make install && make test
1060
1137
```
1061
1138
1062
- The make test command will invoke CTest which will run each test that
1063
- was registered using the ADD_TEST CMake directive described above. Typical
1064
- output from make test will look like this:
1139
+ The make test command will invoke CTest which will run each test that was
1140
+ registered using the ADD_TEST CMake directive described above. Typical output
1141
+ from make test will look like this:
1065
1142
1066
1143
```
1067
1144
Running tests...
@@ -1079,9 +1156,9 @@ Test project /Users/tim/dev/cpp/qgis/build
1079
1156
make: *** [test] Error 8
1080
1157
```
1081
1158
1082
- If a test fails, you can use the ctest command to examine more
1083
- closely why it failed. User the -R option to specify a regex for
1084
- which tests you want to run and -V to get verbose output:
1159
+ If a test fails, you can use the ctest command to examine more closely why it
1160
+ failed. User the -R option to specify a regex for which tests you want to run
1161
+ and -V to get verbose output:
1085
1162
1086
1163
```
1087
1164
[build] ctest -R appl -V
@@ -1123,51 +1200,53 @@ PASS : TestQgsApplication::cleanupTestCase()
1123
1200
1124
1201
```
1125
1202
1126
- Well that concludes this section on writing unit tests in QGIS. We hope you
1127
- will get into the habit of writing test to test new functionality and to
1128
- check for regressions. Some aspects of the test system (in particular the
1129
- CMakeLists.txt parts) are still being worked on so that the testing framework
1130
- works in a truly platform way. I will update this document as things progress.
1203
+ Well that concludes this section on writing unit tests in QGIS. We hope you
1204
+ will get into the habit of writing test to test new functionality and to check
1205
+ for regressions. Some aspects of the test system (in particular the
1206
+ CMakeLists.txt parts) are still being worked on so that the testing framework
1207
+ works in a truly platform way. I will update this document as things
1208
+ progress.
1131
1209
1132
1210
= HIG (Human Interface Guidelines) =
1133
1211
1134
- In order for all graphical user interface elements to appear consistant and
1135
- to all the user to instinctively use dialogs, it is important that the following
1212
+ In order for all graphical user interface elements to appear consistant and to
1213
+ all the user to instinctively use dialogs, it is important that the following
1136
1214
guidelines are followed in layout and design of GUIs.
1137
1215
1138
1216
+ Group related elements using group boxes:
1139
- Try to identify elements that can be grouped together and then use
1140
- group boxes with a label to identify the topic of that group.
1141
- Avoid using group boxes with only a single widget / item inside.
1217
+ Try to identify elements that can be grouped together and then use group
1218
+ boxes with a label to identify the topic of that group. Avoid using group
1219
+ boxes with only a single widget / item inside.
1142
1220
+ Capitalise first letter only in labels:
1143
- Labels (and group box labels) should be written as a phrase with leading capital letter,
1144
- and all remaing words written with lower case first letters
1221
+ Labels (and group box labels) should be written as a phrase with leading
1222
+ capital letter, and all remaing words written with lower case first letters
1145
1223
+ Do not end labels for widgets or group boxes with a colon:
1146
1224
Adding a colon causes visual noise and does not impart additional meaning,
1147
- so dont use them. An exception to this rule is when you have two labels
1148
- next to each other e.g.: Label1 [Plugin Path:] Label2 [/path/to/plugins]
1225
+ so dont use them. An exception to this rule is when you have two labels next
1226
+ to each other e.g.: Label1 [Plugin Path:] Label2 [/path/to/plugins]
1149
1227
+ Keep harmful actions away from harmless ones:
1150
- If you have actions for 'delete', 'remove' etc, try to impose adequate
1151
- space between the harmful action and innocuous actions so that the users
1152
- is less likely to inadvertantly click on the harmful action.
1228
+ If you have actions for 'delete', 'remove' etc, try to impose adequate space
1229
+ between the harmful action and innocuous actions so that the users is less
1230
+ likely to inadvertantly click on the harmful action.
1153
1231
+ Always use a QButtonBox for 'OK', 'Cancel' etc buttons:
1154
- Using a button box will ensure that the order of 'OK' and 'Cancel' etc,
1155
- buttons is consistent with the operating system / locale / desktop
1232
+ Using a button box will ensure that the order of 'OK' and 'Cancel' etc,
1233
+ buttons is consistent with the operating system / locale / desktop
1156
1234
environment that the user is using.
1157
1235
1158
1236
1159
1237
= Authors =
1160
1238
1161
- * Tim Sutton (author and editor)
1162
- * Gary Sherman
1163
- * Marco Hugentobler
1239
+ - Tim Sutton (author and editor)
1240
+ - Gary Sherman
1241
+ - Marco Hugentobler
1242
+ -
1164
1243
1165
1244
Original pages from wiki to deprecate:
1166
1245
1167
- * http://wiki.qgis.org/qgiswiki/CodingGuidelines (./)
1168
- * http://wiki.qgis.org/qgiswiki/CodingStandards (./)
1169
- * http://wiki.qgis.org/qgiswiki/UsingSubversion (./)
1170
- * http://wiki.qgis.org/qgiswiki/DebuggingPlugins
1171
- * http://wiki.qgis.org/qgiswiki/DevelopmentInBranches (./)
1172
- * http://wiki.qgis.org/qgiswiki/SubmittingPatchesAndSvnAccess (./)
1246
+ - http://wiki.qgis.org/qgiswiki/CodingGuidelines (./)
1247
+ - http://wiki.qgis.org/qgiswiki/CodingStandards (./)
1248
+ - http://wiki.qgis.org/qgiswiki/UsingSubversion (./)
1249
+ - http://wiki.qgis.org/qgiswiki/DebuggingPlugins
1250
+ - http://wiki.qgis.org/qgiswiki/DevelopmentInBranches (./)
1251
+ - http://wiki.qgis.org/qgiswiki/SubmittingPatchesAndSvnAccess (./)
1173
1252
0 commit comments