% vim: set textwidth=78 autoindent:

% when the revision of a section has been finalized,
% comment out the following line:
% \updatedisclaimer

\hypertarget{toc1}{}
\section{Τα standard της κωδικοποίησης του QGIS}

Τα επόμενα κεφάλαια παρέχουν πληροφορίες κώδικα για την έκδοση \CURRENT.
Το έγγραφο αυτό ανταποκρίνεται σχεδόν σε \LaTeX~ μετατροπή του αρχείου CODING.t2t
που έρχεται μαζί με τον πηγαίο κώδικα του QGIS απο την 27η του ιουλίου 2010. 

Αυτά τα standards θα έπρεπε να ακολουθηθούν απο όλους τους δημιουργούς κώδικα του QGIS.

\hypertarget{toc2}{}
\subsection{Κλάσεις}
\hypertarget{toc3}{}
\subsubsection{Ονόματα}
Οι κλάσεις στο QGIS ξεκινούν με Qgs και σχηματίζονται χρησιμοποιώντας κεφαλαία αλλά και μικρά γράμματα. 

\begin{verbatim}
Examples:
  QgsPoint
  QgsMapCanvas
  QgsRasterLayer
\end{verbatim}

\hypertarget{toc4}{}
\subsubsection{Μέλη}
Τα ονόματα κλάσεων μελών ξεκινούν με ένα μικρό γράμμα \textit{m} και σχηματίζονται χρησιμοποιώντας μικρά και κεφαλαία γράμματα.

\begin{verbatim}
  mMapCanvas  
  mCurrentExtent
\end{verbatim}

Όλες οι κλάσσεις μέλη θα έπρεπε να είναι private.
\textbf{Οι κλάσεις μέλη συνίσταται έντονα να μην είναι Public}

\hypertarget{toc5}{}
\subsubsection{Συναφής λειτουργίες (Accessor functions)}
Οι τιμές των κλάσεων μελών θα έπρεπε να παίρνονται απο τις συναφείς λειτουργίες. Η λειτουργία πρέπει να ονομάζεται χωρίς το επιπρόσθετο get. Οι συναφείς λειτουργίες για τα δύο παραπάνω private  μέλη θα ήταν: 

\begin{verbatim}
  mapCanvas()
  currentExtent()
\end{verbatim}

\hypertarget{toc6}{}
\subsubsection{Λειτουργίες (Functions)}
Τα ονόματα των λειτουργιών ξεκινούν με ένα μικρό γράμμα και σχηματίζονται χρησιμοποιώντας μικρούς αλλα και μεγάλους χαρακτήρες. Το όνομα της λειτουργίας θα έπρεπε να μεταφέρει κάτι σχετικά με το σκοπό της λειτουργίας.

\begin{verbatim}
  updateMapExtent()
  setUserOptions()
\end{verbatim}

\hypertarget{toc7}{}
\subsection{Ο σχεδιαστής Qt}
\hypertarget{toc8}{}
\subsubsection{Παραγόμενες  κλάσεις}
Οι κλάσεις του QGIS που παράγονται απο αρχεία (ui) του σχεδιαστή Qt θα πρέπει να έχουν ένα επίθημα
\textit{Base}. Αυτό αναγνωρίζει την κλάση ως μία παραγόμενη κλάση βάσης.

\begin{verbatim}
Examples:
  QgsPluginManagerBase
  QgsUserOptionsBase
\end{verbatim}
\hypertarget{toc9}{}
\subsubsection{Διάλογοι}

Όλοι οι διάλογοι θα έπρεπε να παρέχουν τα ακόλουθα:

\begin{itemize}
\item Εργαλεία βοήθειας για όλα το εικονίδια της εργαλειοθήκης και άλλα σχετικά widget
\item “Τι είναι αυτή η βοήθεια” για \textbf{όλα} τα widget στο διάλογο
\item Ένα προαιρετικό (παρ'όλα αυτά πολύ προτεινόμενο) ευαίσθητου περιεχομένου κουμπί \textit{Help} το οποίο κατευθύνει το χρήστη στην κατάλληλη σελίδα βοηθείας ξεκινώντας τον φυλλομετρητή περιήγησης
\end{itemize}

\hypertarget{toc10}{}
\subsection{Αρχεία C++}
\hypertarget{toc11}{}
\subsubsection{Ονόματα}
Η εφαρμογή C++ και τα προσαγωγά αρχεία (header files) θα πρέπει να έχουν μια .cpp και .h κατάληξη αντίστοιχα. Το όνομα αρχείου θα πρέπει να είναι με μικρούς χαρακτήρες και, στην περίπτωση των κλάσεων, ταιριάξτε το όνομα της κλάσης.

\begin{verbatim}
Example:
  Class QgsFeatureAttribute source files are 
    qgsfeatureattribute.cpp and qgsfeatureattribute.h
\end{verbatim}

/!$\backslash$ \textbf{Σημείωση:} σε περίπτωση που δεν είναι ξεκάθαρο απο την παραπάνω δήλωση, για να ταιριάξει ένα όνομα αρχείου με το όνομα μιας κλάσης εννοείται ότι κάθε κλάση πρέπει να δηλωθεί και να εφαρμοστεί στο δικό της αρχείο. Έτσι για νέους χρήστες είναι πιο εύκολο να αναγνωρίσουν τον κώδικα που σχετίζεται με συγκεκριμένες κλάσεις.

\hypertarget{toc12}{}
\subsubsection{Καθιερωμένη επικεφαλίδα και άδεια}
Κάθε πηγαίο αρχείο θα πρέπει να περιέχει σχεδιασμένο ένα τμήμα επικεφαλίδας μετά το επόμενο παράδειγμα:

\begin{verbatim}
/***************************************************************************
    qgsfield.cpp - Describes a field in a layer or table
     --------------------------------------
    Date                 : 01-Jan-2004
    Copyright            : (C) 2004 by Gary E.Sherman
    Email                : sherman at mrcc.com
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
\end{verbatim}

\hypertarget{toc13}{}
\subsubsection{Λέξη κλειδι SVN}
Κάθε πηγαίο αρχείο πρέπει να περιέχει τη λέξη-κλειδί \$Id\$. Αυτή θα επεκταθεί απο το SVN έτσι ώστε να περιέχει χρήσιμες πληροφορίες σχετικά με το αρχείο, την αναθεώρηση, τον τελευταίο χρήστη που ασχολήθηκε με αυτό, και την ημερομηνία/ώρα της τελευταίας εισόδου.

Βάλτε τη λεξη-κλειδί ακριβώς μετά τη standard επικεφαλίδα/άδεια που βρίσκεται στην κορυφή κάθε πηγαίου αρχείου:

\begin{verbatim}
  /* $Id$ */
\end{verbatim}

Χρειάζεται επίσης να θέσετε

svn propset svn:keywords "Id"

για τα καινούγρια αρχεία.

\hypertarget{toc14}{}
\subsection{Ονόματα μεταβλητών}
Τα ονόματα των μεταβλητών ξεκινούν με μικρό χαρακτήρα και σχηματίζονται χρησιμοποιώντας μικρούς αλλά και μεγάλους χαρακτήρες.

\begin{verbatim}
Examples:
  mapCanvas
  currentExtent
\end{verbatim}

\hypertarget{toc15}{}
\subsection{Αριθμημένοι τύποι}
Οι αριθμημένοι τύποι θα έπρεπε να ονομάζονται με λέξεις οι φράσεις οι οποίες ενώνονται χωρίς διαστήματα, με το αρχικό γράμμα κάθε στοιχείου να είναι κεφαλαίο (CamelCase) π.χ.:

\begin{verbatim}
    enum UnitType
    {
      Meters,
      Feet,
      Degrees,
      UnknownUnit
    } ;
\end{verbatim}

Μη χρησιμοποιείται γενικούς τύπους ονομάτων που θα έρθουν σε αντίθεση με άλλους τύπους π.χ. χρησιμοποιήστε καλύτερα "UnkownUnit" 
αντί για "Unknown"

\hypertarget{toc16}{}
\subsection{Γενικές σταθερές}
Οι γενικές σταθερές θα πρέπει να γράφονται με κεφαλαίους χαρακτήρες διαχωρισμένους με μία κάτω παύλα π.χ.:

\begin{verbatim}
const long GEOCRS_ID = 3344;
\end{verbatim}

\hypertarget{toc17}{}
\subsection{Επεξεργασία}
Κάθε επεξεργαστής κειμένου/IDE μπορεί να χρησιμοποιηθεί για την επεξεργασία κώδικα QGIS, με την προϋπόθεση ότι οι παρακάτω απαιτήσεις θα ισχύουν.

\hypertarget{toc18}{}
\subsubsection{Στηλοθέτες}
Θέστε τον επεξεργαστή σας έτσι ώστε να εξομοιώνει τους στηλοθέτες με διαστήματα. Το διάστημα στηλοθέτησης θα πρέπει να αντιστοιχεί σε 2 διαστήματα.

\hypertarget{toc19}{}
\subsubsection{Εσοχές κειμένου}
Ο πηγαίος κώδικας θα πρέπει να έχει εσοχές έτσι ώστε να βελτιώνεται η αναγνωσιμότητα. Υπάρχει ένα .indent.pro αρχείο στον QGIS src κατάλογο που εμπεριέχει τους “διακόπτες” που χρησιμοποιούνται όταν φτιάχνουμε εσοχές στον κώδικα χρησιμοποιώντας το αντίστοιχο GNU πρόγραμμα. Αν δεν χρησιμοποιήσετε αυτό το αντίστοιχο GNU πρόγραμμα, θα πρέπει να προσομοιώσετε αυτές τις ρυθμίσεις..

\hypertarget{toc20}{}
\subsubsection{Παρενθέσεις}
Οι παρενθέσεις πρέπει να ξεκινούν απο τη γραμμή που ακολουθείται απο έκφραση:

\begin{verbatim}
  if(foo == 1)
  {
    // do stuff
    ...
   }else
  {
    // do something else
    ...
  }
\end{verbatim}

Υπάρχει ένα  scripts/prepare-commit.sh που προσέχει τα αλλαγμένα αρχεία και τα “ξαναδιπλώνει” χρησιμοποιώντας το astyle. Αυτό πρέπει να τρέξει πριν γίνει οτιδήποτε.

Καθώς οι πιο καινούργιες εκδόσεις του astyle εγκολπώνουν καλύτερα απο την έκδοση που χρησιμοποιήθηκε για να κάνει μια πλήρη εγκόλπωση του πηγαίου, το script χρησιμοποιεί μια παλιά έκδοση του astyle, που συμπεριλαμβάνουμε στα αποθετήριά μας.

\hypertarget{toc21}{}
\subsection{Συμβατότητα API}
Για το QGIS 1.0 θα παρέχουμε ένα σταθερό, αντιστρόφως συμβατό API. Αυτό θα παρέχει μια σταθερή βάση για όσους θα αναπτύσουν αντίθετα, ξέροντας ότι ο κώδικάς τους θα δουλέψει αντίθετα σε οποιαδήποτε απο τις 1.x QGIS εκδόσεις (παρολο που η σύνταξη μπορεί να απαιτηθεί ξανα). Καθαρισμός στο API θα πρεπε να γίνει με έναν τρόπο παρόμοιο με αυτό που αναπτύσεται στην Trolltech π.χ..

\begin{verbatim}
class Foo 
{
  public:
    /** This method will be deprecated, you are encouraged to use 
      doSomethingBetter() rather.
      @see doSomethingBetter()
     */
    bool doSomething();

    /** Does something a better way.
      @note This method was introduced in QGIS version 1.1
     */
    bool doSomethingBetter();

}
\end{verbatim}

\hypertarget{toc22}{}
\subsection{Στυλ κωδικοποίησης}
Εδώ περιγράφονται μερικές προγραμματιστικές συμβουλές και βοήθειες οι οποίες ευελπίστως θα μειώσουν τα λάθη, το χρόνο ανάπτυξης και τη συντήρηση.

\hypertarget{toc23}{}
\subsubsection{Οπουδήποτε δυνατόν γενικευμένος κώδικας}
\begin{verbatim}
Αν αποκόπτετε και αντιγράφετε κώδικα, ή αλλιώς γράφετε το ίδιο πράγμα παρα πάνω απο μία φορά, σκεφτείτε να παγειώσετε τον κώδικα σε μία μοναδική λειτουργία.
\end{verbatim}

Αυτό θα:

\begin{itemize}
\item επιτρέψει αλλαγές να γίνουν σε ένα μέρος αντί για πολλά
\item βοηθήσει στην αποφυγή φουσκομένου κώδικα
\item Το κάνει πιο δύσκολο για πολλαπλά αντίγραφα να αναπτύξουν διαφορές με την πάροδο του χρόνου, κάνοντας έτσι πιο δύσκολη την κατανόηση και τη διατήρηση για τους άλλους
\end{itemize}

\hypertarget{toc24}{}
\subsubsection{Να προτιμάτε να έχετε τις σταθερές πρώτες σε προϋποθέσεις}
Να προτιμάτε να βάζετε τις σταθερές πρώτες σε προϋποθέσεις. 

\begin{verbatim}
"0 == value" instead of "value == 0"
\end{verbatim}

Αυτό θα αποτρέψει τους προγραμματιστές απο το να χρησιμοποιήσουν κατά λάθος το “=” ενώ θα ήθελαν να χρησιμοποιήσουν το “==” το οποίο μπορεί να εισάγει πολύ δυσδιάκριτα λογικά bugs. Ο συντάκτης θα δημιουργήσει ένα λάθος αν κατα λάθος χρησιμοποιήσετε “=” αντί για “==” για συγκρίσεις απο τη στιγμή που οι σταθερές δεν μπορούν “κληρονομημένα” να πάρουν τιμές.

\hypertarget{toc25}{}
\subsubsection{Τα διαστήματα μπορεί να γίνουν οι καλύτεροι σας φίλοι}
Προσθέτοντας διαστήματα ανάμεσα στους τελεστές, τα στοιχεία και τις λειτουργίες κάνει πιο εύκολο στους ανθρώπους να μεταφράσουν τον κώδικα.

Είναι πιο εύκολο να διαβαστεί αυτό:

\begin{verbatim}
if (!a&&b)
\end{verbatim}

ή αυτό:

\begin{verbatim}
if ( ! a && b )
\end{verbatim}

\hypertarget{toc26}{}
\subsubsection{Προσθέστε σχόλια αναγνώρισης της πορείας}
Η προσθήκη σχολίων στο τέλος των λειτουργιών, η δόμηση και εφαρμογή των κλάσεων κάνει πιο εύκολη την εύρεση τους αργότερα.

Θεωρείστε ότι είστε στο τέλος ενός πηγαίου αρχείου και χρειάζεται να βρείτε μια μεγάλη λειτουργία – χωρίς αυτά τα σχόλια ανίχνευσης θα πρέπει να ανεβείτε προς τα πάνω όλη τη λειτουργία για να βρείτε το όνομα της. Βέβαια αν θέλετε να βρείτε την αρχή της λειτουργίας τότε είναι εντάξει. Αλλά τι θα γινόταν αν σας ενδιέφερε ο κώδικας κοντά στο τέλος; Θα έπρεπε να ανεβείτε προς τα πάνω και μετά πάλι προς τα κάτω για να βρείτε το επιθυμητό κομμάτι.

π.χ.,

\begin{verbatim}
void foo::bar()
{ 
    // ... imagine a lot of code here 
} // foo::bar()
\end{verbatim}

\hypertarget{toc27}{}
\subsubsection{6.9.5 Χρησιμοποιήστε παρενθέσεις ακόμα και για στοιχεία κώδικα μίας γραμμής}
Η χρήση παρενθέσεων σε if/then κομμάτια κώδικα ή παρεμφερείς δομήσεις κώδικα ακόμα και για στοιχεία κώδικα μιας γραμμής σημαίνει ότι η προσθήκη ενός ακόμα στοιχείου είναι λιγοτερο πιθανό να προκαλέσει κατεστραμένο κώδικα.

Θεωρείστε:

\begin{verbatim}
  if (foo)
    bar();
 else
    baz();
\end{verbatim}

Η προσθήκη κώδικα μετά το bar() ή το baz() χωρίς την προσθήκη παρενθέσεων θα προκαλούσε σπασμένο κώδικα. Παρ'όλο που οι περισσότεροι προγραμματιστές θα το κάναν αυτό, μερικοί θα ξεχνούσαν να το κάνουν απο βιασύνη.

Έτσι προτιμήστε αυτό:

\begin{verbatim}
 if (foo)
 {
   bar();
 }
 else
 { 
    baz();
 } 
\end{verbatim}

\hypertarget{toc28}{}
\subsubsection{Προτεινόμενα βιβλία}
\begin{itemize}
\item \htmladdnormallink{Effective C++}{http://www.awprofessional.com/title/0321334876}, Scott Meyers
\item \htmladdnormallink{More Effective C++}{http://www.awprofessional.com/bookstore/product.asp?isbn=020163371X\&rl=1}, Scott Meyers
\item \htmladdnormallink{Effective STL}{http://www.awprofessional.com/title/0201749629}, Scott Meyers
\item \htmladdnormallink{Design Patterns}{http://www.awprofessional.com/title/0201634988}, GoF
\end{itemize}


Διαβάστε επίσης και το παρακάτω άρθρο του Qt Quarterly απο \\
\url{http://doc.trolltech.com/qq/qq13-apis.html}


\hypertarget{toc29}{}
\section{Πρόσβαση SVN}
Αυτή η σελίδα περιγράφει πως να ξεκινήσετε χρησιμοποιώντας το αποθετήριο του QGIS Subverion

\hypertarget{toc30}{}
\subsection{Έχοντας πρόσβαση στο αποθετήριο}
Για να δείτε το QGIS HEAD:

\begin{verbatim}
  svn --username [your user name] co https://svn.osgeo.org/qgis/trunk/qgis
\end{verbatim}

\hypertarget{toc31}{}
\subsection{Ανώνυμη είσοδος}
Μπορείτε να χρησιμοποιήσετε τις ακόλουθες εντολές για κάνετε έναν ανώνυμο έλεγχο απο το αποθετήριο του QGIS sybversion. Σημείωστε ότι προτείνουμε να χρησημοιήσετε την κύρια γραμμή ανάπτυξης (trunk) (εκτός αν είστε προγραμματιστής ή είναι πραγματικά ανάγκη να έχετε τις τελευταίες αλλαγές και δεν σας ενοχλούν τα πολλά “κρασαρίσματα”!).

Πρέπει να έχετε εγκατεστημένο ένα subverion client πριν ελέγξετε τον κώδικα. Δείτε την ιστοσελίδα του Subverion για περισσότερες λεπτομέρειες. Η σελίδα των Συνδέσμων περιέχει μια καλή επιλογή των SVN clients για διάφορες πλατφόρμες.

Για να ελέγξετε

\begin{verbatim}
  svn co https://svn.osgeo.org/qgis/branches/<branch name>
\end{verbatim}

Για να ελέγξετε τη σταθερή SVN γραμμή ανάπτυξης:

\begin{verbatim}
  svn co https://svn.osgeo.org/qgis/trunk/qgis qgis_trunk
\end{verbatim}

\textbf{Σημείωση:} αν βρίσκεστε πίσω απο έναν διακομηστή εξουσιοδότησης (proxy server), επεξεργαστείτε το αρχείο \~{}/subversion/servers
για να καθορίσετε τις ρυθμίσεις εξουσιοδήτησης!

\textbf{Σημείωση:} Στο QGIS κρατάμε τον πιο σταθερό κώδικα στην έκδοση 1\_0 branch.
Η γραμμή ανάπτυξης περιέχει κώδικα για τη σειρά “ασταθών” εκδόσεων. Περιοδικά θα τιτλοφορούμε μια έκδοση της γραμμής ανάπτυξης και μετά θα συνεχίζουμε την σταθεροποίηση και την επιλεκτική ενσωμάτωση καινούργιων χαρακτηριστικών στη γραμμή ανάπτυξης.

Δείτε το αρχείο εγκατάστασης (ΙNSTALL file) στον πηγαίο φάκελο ακριβής οδηγίες πάνω στο χτίσιμο εκδόσεων ανάπτυξης. 

\hypertarget{toc32}{}
\subsection{Πηγές εγγράφων του QGIS}
Αν σας ενδιαφέρει να δείτε τις πηγές εγγράφων του QGIS:

\begin{verbatim}
  svn co https://svn.osgeo.org/qgis/docs/trunk qgis_docs
\end{verbatim}

Μπορείτε επίσης να ρίξετε μια ματιά στο DocumentationWritersCorner για περισσότερες πληροφορίες.

\hypertarget{toc33}{}
\subsection{Έγγραφα για το SVN}
Το αποθετήριο είναι οργανωμένο όπως παρακάτω:

\htmladdnormallink{http://wiki.qgis.org/images/repo.png}{http://wiki.qgis.org/images/repo.png}

Δείτε το βιβλίο του Subversion 
\htmladdnormallink{http://svnbook.red-bean.com}{http://svnbook.red-bean.com} 
για περισσότερες πληροφορίες σχετικά με το πως να εξειδικευτείτε στο SVN.

\hypertarget{toc34}{}
\subsection{Ανάπτηξη σε παρακλάδια}
\hypertarget{toc35}{}
\subsubsection{7.5.1Σκοπός}
The complexity of the QGIS source code has increased considerably during the
last years. Therefore it is hard to anticipate the side effects that the
addition of a feature will have. In the past, the QGIS project had very long
release cycles because it was a lot of work to reetablish the stability of the
software system after new features were added. To overcome these problems, QGIS
switched to a development model where new features are coded in svn branches
first and merged to trunk (the main branch) when they are finished and stable.
This section describes the procedure for branching and merging in the QGIS
project.

\hypertarget{toc36}{}
\subsubsection{Διαδικασία}
\begin{itemize}
\item \textbf{Αρχική ανακοίνωση στην ταχυδρομική λίστα:}
Πριν ξεκινήσετε, κάντε μια ανακοίνωση στην ταχυδρομική λίστα για να δείτε αν κάποιος άλλος προγραμματιστής εργάζεται ήδη στο συγκεκριμένο αντικείμενο. Επίσης επικοινωνήστε με τον τεχνικό σύμβουλο της εξεταστικής επιτροπής του σχεδίου (PSC). Αν το καινούργιο αντικείμενο απαιτεί κάποια αλλαγή στην αρχιτεκτονική του QGIS, χρειάζεται μια αίτηση για έκφραση άποψης (RFC). 

\item \textbf{Δημιουργήστε ένα παρακλάδι:} 
Δημιουργήστε ένα καινούργιο svn παρακλάδι για την ανάπτυξη ενός καινούργιου αντικειμένου (βλ. Χρησιμοποιώντας το Subversion για τη σύνταξη του svn). Τώρα μπορείτε να ξεκινήσετε την ανάπτυξη.

\item \textbf{Συγχωνεύστε απο τη γραμμή ανάπτυξης τακτικά:}
Συνίσταται να συγχωνεύετε τις αλλαγές στη γραμμή ανάπτυξης στο παρακλάδι τακτικά. Έτσι γίνεται ευκολότερο να συμπτυχθεί ξανά το παρακλάδι με τη γραμμή ανάπτυξης αργότερα.

\item \textbf{Τεκμηρίωση - έγγραφα στο wiki:} 
Συνίσταται επίσης να καταγράψετε τις σχεδιασμένες αλλαγές και τη τρέχουσα κατάσταση της εργασίας σε μία wiki σελίδα.

\item \textbf{Έλεγχος πριν απο τη σύμπτηξη πάλι με τη γραμμή ανάπτυξης:} 
Όταν τελειώσετε με το καινούργιο αντικέινενο και είστε ευχαριστημένοι με τη σταθερότητα, κάντε μια ανακοίνωση στη λίστα των προγραμματιστών. Πριν απο τη σύμπτηξη, οι αλλαγές θα ελεγχούν απο προγραμματιστές και χρήστες. Τα δυαδικά πακέτα (ειδικά για τα OsX και τα Windows) θα αναπαραχθούν για να συμπεριλάβουν επίσης άτομα που δεν είναι προγραμματιστές. Εν τέλει, ένα καινούργιο Στοιχείο θα ανοιχθεί. Όταν δεν θα έχουν μείνει άλλα θέματα άνοιχτα, ο τεχνικός σύμβουλος θα ενώσει τις αλλαγές στη γραμμή ανάπτυξης.
\end{itemize}


\hypertarget{toc37}{}
\subsubsection{Δημιουργώντας ένα παρακλάδι}
Προτιμούμε η ανάπτυξη καινούργιων στοιχείων να γίνεται εκτός της γραμμής ανάπτυξης έτσι ώστε η γραμμή ανάπτυξης να παραμένει σε σταθερή κατάσταση. 
Για να δημιουργήσετε ένα παρακλάδι χρησιμοποιήστε την παρακάτω εντολή:

\begin{verbatim}
svn copy https://svn.osgeo.org/qgis/trunk/qgis \
https://svn.osgeo.org/qgis/branches/qgis_newfeature
svn commit -m "New feature branch"
\end{verbatim}

\hypertarget{toc38}{}
\subsubsection{Συμπτείξτε τακτικά απο τη γραμμή ανάπτυξης στο παρακλάδι}
Όταν δουλεύετε σε ένα παρακλάδι θα πρέπει τακτικά να συμπτήσετε τη γραμμή ανάπτυξης μέσα του έτσι ώστε το παρακλάδι να μην αποκλίνει παραπάνω απ'όσο χρειάζεται. Στον τελευταίο προς τα πάνω κατάλογο του παρακλαδιού σας, πρώτα πληκτρολογήστε ‘svn info‘ για να καθορίσετε τους αριθμούς αναθεώρησης του παρακλαδιού που θα παράγει αποτέλεσμα όπως το παρακάτω::

\begin{verbatim}
timlinux@timlinux-desktop:~/dev/cpp/qgis_raster_transparency_branch svn info
Caminho: .
URL: https://svn.osgeo.org/qgis/branches/raster_transparency_branch
Raiz do Repositorio: https://svn.osgeo.org/qgis
UUID do repositorio: c8812cc2-4d05-0410-92ff-de0c093fc19c
Revisao: 6546
Tipo de No: diretorio
Agendado: normal
Autor da Ultima Mudanca: timlinux
Revisao da Ultima Mudanca: 6495
Data da Ultima Mudanca: 2007-02-02 09:29:47 -0200 (Sex, 02 Fev 2007)
Propriedades da Ultima Mudanca: 2007-01-09 11:32:55 -0200 (Ter, 09 Jan 2007)
\end{verbatim}

Ο δεύτερος αριθμός αναθεώρησης δείχνει τον αριθμό αναθεώσης της αρχικής αναθεώρησης του παρακλαδιού και ο πρώτος την τρέχουσα αναθεώρηση. Μπορείτε να δείτε τη σύμπτηξη με τον παρακάτω τρόπο:

\begin{verbatim}
svn merge --dry-run -r 6495:6546 https://svn.osgeo.org/qgis/trunk/qgis
\end{verbatim}

Αφού είστε ευχαριστημένοι με τις αλλαγές που θα προκύψουν κάντε τη σύμπτηξη όπως παρακάτω:

\begin{verbatim}
svn merge -r 6495:6546 https://svn.osgeo.org/qgis/trunk/qgis
svn commit -m "Merged upstream changes from trunk to my branch"
\end{verbatim}

\hypertarget{toc39}{}
\subsection{Υποβάλλοντας τα Patches}
Υπάρχουν μερικές οδηγίες που θα σας βοηθήσουν να βάλετε τα patches σας στο QGIS εύκολα, και θα μας βοηθήσει να διευθετήσουμε τα patches που στέλνονται εύκολα.

\hypertarget{toc40}{}
\subsubsection{Ονομασία των patch αρχείων}
Αν το patch είναι διόρθωση για ένα συγκεκριμένο patch, παρακαλούμε ονομάστε το αρχείο με τον αριθμό του bug μέσα, π.χ.  \textbf{bug777fix.diff},  και επισυνάψτε το στην αρχική αναφορά των bug στο  trac (\htmladdnormallink{https://trac.osgeo.org/qgis/}{https://trac.osgeo.org/qgis/}).

Αν το bug είναι μια αναβάθμιση ή ενα καινούργιο αντικείμενο, συνήθως είναι καλή ιδέα να δημιουργήσετε ένα εισητήριο στο trac (\htmladdnormallink{https://trac.osgeo.org/qgis/}{https://trac.osgeo.org/qgis/}) και μετά να επισυνάψετε 

\hypertarget{toc41}{}
\subsubsection{Δημιουργήστε το patch στον πιο πάνω πηγαίο επίπεδο του QGIS καταλόγου}
Αυτό το κάνει πιο εύκολο για μας να εφαρμόσουμε τα patch απο τη στιγμή που δεν χρειάζεται να πλοηγηθούμε σε ένα συγκεκριμένο μέρος στον πηγαίο αρχικό κατάλογο για να εφαρμόσουμε το patch. Επίσης όταν λαμβάνω patches συνήθως τα αξιολογώ χρησιμοποιώντας το kompare, και έχοντας το patch απο τον πιο πάνω κατάλογο κάνει αυτή τη δουλειά πιο εύκολη. Παρακάτω είναι ένα παράδειγμα σχετικά με το πως μπορείτε να συμπεριλάβετε πολλαπλά αλλαγμένα αρχεία μέσα στο patch σας απο τον κατάλογο που βρίσκεται στην κορυφή:

\begin{verbatim}
cd qgis
svn diff src/ui/somefile.ui src/app/somefile2.cpp > bug872fix.diff
\end{verbatim}

\hypertarget{toc42}{}
\subsubsection{Συμπεριλαμβάνοντας στο patch αρχεία που δεν ελέγχονται απο έκδοση}
Αν οι βελτιώσεις σας συμπεριλαμβάνουν καινούργια αρχεία που δεν υπάρχουν ακόμη στο αποθετήριο, θα πρέπει να επισημάνετε στο svn ότι χρειάζεται να προστεθούν πριν αναπαράγετε το patch σας π.χ.

\begin{verbatim}
cd qgis
svn add src/lib/somenewfile.cpp
svn diff > bug7887fix.diff
\end{verbatim}

\hypertarget{toc43}{}
\subsubsection{Κάνοντας το patch σας παρατηρήσιμο}
Οι προγραμματιστές του QGIS είναι πολυάσχολοι. Πράγματι κάνουμε έλεγχο στα εισερχόμενα patches στις αναφορές των bug αλλά μερικές φορές μας ξεφεύγουν πράγματα. Μην προσβληθείτε ή ενοχληθείτε. Προσπαθείστε να βρείτε έναν προγραμματιστή να σας βοηθήσει – χσηριμοποιώντας το Οργανόγραμμα του Project στη σελίδα http://www.qgis.org/wiki/Project_Organigram και επικοινωνήστε μαζί τους ρωτώντας τους αν μπορούν να ρίξουν μια ματιά στο patch σας. Αν δεν λάβετε καμία απάντηση, μπορείτε να κλιμακώσετε το ερώτημά σας σε ένα απο τα μέλη της Οργανωτικής Επιτροπής (πληροφορίες επικοινωνίας είναι διαθέσιμες επίσης στο “Οργανόγραμμα του Project”). 

\hypertarget{toc44}{}
\subsubsection{Προγραμματισμένη επιμέλεια}
Τo QGIS είναι αδειοδοτημένο υπο την GPL. Θα πρέπει να κάνετε οποιαδήποτε προσπάθεια έτσι ώστε να σιγουρευτείτε ότι θα υποβάλετε μόνο τα patches που δεν είναι βεβαρημένα με αντικρουόμενα πνευματικά διακαιώματα. Επίσης μην υποβάλετε κώδικα τον οποίο δεν θέλετε να είναι διαθέσιμος υπο την GPL άδεια.

\hypertarget{toc45}{}
\subsection{Αποκτώντας SVN δικαιώματα γραψίματος}
Η πρόσβαση γραψίματος στον πηγαίο κατάλογο του QGIS γίνεται με πρόσκληση. Τυπικά, όταν κάποιο άτομο υποβάλει μερικά (δεν υπάρχει συγκεκριμένος αριθμός εδώ) ουσιώδη patches τα οποία υποδυκνείουν ουσιώδη επάρκεια και κατανόηση της C++ και της QGIS συμβατότητας κωδικοποίησης, ένα απο τα μέλη της Οργανωτικής Επιτροπής ή άλλοι υπάρχοντες προγραμματιστές μπορούν να υποδείξουν αυτό το άτομο στην Οργανωτική Επιτροπή πρόσβασης εγγραφής. Ο υποστηρικτής υποψηφιοτητας θα πρέπει να δώσει μια βασική προωθητική παράγραφο του γιατί πιστεύουν ότι αυτό το άτομο πρέπει να έχει πρόσβαση εγγραφής. Σε μερικές περιπτώσεις θα παρέχουμε πρόσβαση γραψίματος σε μη προγραμματιστές της C++ π.χ. για μεταφραστές και κειμενογράφους. Σε αυτές τις περιπτώσεις, το άτομο θα έχει ακόμα την υποδυκνειόμενη ικανότητα να υποβάλει patches και ιδανικά θα πρέπει να έχει υποβάλει μερικά ουσιώδη patches τα οποία υποδυκνείουν την κατανόηση τους στη μετατροπή του κώδικα βάσης να σπάσει οτιδήποτε κλπ .

\hypertarget{toc46}{}
\subsubsection{Διαδικασία αφ'ότου έχετε αποκτήσει πρόσβαση}
Ελέγξτε τις πηγές: 

\begin{verbatim}
svn co https://svn.osgeo.org/qgis/trunk/qgis qgis
\end{verbatim}

Χτίστε τον πηγαίο κώδικα (δείτε το έγγραφο INSTALL για λεπτομερείς οδηγίες)

\begin{verbatim}
cd qgis
mkdir build
ccmake ..    (set your preferred options)
make
make install  (maybe you need to do with sudo / root perms)
\end{verbatim}

Κάντε τις αλλαγές σας

\begin{verbatim}
cd ..
\end{verbatim}

Κάντε τις αλλαγές σας στους πηγαίους κώδικες. Πάντα να ελέγχετε οτι τα πάντα συντάσονται πριν κάνετε οποιαδήποτε αποθήκευση. Προσπαθείτε να έχετε επίγνωση πιθανών σπασιμάτων που οι αποθηκεύσεις μπορεί να προκαλέσουν για άτομα τα οποία χτίζουν σε άλλες πλατφόρμες και με παλαιότερες / νεότερες εκδόσεις βιβλιοθηκών.

Προσθέστε αρχεία (αν έχετε οποιαδήποτε καινούργια αρχεία). Η εντολή κατάστασης του SVN για να ελέγξετε γρήγορα αν έχετε προσθέσει καινούργια αρχεία.

\begin{verbatim}
svn status src/pluguns/grass/modules
\end{verbatim}

Τα αρχεία που βρίσκονται στη λίστα με ? απο μπροστά δεν βρίσκονται στο SVN και πιθανώς χρειάζεται να προστεθούν απο εσάς:

\begin{verbatim}
svn add src/pluguns/grass/modules/foo.xml
\end{verbatim}

Αποθηκεύστε τις αλλαγές σας

\begin{verbatim}
svn commit src/pluguns/grass/modules/foo.xml
\end{verbatim}

Ο επεξεργαστής κειμένου (όπως έχει οριστεί στη μεταβλητή περιβάλλοντος \$EDITOR) θα εμφανιστεί και θα έπρεπε να κάνετε ένα σχόλιο στην αρχή του αρχείου (πάνω απο την περιοχή που λέει “don't change this”). Βάλτε ένα περιγραφικό σχόλιο και καλύτερα κάντε μερικές μικρές αποθηκεύσεις αν οι αλλαγές γύρα απο έναν αριθμό αρχείων δεν σχετίζονται. Αντιστρόφως, προτιμούμαι να ομαδοποιείτε σχετιζόμενες αλλαγές σε μία μοναδική αποθήκευση.

Αποθηκεύστε και κλείστε τον επεξεργαστή κειμένου. Την πρώτη φορά που θα το κάνετε αυτό, θα παραπεμφθείτε να βάλετε το όνομα χρήστη και τον κωδικό σας. Χρησιμοποιήστε τα ίδια που είχατε στον trac λογαριασμό σας.


\hypertarget{toc47}{}
\section{Δοκιμή μονάδας}
Απο το Νοέμβριο του 2007 απαιτούμε όλα τα καινούργια αντικείμενα που πηγαίνουν στη γραμμή ανάπτυξης να συνοδεύονται απο μία μονάδα ελέγχου. Αρχικά έχουμε περιορίσει αυτή την απαίτηση στο \textbf{qgis\_core}, και θα επεκτείνουμε αυτή την απαίτηση σε άλλα μέρη του κώδικα βάσης όταν οι άνθρωποι οικειοποιηθούν τις διαδικασίες για τον έλεγχο μονάδας που εξηγούνται στα κεφάλαια που ακολουθούν.

\hypertarget{toc48}{}
\subsection{Το πλαίσιο ελέγχου του QGIS – μία επισκόπηση}
Ο έλεγχος μονάδας διεξάγεται χρησιμοποιώντας ένα συνδιασμό απο QTestLib (η βιβλιοθήκη ελέγχου του Qt) και το Ctest ( ένα πλαίσιο για σύνταξη και διεξαγωγή ελέγχων ως μέρος της διαδικασίς του Cmake). Ας κάνουμε μια επισκόπηση της διαδικασίας πριν ανατρέξουμε σε λεπτομέρειες:

\begin{itemize}
\item \textbf{Υπάρχει κάποιος κώδικας που θέλετε να ελέγξετε}, π.χ. μία κλάσση ή μία λειτουργία. Οι ακραίοι υποστηρικτές του προγραμματισμού προτείνουν ότι ο κώδικας δεν θα έπρεπε καν να γραφεί όταν αρχίζετε να χτίζετε τους ελέχγους σας, και έπειτα καθώς θα εφαρμόζετε τον κώδικά σας μπορείτε αμέσως να αξιολογήσετε κάθε νεό λειτουργικό μέρος που προσθέτετε με τον έλεγχο σας. Στην πρακτική πιθανόν να χρειαστεί να γράψετε tests για προϋπάρχων κώδικα στο QGIS απο τη στιγμή που αρχίζουμε με ένα πλαίσιο ελέγχου καλά αφού πολλυ εφαρμόσιμη λογική έχει ήδη εφαρμοστεί.

\item \textbf{Δημιουργείτε μία μονάδα ελέγχου.} Αυτό γίνεται υπο το $<$QGIS Source Dir$>$/tests/src/core 
   στην περίπτωση του core lib. Ο έλεγχος βασικά είναι ενας πελάτης-client ο οποίος δημιουργεί ένα αντικείμενο κλάσης και καλεί μερικές μεθόδους σε αυτή την κλάση. Θα ελέγξει το αποτέλεσμα απο κάθε μέθοδο για να σιγουρευτεί για ότι ταιριάζει την αναμενόμενη τιμή. Αν οποιοδήποτε απο τα καλέσματα αποτύχει, μονάδα θα αποτύχει επίσης.

\item \textbf{Συμπεριλάβετε τα QtTestLib macros στην κλαση ελέγχου.} Αυτό το macro επεξεργάζεται απο τον συντάκτη αντικειμένων meta (meta object compiler – moc) και επεκτείνει την κλάση ελέγχου σε μία εφαρμογή. 

\item \textbf{Προσθέστε ένα κεφάλαιο CmakeLists.txt} στον κατάλογο ελέγχων που θα χτίσει τον έλεγχο σας (test).

\item \textbf{Σιγουρευτείτε ότι έχετε ενεργοποιημένο το ENABLE_TESTING στο ccmake / cmakesetup.} Αυτό θα σιγουρέψει ότι οι έλεγχοι σας πραγματικά συντάσονται όταν πληκτρολογείτε make.

\item \textbf{Προαιρετικά προσθέστε δεδομένα ελέγχου στο $<$QGIS Source Dir$>$/tests/testdata} αν ο έλεγχος σας καθοδηγείται απο δεδομένα (π.χ, χρειάζεται να φορτώσει ένα shapefile). Αυτά τα δεδομένα ελέγχου θα πρέπει να είναι όσο το δυνατόν μικρότερα και όπου είναι δυνατόν χρησιμοποιήστε τα υπάρχοντα δεδομένα που είναι ήδη εκεί. Οι έλεγχοι σας δεν πρέπει ποτέ να μετατεουν αυτά τα δεδομένα μέσα στην τοποθεσία, αλλά είναι προτιμότερο να γίνει ένα προσωρινό αντίγραφο οπουδήποτε αν είναι απαραίτητο

\item \textbf{Συντάσετε τους πηγαίους κώδικες και εγκαθιταστείτε.} Κάντε το αυτό χρησιμοποιώντας την κανονική make \&\& (sudo) 
    make install διαδικασία.

\item \textbf{Τρέχετε τον έλεγχο σας.}  Αυτό κανονικά γίνεται απλά κάνοντας ένα \textbf{make test} 
 μετά την make install διαδικασία, παρ'όλα αυτά θα εξηγήσω άλλες προσεγγίσεις που προσφέρουν πιο λεπτομερή έλεγχο στη διεξαγωγή των ελέγχων.

\end{itemize}


Με αυτή τη γενική επισκόπηση στο μυαλό, θα ανατρέξω σε λίγο περιοσσότερη λεπτομέρεια. Έχω ήδη κάνει το περισσότερο μέρος της ρύθμισης για εσάς στο Cmake και άλλα μέρη στον πηγαίο κατάλογο οπότε αυτό που χρειάζεται να κάνετε είναι το εύκολο μέρος – να γράφετε ελέγχους μονάδας!

\hypertarget{toc49}{}
\subsection{Δημιουργώντας έναν έλεγχο μονάδας}
Το να δημιουργήσετε έναν έλεγχο μονάδας είναι εύκολο – τυπικά αυτό θα το κάνετε δημιουργώντας ένα .cpp αρχείο (κανένα .h αρχείο δεν χρησιμοποιείται) και εφαρμόστε όλες τις μεθόδους ελέγχου σαν μεθόδους public που επιστρέφουν void. Θα χρησιμοποιηω μία απλή κλάση ελέγχου για το QgsRasterLayer στο κεφάλαιο που ακολουθεί για την επεξήγηση. Όπως συνηθίζεται θα ονομάσουμε τον έλεγχο μας με το ίδιο όνομα όπως στην κλάση που ελέγχουν αλλά με το πρόθημα “Test”. Οπότε η εφαρμογή του ελέγχου μας πηγαίνει σε ένα αρχέιο που ονομάζεται testqgsrasterlayer.cpp και η κλάση θα είναι η TestQgsRasterLayer.
 Πρώτα προσθέτουμε το πλαίσιο κειμένου περί πνευματικής ιδιοκτησίας:

\begin{verbatim}
/***************************************************************************
     testqgsvectorfilewriter.cpp
     --------------------------------------
    Date                 : Frida  Nov 23  2007
    Copyright            : (C) 2007 by Tim Sutton
    Email                : tim@linfiniti.com
 ***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
\end{verbatim}

Μετά χρησιμοποιούμε τα include που μας χρειάζονται για τους ελέγχους που σχεδιάζουμε να τρέξουμε. Υπάρχει ένα συγκεκριμένο include όπου όλο οι έλεγχοι θα έπρεπε να έχουν:

\begin{verbatim}
#include <QtTest>
\end{verbatim}

\textbf{Σημειώστε}ότι χρησιμοποιούμε όλα τα  Qt4 includes 
νέου στυλ – δηλαδή το QtTest συμπεριλαμβάνεται όχι το qttest.h.

Πέρα απο αυτό απλά συνεχίζετε να εφαρμόζετε την κλάση σας ως συνήθως, βάζοντας οποιαδήποτε κεφαλίδα μπορεί να χρειαστείτε:

\begin{verbatim}
//Qt includes...
#include <QObject>
#include <QString>
#include <QObject>
#include <QApplication>
#include <QFileInfo>
#include <QDir>

//qgis includes...
#include <qgsrasterlayer.h> 
#include <qgsrasterbandstats.h> 
#include <qgsapplication.h>
\end{verbatim}

Απο τη στιγμή που συνδυάζουμε και την δήλωση της κλάσης και την εφαρμογή σε ένα μοναδικό αρχείο η δήλωση της κλάσης έρχεται αμέσως μετά. Ξεκινάμε με τα έγγραφα τεκμηρίωσης  doxygen.Οποιαδήποτε περίπτωση ελέγχου θα πρέπει να τεκμηριωθεί σωστά. Χρησιμοποιούμε την doxygen \textbf{ingroup}
οδηγία έτσι ώστε όλα τα UnitTests να εμφανιστούν στα παραγόμενα Doxygen έγγραφα τεκμηρίωσης. Μετά απο αυτό έρχεται μια μικρή της μονάδας ελέγχου:

\begin{verbatim}
/** \ingroup UnitTests
 * This is a unit test for the QgsRasterLayer class.
 */
\end{verbatim}

Η κλάση \textbf{πρέπει} να “κληρονομήσει” απο την QΟbject και το Q\_OBJECT macro.

\begin{verbatim}
class TestQgsRasterLayer: public QObject
{
  Q_OBJECT;
\end{verbatim}

Όλοι οι μέθοδοι ελέγχου εφαρμόζονται ως \textbf{private slots}. Το QtTest πλαίσιο θα καλέσει επακολούθως κάθε private slot μέθοδο στην κλάση ελέγχου. Υπάρχουν τέσσερεις “ειδικές” μέθοδοι οι οποίες αν εφαρμοστούν θα καλεστούν στην αρχή της μονάδας ελέγχου (\textbf{initTestCase}), στο τέλος της μονάδας ελέγχου (\textbf{cleanupTestCase}). Πριν κάθε μέθοδος ελέγχου καλεστεί, η μέθοδος \textbf{init()}
θα καλεστεί  και αφού κάθε μέθοδος ελέγχου καλεστεί καλείται και η μέθοδος \textbf{cleanup()}. Αυτές οι μέθοδοι είναι εξυπηρετικοί στο ότι σας επιτρέπουν να μοιράσετε και να καθαρίσετε τις πηγές πρίν τρέξετε οποιοδήποτε έλεγχο, και τον λελεγχο μονάδας σαν ολότητα. 

\begin{verbatim}
private slots:
  // will be called before the first testfunction is executed.
  void initTestCase();
  // will be called after the last testfunction was executed.
  void cleanupTestCase(){};
  // will be called before each testfunction is executed.
  void init(){};
  // will be called after every testfunction.
  void cleanup();
\end{verbatim}

Μετά έρχονται οι μέθοδο ελέγχου, όλο εκ των οποίων δεν θα έπρεπε να παίρνουν \textbf{καθόλου παραμέτρους} και θα πρέπει να \textbf{επιστρέφουν void}. Οι μέθοδοι θα καλεστούν με τη σειρά που δηλώθηκαν. Εφαρμόζω δύο μεθόδους εδώ που δείχνουν δύο μεθόδους ελέγχου. Στην πρώτη περίπτωση θέλω να ελέγξω γενικά τα διάφορα μέρη της κλάσης που δουλέυουν, οπότε μπορώ να χρησιμοποιήσω μια προσέγγιση  \textbf{λειτουργικού ελέγχου}. Για άλλη μία φορά, οι ακραίοι προγραμματιστές θα τασόταν υπερ του να γράφονται αυτοί οι έλεγχοι \textbf{πριν} την εφαρμογή της κλάσης. Έπειτα καθώς θα δουλεύετε με την εφαρμογή της κλάσης κατ'επανάληψη τρέχτε τις μονάδες ελέγχου. Όλο και περισσότερες λειτουργίες ελέγχου πρέπει να ολοκληρωθούν επιτυχημένα καθώς η εργασία εφαρμογής της κλάσης προχωράει, και όταν η μονάδα ελέγχου περάσει, η καινούργια σας κλάση έχει τελειώσει και τώρα έιναι ολοκληρωμένη με έναν επαναλαμβανόμενο τρόπον να την αξιολογήσετε. 

Τυπικά οι μονάδες ελέγχου σας θα κάλυπταν μόνο το \textbf{public} API της κλάσης σας και κανονικά δεν χρειάζεται να γράψετε ελέγχους για accessors (απλές και μικρές μέθοδοι που παρέχουν τα μέσα για την κατάσταση ενός αντικειμένου που θα ανακτηθεί απο άλλα μέρη του προγράμματος) και mutators (μέθοδοι που χρησιμοποιούνται για να ελέγξουν τις αλλαγές σε μία μεταβλητή).  Αν ένας accesor ή mutator δεν δουλεύει όπως αναμενόταν κανονικά θα εφαρμόζατε έναν έλεγχο \textbf{παλινδρόμησης} για να το ελέγξετε (δείτε παρακάτω).

\begin{verbatim}
  //
  // Functional Testing
  //
  
  /** Check if a raster is valid. */
  void isValid();

  // more functional tests here ...
\end{verbatim}

Μετά εφαρμόζουμε τους \textbf{ελέγχους παλινδρόμησής}. Οι έλεγχοι παλινδρόμησης θα πρέπει να εφαρμοστούν για να αναπαράγουν πανομοιότυπα τις καταστάσεις ενός συγκεκριμένου bug. Για παράδειγμα πρόσφατα έλαβα με e-mail μια αναφορά  ότι η μέτρηση κελιών απο τα raster ήταν εκτός για 1, αλλάζοντας τα στατιστικά για τις μπάντες του raster. Άνοιξα ένα bug (αριθμός\#832) και μέτα δημιούργησα έναν έλεγxο παλινδρόμησης που αναπαρήγαγε πανομοιότυπα το bug χρησιμοποιώντας ένα μικρό σύνολο δεδομένων ελέγχου (ένα 10x10 raster). Μετά έτρεξα τον έλεγχο (test) επαληθεύοντας ότι όντως απέτυχε (η μέτρηση κελιών ήταν 99 αντί για 100). Μετά πηγα να φτιάξω το bug και ξαναέτρεξα τον έλεγχο μονάδας και ο έλεγχος παλινδρόμησης πέρασε. Έκανα τον έλεγχο παλινδρόμησης μαζί με το φτιάξιμο του bug. Τώρα αν κάποιος τo σπάσει αυτό στον πηγαίο κώδικα ξανά στο μέλλον, μπορούμε αμέσως να αναγνωρίσουμε ότι ο κώδικας έχει επαναληφθεί. Ακόμα καλύτερα πριν γίνουν οποιεσδήποτε αλλαγές στο μέλλον, το τρεξιμο των ελέγχων μας θα σιγουρέψει ότι οι αλλαγές μας δεν έχουν μη αναμενόμενες παρενέργειες – όπως το σπάσιμο της υπάρχουσας λειτουργικότητας.

Υπάρχει ακόμα ένα όφελος στους ελέγχους παλινδρόμησης -  μπορούν να σας εξοικονομήσουν χρόνο. Αν ποτέ φτιάξατε κάποιο bug που συμπεριλάμβανε αλλαγές στον πηγαίο κώδικα, και μετά το τρέξιμο της εφαρμογής και τη διεξαγωγή ενός αριθμού περίπλοκων βημάτων για την ακριβή αναπαραγωγή του προβλήματος, θα γίνει αμέσως εμφανές ότι απλά εφαρμόζοντας τον έλεγχο παλινδρόμησης \textbf{πριν} φτιάξετε το bug, θα σας επιτρέψει να αυτοματοποιήσετε τον έλεγχο για την επίλυση των bug με έναν επαρκή τρόπο. 

Για να εφαρμόσετε τον έλεγχο παλινδρόμησης σας, ακολουθήστε την πρότυπη ονομασία της παλινδρόμησης $<$TicketID$>$ για τις λειτουργίες του ελέγχου. Αν δεν υπάρχει αριθμός trac για την παλινδρόμηση σας, δημιουργήστε πρώτα έναν. Χρησιμοποιώντας αυτή την προσέγγιση επιτρέπει στο άτομο που τρέχει έναν επιτυχημένο έλεγχο παλινδρόμησης να βρεί εύκολα περισσότερες πληροφορίες. 

\begin{verbatim}
  //
  // Regression Testing
  //
  
  /** This is our second test case...to check if a raster
   reports its dimensions properly. It is a regression test 
   for ticket #832 which was fixed with change r7650. 
   */
  void regression832(); 
  
  // more regression tests go here ...
\end{verbatim}

Τελικά στη δήλωση της κλάσης ελέγχου μπορείτε να δηλώσετε ως private οποιαδήποτε δεδομένα και βοηθητικές μεθόδους όπου η μονάδα ελέγχου σας μπορεί να χρειάζεται. Στη δική μας περίπτωση θα δηλώσω ένα QgsRasterLayer * που μπορεί να χρησιμοποιηθεί απο οποιαδήποτε απο τις μεθόδους ελέγχου. Το επίπεδο raster θα δημιουργηθεί στη λειτουργία initTestCase() η οποία τρέχει πρίν απο οποιδήποτε άλλο έλεγχο, και μετα θα καταστραφεί χρησιμοποιώντας τη μέθοδο cleanupTestCase() η οποία τρέχει μετά απο όλους τους ελέχγους. Δηλώνοντας τις βοηθητικές μεθόδους (οι οποίες μπορούν να καλεστούν απο διάφορες λειτουργίες ελέγχου) ως private, μπορείτε να σιγουρευτείτε ότι δεν θα τρέξουν αυτόματα απο το εκτελέσιμο QΤest που δημιουργείται όταν συντάσουμε τον έλεχγο.

\begin{verbatim}
  private:
    // Here we have any data structures that may need to 
    // be used in many test cases.
    QgsRasterLayer * mpLayer;
};

\end{verbatim}

Αυτό τελειώνει την δήλωση της κλάσης μας. Η εφαρμογή είναι απλά ευθυγραμμισμένη στο ίδιο αρχείο παρακάτω. Πρώτα οι αρχικές και οι λειτουργίες καθαρισμού: 

\begin{verbatim}
void TestQgsRasterLayer::initTestCase()
{
  // init QGIS's paths - true means that all path will be inited from prefix
  QString qgisPath = QCoreApplication::applicationDirPath ();
  QgsApplication::setPrefixPath(qgisPath, TRUE);
#ifdef Q_OS_LINUX
  QgsApplication::setPkgDataPath(qgisPath + "/../share/qgis");
#endif
  //create some objects that will be used in all tests...

  std::cout << "Prefix  PATH: " << \
  QgsApplication::prefixPath().toLocal8Bit().data() << std::endl;
  std::cout << "Plugin  PATH: " << \
  QgsApplication::pluginPath().toLocal8Bit().data() << std::endl;
  std::cout << "PkgData PATH: " << \
  QgsApplication::pkgDataPath().toLocal8Bit().data() << std::endl;
  std::cout << "User DB PATH: " << \
  QgsApplication::qgisUserDbFilePath().toLocal8Bit().data() << std::endl;

  //create a raster layer that will be used in all tests...
  QString myFileName (TEST_DATA_DIR); //defined in CmakeLists.txt
  myFileName = myFileName + QDir::separator() + "tenbytenraster.asc";
  QFileInfo myRasterFileInfo ( myFileName );
  mpLayer = new QgsRasterLayer ( myRasterFileInfo.filePath(),
            myRasterFileInfo.completeBaseName() );
}

void TestQgsRasterLayer::cleanupTestCase()
{
  delete mpLayer;
}

\end{verbatim}

Η παραπάνω αρχική λειτουργία δείχνει μερικά ενδιαφέροντα πράγματα. 

 1. Χρειάστεηκε να θέσω χειροκίνητα τη διαδρομή δεδομένων της QGIS εφαρμογής έτσι ώστε οι πηγές όπως η srs.db να μπορούν βρεθούν κανονικά.
 2. Δεύτερον, αυτός είναι ένας έλεγχος που οδηγείται απο δεδομένα έτσι χρειάστηκε να παρέχουμε έναν τρόπο για να εντοπίσουμε γενικά το αρχέιο 'tenbytenraster.as'. Αυτό έγινε εφικτό χρησιμοποιώντας τον ορισμό του συντάκτη \textbf{TEST\_DATA\_PATH}.  Ο χαραλτηρισμός δημιουργείται στο αρχείο καθορισμού CmakeLists.txt στο $<$QGIS Source Root$>$/tests/CMakeLists.txt και είναι διαθέσιμο σε όλες τις μονάδες ελέγχου του QGIS. Αν χρειάζεστε πειραματικά δεδομένα για τον έλεγχό σας, κάντε το στο $<$QGIS Source Root$>$/tests/testdata. Θα πρέπει να κάνετε πολύ μικρά δεδομένα εδώ. Αν ο έλεγχος σας χρειάζεται να κάνει αλλαγές στα πειραματικά δεδομένα σας, θα πρέπει να κάνει ένα αντίγραφό του πρώτα.

Το Qt παρέχει κάποιους ενδιαφέροντες μηχανισμούς για έλεγχο που διεξάγεται απο δεδομένα, οπότε αν χρειάζεστε να μάθετε περισσότερα σχετικά με αυτό το θέμα, συμβουλευτείτε τα έγγραφα τεκμηρίωσης του Qt. 

Έπειτα ας ρίξουμε μια ματιά στον λειτουργικό μας έλεγχο. Ο έλεγος sValid() απλά ελέγχει το επίπεδο πληροφορίας του raster αν φορτώθηκε σωστά στο initTestCase. To QVERIFY είναι ένα Qt macro που μπορείτε να χρησιμοποιήσετε για να αξιολογήσετε την κατάσταση του ελέγχου. Υπάρχουν και μερικά άλλα macros που το Qt παρέχει για χρήση στους ελέγχους σας συμπεριλαμβάνοντας:

\begin{verbatim}
QCOMPARE ( actual, expected )
QEXPECT_FAIL ( dataIndex, comment, mode )
QFAIL ( message )
QFETCH ( type, name )
QSKIP ( description, mode )
QTEST ( actual, testElement )
QTEST_APPLESS_MAIN ( TestClass )
QTEST_MAIN ( TestClass )
QTEST_NOOP_MAIN ()
QVERIFY2 ( condition, message )
QVERIFY ( condition )
QWARN ( message ) 
\end{verbatim}

Μερικά απο αυτά τα macros είναι χρήσιμα μόνο όταν χρησιμοποιείται το Qt framework για ελέγχους που κατευθύνονται απο δεδομένα (δείτε τα Qt docs για περισσότερες λεπτομέρειες).

\begin{verbatim}
void TestQgsRasterLayer::isValid()
{
  QVERIFY ( mpLayer->isValid() );
}
\end{verbatim}

Κανονικά οι λειτουργικοί σας έλεγχοι καλύπτουν ολο το εύρος λειτουργικότητας των public API των κλάσεων όπου είναι εφικτό. Με τους λειτουργικούς μας ελέγχους, μπορούμε να δούμε το παράδειγμα του ελέγχου παλινδρόμησης.

Απο τη στιγμή που το πρόβλημα στο  bug \#832 είναι ένα λανθασμένα αναφερμένο μέτρημα κελιών (cell count), το γράψιμο του ελέγχου είναι απλά ένα θέμα χρήσης του QVERIFY για να ελέγξει ότι η μέτρηση των κελιών ανταποκρίνεται στην αναμενόμενη τιμή:

\begin{verbatim}
void TestQgsRasterLayer::regression832()
{
   QVERIFY ( mpLayer->getRasterXDim() == 10 );
   QVERIFY ( mpLayer->getRasterYDim() == 10 );
   // regression check for ticket #832
   // note getRasterBandStats call is base 1
   QVERIFY ( mpLayer->getRasterBandStats(1).elementCountInt == 100 );
}
\end{verbatim}

Με όλες τις λειτουργίες της μονάδας ελέγχου εφαρμοσμένες, υπάρχει ένα τελευταίο πράγμα που πρέπει να προσθέσουμε στην κλάση ελέγχου μας:

\begin{verbatim}
QTEST_MAIN(TestQgsRasterLayer)
#include "moc_testqgsrasterlayer.cxx"
\end{verbatim}

Ο σκοπός αυτών των δύο γραμμών είναι να δώσουν σήμα στον moc (Meta Object Compiler) του Qt ότι πρόκειται για ένα QtTest (θα αναπαράγει μια κύρια μέθοδο που καλεί κάθε λειτουργία ελέγχου). Η τελευταία γραμμή είναι το include για τις αναπαραγόμενες πηγές του MOC. Αντικαταστήστε το ’testqgsrasterlayer’ με το όνομα της κλάσης σας με μικρούς χαρακτήρες.

\hypertarget{toc50}{}
\subsection{Προσθέτοντας τη μονάδα ελέγχου στο CmakeLists.txt}
Προσθέτοντας τη μονάδα ελέγχου στο σύστημα χτισίματος είναι απλά θέμα επεξεργασίας του CmakeLists.txt στον κατάλογο ελέγχου, κλονοποίησης ενός απο τα υπάρχοντα τετράγωνα ελέγχου, και μετά αντικατάστασης του ονόματος της κλάσης ελέγχου μέσα του. Για παράδειγμα:

\begin{verbatim}
# QgsRasterLayer test
ADD_QGIS_TEST(rasterlayertest testqgsrasterlayer.cpp)
\end{verbatim}

\hypertarget{toc51}{}
\subsection{Επεξήγηση του ADD\_QGIS\_TEST macro}
Θα ανατρέξω αυτές τις γραμμές εν συντομία για να εξηγήσω τι κάνουν, αλλά αν δεν ενδιαφέρεστε, απλά κάντε το βήμα που εξηγείται στο παραπάνω κεφάλαιο.

\begin{verbatim}
MACRO (ADD_QGIS_TEST testname testsrc)
  SET(qgis_${testname}_SRCS ${testsrc} ${util_SRCS})
  SET(qgis_${testname}_MOC_CPPS ${testsrc})
  QT4_WRAP_CPP(qgis_${testname}_MOC_SRCS ${qgis_${testname}_MOC_CPPS})
  ADD_CUSTOM_TARGET(qgis_${testname}moc ALL DEPENDS ${qgis_${testname}_MOC_SRCS})
  ADD_EXECUTABLE(qgis_${testname} ${qgis_${testname}_SRCS})
  ADD_DEPENDENCIES(qgis_${testname} qgis_${testname}moc)
  TARGET_LINK_LIBRARIES(qgis_${testname} ${QT_LIBRARIES} qgis_core)
  SET_TARGET_PROPERTIES(qgis_${testname}
    PROPERTIES
    # skip the full RPATH for the build tree
    SKIP_BUILD_RPATH  TRUE
    # when building, use the install RPATH already
    # (so it doesn't need to relink when installing)
    BUILD_WITH_INSTALL_RPATH TRUE
    # the RPATH to be used when installing
    INSTALL_RPATH ${QGIS_LIB_DIR}
    # add the automatically determined parts of the RPATH
    # which point to directories outside the build tree to the install RPATH
    INSTALL_RPATH_USE_LINK_PATH true)
  IF (APPLE)
    # For Mac OS X, the executable must be at the root of the bundle's executable folder
    INSTALL(TARGETS qgis_${testname} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
    ADD_TEST(qgis_${testname} ${CMAKE_INSTALL_PREFIX}/qgis_${testname})
  ELSE (APPLE)
    INSTALL(TARGETS qgis_${testname} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
    ADD_TEST(qgis_${testname} ${CMAKE_INSTALL_PREFIX}/bin/qgis_${testname})
  ENDIF (APPLE)
ENDMACRO (ADD_QGIS_TEST)
\end{verbatim}

Ας δούμε με λίγο παραπάνω λεπτομέρεια τις δυγκεκριμένες γραμμές. Πρώτα ορίζουμε τη λίστα των πηγών μας για τον έλεγχο μας. Απο τη στιγμή που έχουμε ένα μόνο πηγαίο αρχείο (ακολουθώντας τη μεθοδολογία που περιέγραψα παραπάνω όπου η δήλωση των κλάσεων και ο ορισμός ειναι στο ίδιο αρχείο) είναι μια απλή δήλωση:

\begin{verbatim}
SET(qgis_${testname}_SRCS ${testsrc} ${util_SRCS})
\end{verbatim}

Απο τη στιγμή που η κλάση ελέγχου χρειάζεται νε τρέξει δια μέσου του Qt Meta Object Compiler (MOC) πρέπει να παρέχουμε μερικές γραμμές για να το κάνουμε αυτό εφικτό επίσης:

\begin{verbatim}
SET(qgis_${testname}_MOC_CPPS ${testsrc})
QT4_WRAP_CPP(qgis_${testname}_MOC_SRCS ${qgis_${testname}_MOC_CPPS})
ADD_CUSTOM_TARGET(qgis_${testname}moc ALL DEPENDS ${qgis_${testname}_MOC_SRCS})
\end{verbatim}

Μετά λέμε στο cmake ότι πρέπει να φτιάξει ένα εκτελέσιμο απο την κλαση ελέγχου. Θυμηθείτε ότι στο προηγούμενο κεφάλαιο στην τελευταία γραμμή της εφαρμογής της κλάσης συμπεριέλαβα τα αποτελέσματα του moc κατευθείαν μέσα στην κλάση ελέγχου, έτσι θα της δώσει (ανάμεσα στα πολλά) μια κύρια μέθοδο έτσι ώστε η κλαση να μπορεί να συνταχθεί ως ένα εκτελέσιμο:

\begin{verbatim}
ADD_EXECUTABLE(qgis_${testname} ${qgis_${testname}_SRCS})
ADD_DEPENDENCIES(qgis_${testname} qgis_${testname}moc)
\end{verbatim}

Έπειτα πρέπει να καθορίσουμε οποιεσδήποτε εξαρτησίες βιβλιοθηκών. Προς το παρόν οι κλάσεις έχουν εφαρμοστεί με μία εξαρτησία catch-all QT\_LIBRARIES, αλλά θα εργάζομαι για να το αντικαταστήσω αυτό με με τις συγκεκριμένες Qt βιβλιοθήκες όπου κάθε κλάση χρειάζεται μόνο. Φυσικά χρειάζεται επίσης να συνδεθείτε με τις σχετικές qgis βιβλιοθήκες όπως απαιτείται απο τη μονάδα ελέγχου.

\begin{verbatim}
TARGET_LINK_LIBRARIES(qgis_${testname} ${QT_LIBRARIES} qgis_core)
\end{verbatim}

Μετά λεώ στο cmake να εγκαταστήσει τους ελέγχους στο ίδιο μέρος όπου όπως τα ίδια τα δυαδικά (binaries) του qgis. Υπάρχει κάτι που σκοπεύω να αφαιρέσω στο μέλλον έτσι ώστε οι έλεγχοι να τρέχουν κατευθείαν μέσα απο το πηγαίο δέντρο.

\begin{verbatim}
SET_TARGET_PROPERTIES(qgis_${testname}
  PROPERTIES
  # skip the full RPATH for the build tree
  SKIP_BUILD_RPATH  TRUE
  # when building, use the install RPATH already
  # (so it doesn't need to relink when installing)
  BUILD_WITH_INSTALL_RPATH TRUE
  # the RPATH to be used when installing
  INSTALL_RPATH ${QGIS_LIB_DIR}
  # add the automatically determined parts of the RPATH
  # which point to directories outside the build tree to the install RPATH
  INSTALL_RPATH_USE_LINK_PATH true)
IF (APPLE)
  # For Mac OS X, the executable must be at the root of the bundle's executable folder
  INSTALL(TARGETS qgis_${testname} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
  ADD_TEST(qgis_${testname} ${CMAKE_INSTALL_PREFIX}/qgis_${testname})
ELSE (APPLE)
  INSTALL(TARGETS qgis_${testname} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
  ADD_TEST(qgis_${testname} ${CMAKE_INSTALL_PREFIX}/bin/qgis_${testname})
ENDIF (APPLE)
\end{verbatim}

Εν τέλει τα παραπάνω χρησιμοποιούνε το ADD_TEST για να καταχωρήσουν τον έλεγχο με το cmake / ctest. Σ'αυτό το σημείο γίνεται το καλύτερο μαγικό – καταχωρούμε την κλάση με ctest. Αν θυμάστε στην επισκόπηση που έκανα στην αρχή του κεφαλαίου χρησιμοποιούμε το QtTest και το CTest μαζί. Για να ανακεφαλαιώσουμε, \textbf{QtTest} προσθέτει μια κύρια μέθοδο στη μονάδα ελέγχου και χειρίζεται το κάλεσμα των μεθόδων ελέγχου μέσα στην κλάση. Παρέχει επίσης μερικά macros όπως το QVERIFY που μπορείτε να χρησιμοποιήσετε, όπως για τον έλεγχο αποτυχίας των ελέγχων χρησιμοποιώντας όρους. Το αποτέλεσμα μίας μονάδας ελέγχου QtTest είναι ένα εκτελέσιμο το οποίο μπορείτε να τρέξετε απο τη γραμμή εντολών. Παρ'όλα αυτά όταν έχετε έναν αριθμό ελέγχων και θέλετε να τρέξετε κάθε εκτελέσιμο σε σειρά, και ακόμα καλύτερα να ενοποιήστε τους τρέχοντες ελέγχους σε μία διαδικασία build, το \textbf{CTest} είναι αυτό που θα χρησιμοποιήσουμε. 

\hypertarget{toc52}{}
\subsection{Χτίζοντας τη μονάδα ελέγχου}
Για να χτίσετε τη μονάδα ελέγχου χρειάζεται μόνο να σιγουρευτείτε ότι ENABLE\_TESTS=true στη ρύθμιση του cmake. Υπάρχουν δύο τρόποι να το κάνετε αυτό:

 1. Τρέξτε το ccmake .. (cmakesetup .. στα windows) και διαδραστικά θέστε το ENABLE\_TESTS flag σε ON.
 1. Προσθέστε μια γραμμή ελέγχου flag στο cmake π.χ. cmake -DENABLE\_TESTS=true ..

Πέρα απο αυτό, απλά χτίστε το QGIS ως συνήθως και κανονικά οι έλεγχοι θα χτιστούν επίσης.

\hypertarget{toc53}{}
\subsection{Τρέξτε τους ελέγχους σας}
Ο πιο απλός τρόπος να τρέξετε τους ελέγχους είναι μέρος της κανονικής διαδικασίας χτισίματος:

\begin{verbatim}
make && make install && make test
\end{verbatim}

Η εντολή make test θα καλέσει το Ctest που θα τρέξει κάθε έλεγχο που ήταν καταχωρημένος χρησιμοποιώντας την ADD\_TEST CMake οδηγία που περιγράφηκε παραπάνω. Το τυπικό αποτέλεσμα του make test θα φαίνεται κάπως έτσι:

\begin{verbatim}
Running tests...
Start processing tests
Test project /Users/tim/dev/cpp/qgis/build
1/  3 Testing qgis_applicationtest          ***Exception: Other
2/  3 Testing qgis_filewritertest           *** Passed
3/  3 Testing qgis_rasterlayertest          *** Passed

0% tests passed, 3 tests failed out of 3

  The following tests FAILED:
  1 - qgis_applicationtest (OTHER_FAULT)
  Errors while running CTest
  make: *** [test] Error 8
\end{verbatim}

Αν ένας έλεγχος αποτύχει, μπορείτε να χρησιμοποιήσετε την εντολή ctest για να εξετάσετε πιο λεπτομερώς γιατί απέτυχε. Χρησιμοποιήστε την επιλογή -R για να καθορίστε μια κανονική έκφραση σχετικά με το ποιούς ελέγχους θέλετε να τρέξετε και -V για να πάρετε περισσότερα αποτελέσματα:

\begin{verbatim}
[build] ctest -R appl -V
Start processing tests
Test project /Users/tim/dev/cpp/qgis/build
Constructing a list of tests
Done constructing a list of tests
Changing directory into /Users/tim/dev/cpp/qgis/build/tests/src/core
1/  3 Testing qgis_applicationtest          
Test command: /Users/tim/dev/cpp/qgis/build/tests/src/core/qgis_applicationtest
********* Start testing of TestQgsApplication *********
  Config: Using QTest library 4.3.0, Qt 4.3.0
PASS   : TestQgsApplication::initTestCase()
  Prefix  PATH: /Users/tim/dev/cpp/qgis/build/tests/src/core/../
  Plugin  PATH: /Users/tim/dev/cpp/qgis/build/tests/src/core/..//lib/qgis
  PkgData PATH: /Users/tim/dev/cpp/qgis/build/tests/src/core/..//share/qgis
  User DB PATH: /Users/tim/.qgis/qgis.db
PASS   : TestQgsApplication::getPaths()
  Prefix  PATH: /Users/tim/dev/cpp/qgis/build/tests/src/core/../
  Plugin  PATH: /Users/tim/dev/cpp/qgis/build/tests/src/core/..//lib/qgis
  PkgData PATH: /Users/tim/dev/cpp/qgis/build/tests/src/core/..//share/qgis
  User DB PATH: /Users/tim/.qgis/qgis.db
  QDEBUG : TestQgsApplication::checkTheme() Checking if a theme icon exists:
  QDEBUG : TestQgsApplication::checkTheme() 
  /Users/tim/dev/cpp/qgis/build/tests/src/core/..//share/qgis/themes/default/
/mIconProjectionDisabled.png
  FAIL!  : TestQgsApplication::checkTheme() '!myPixmap.isNull()' returned FALSE. ()
  Loc: [/Users/tim/dev/cpp/qgis/tests/src/core/testqgsapplication.cpp(59)]
PASS   : TestQgsApplication::cleanupTestCase()
  Totals: 3 passed, 1 failed, 0 skipped
  ********* Finished testing of TestQgsApplication *********
  -- Process completed
  ***Failed

  0% tests passed, 1 tests failed out of 1

  The following tests FAILED:
1 - qgis_applicationtest (Failed)
  Errors while running CTest
\end{verbatim}

Αυτά είναι τα συμπεράσματα αυτού του κεφαλαίου πάνω στη γραφή ελέγχων του QGIS. Ελπίζουμε ότι  θα συνηθίσετε να γράφετε ελέγχους για να δοκιμάζετε νέες λειτουργικότητες και να ελέγχτετε για παλινδρομήσεις. Μερικές διαστάσεις του συστήματος ελέγχου (συγκεκριμένα τα μέρη του CmakeLists.txt) ακόμα επεξεργάζονται έτσι ώστε το πλαίσιο ελέγχου να δουελεύει με έναν πραγματικό τρόπο πλατφόρμας. Θα ενημερώνω αυτό το έγγραφο όσο τα πράγματα θα εξελίσονται.


\hypertarget{toc54}{}
\section{Οδηγίες για το Ανθρώπινο Περιβάλλον Εργασίας}
Για να παρουσιαστούν σταθερά όλα τα στοιχεία του γραφικού περιβάλλοντος εργασίας και όλοι οι χρήστες να χρησιμοποιούν μηχανικά διαλόγους, είναι σημαντικό ότι οι παρακάτω οδηγίες ακολουθούνται σε διάταξη και σχεδιασμό των Γραφικών Περιβαλλόντων Εργασίας.

 \begin{enumerate}
 \item Στοιχεία που σχετίζονται με ομάδες χρησιμοποιούν ομαδικά κουτιά: προσπαθήστε να αναγνωρίσετε τα στοιχεία τα οποία μπορεί να ομαδοποιηθούν μαζί και μετά χρησιμοποιήστε ομαδικά κουτιά με μια ετικέτα για να αναγνωρίστε αυτή την ομάδα. Αποφύγετε να χρησιμποιήσετε ομαδικά κουτιά με ένα μονό widget / αντικείμενο μέσα.
 \item  Κάντε κεφαλαίο τον πρώτο χαρακτήρα μόνο στις ταμπέλες: οι ταμπέλες (και οι ταμπέλες ομαδικών κουτιών) θα έπρεπε να γραφούν ως μία φράση με τον πρώτο χαρακτήρα κεφαλαίο, και όλες οι εναπομείναντες λέξεις να γραφούν με το πρώτο γράμμα ως μικρό χαρακτήρα. 
 \item Μην τελειώνετε τις ταμπέλες για τα widgets ή τα ομαδικά κουτιά με ένα “ ; “ : η προσθήκη του προκαλεί οπτικό θόρυβο και δεν προσδίδει επιπρόσθετο νόημα, οπότε μη τα χρησιμοποιείτε. Μια εξαίρεση σ'αυτό τον κανόνα είναι όταν έχετε δυο ταμπέλες η μία δίπλα στην άλλη π.χ.: Label1 {Plugin}{Path:} Label2 [/path/to/plugins]
 \item Κρατήστε τις επιβλαβείς ενέργεις μακριά απο τις αβλαβείς: αν έχετε ενέργεις για “διαγραφή”, “μετακίνηση” κλπ, προσπαθήστε να επιφέρετε επαρκή διάστημα ανάμεσα στις επιβλαβείς ενέργειες και τις αβλαβείς ενέργεις έτσι ώστε να ελαχιστοποιείται η πιθανότητα οι χρήστες να κάνουν κλικ κατα λάθος σε μια επιβλαβή ενέργεια.
 \item Πάντα χρησιμοποιείται ένα QbuttonBox
 για τα κουμπιά “ΟΚ”, “Cancel” κλπ: χρησιμοποιώντας ένα τετράγωνο κουτί θα σιγουρέψει ότι η εντολή απο τα κουμπιά “OK”, “Cancel” κλπ είναι συναφής με το λειτουργικό σύστημα / LOCALE / περιβάλλον εργασίας που χρησιμοποιεί ο χρήστης.
 \item Οι στηλοθέτες δεν θα πρέπει να είναι ομαδοποιημένοι. Αν χρησιμοποιείτε στηλοθέτες, ακολουθήστε το στύλ των στηλοθετών που χρησιμποιείτε στο QgsVectorLayerProperties / QgsProjectProperties
 κλπ π.χ. στηλοθέτες στην κορυφή με τα εικονίδια στα 22x22.
 \item Οι σωροί απο widget θα πρέπει να αποφευχθολυν εντελώς αν είναι δυνατόν. Προκαλούν προβληματα με τη διαρύθμιση και ανεξήγητη (για το χρήστη) αναταξινόμηση των διαλόγων που φιλοξενούν τα widget που δεν είναι ορατά.
 \item Προσπαθήστε να αποφύγετε τεχνικούς όρους και καλύτερα χρησιμποιήστε κοινότυπες αντίστοιχες λέξεις π.χ. χρησιμποιήστε τη λέξη “Transparency” απ'οτι “Alpha Channel” (επιτηδευμένο παράδειγμα), “Text” αντι για “String” κλπ.
 \item Χρησιμποιήστε συναφή εικονογραφία. Αν χρειάζεστε μια εικόνα ή ένα στοιχείο εικόνας παρακαλώ επικοινωνήστε με τον Robert Szczepanek στην ταχυδρομική λίστα για βοήθεια.
 \item Τοποθετείστε μεγάλες λίστες απο widgets σε κυλιόμενα κουτιά. Κανένας διάλογος δεν θα έπρεπε να υπερβαίνει τα 580 pixels σε ύψος και τα 1000 pixel σε πλάτος.
 \item Διαχωρίστε τις προχωρημένες επιλογές απο τις βασικές. Οι αρχάριοι χρήστες θα πρέπει να μπορούν να έχουν γρήγορη πρόσβαση στα αντικείμενα που χριεάζονται για τις βασικές δραστηριότητες χωρίς να χρειάζεται να απασχολούν τον εαυτό τους με την πολυπλοκότητα των προχωρημένων χαρακτηριστικών. Τα προχωρημένα χαρακτηριστικά πρέπει είτε να τοοθετηθούν κάτω απο μια διαχωριστική γραμμή, ή να τοποθετηθούν σε ένα ξεχωριστό στηλοθέτη.
 \item Μη προσθέτε επιλογές για χάρη του να έχετε πολλές επιλογές. Προσπαθείτε να κρατάτε το περιβάλλον του χρήστη μινιμαλιστικό και χρησιμοποιήστε συνετά υποκατάστατα.
 \item Αν το πάτημα ενός κουμπιού ανοίξει έναν καινούργιο διάλογο, μια έλληψη (…) θα προστεθεί στο κουμπί ελέγχου.
 \end{enumerate}


