Erweiterung Task Scanner Plugin Tests

Ich habe einige weitere Test Cases für das Task Scanner Plugin geschrieben, um mehr Funktionalität abzudecken. Es gibt ein paar Punkte, die mir aufgefallen sind und die ich noch klären / besprechen möchte:

**(1)** Die ```mapTableCellsKeyValue``` Methode gibt eine Map aus String/Integer Paaren zurück. Das ist für die meisten Evaluationen praktisch, aber eigentlich nicht allgemein gültig, da nicht in allen Tabs in der zweiten Spalte ein Zahlenwert steht. Ich habe daher eine generische Methode hinzugefügt, die von der existierenden entsprechend für den Typ Integer aufgerufen wird:

```Java
    private SortedMap<String, Integer> mapTableCellsKeyValue(final Collection<WebElement> rows) {
        return mapTableCellsKeyValue(Integer.class, rows);
    }

    private <T extends Object > SortedMap<String, T> mapTableCellsKeyValue(Class<T> type, final Collection<WebElement> rows) {
        final SortedMap<String, T> result = new TreeMap<>();
        for(WebElement elem : rows) {
            final List<WebElement> cells = elem.findElements(by.xpath("./td"));
            final String key = asTrimmedString(cells.get(0));
            T value = null;
            if(type.isAssignableFrom(Integer.class))
                value = (T) asInteger(cells.get(1));
            else
                value = (T) asTrimmedString(cells.get(1));

            result.put(key, value);
        }
        return result;
    }
```
Ich bin mir allerdings nicht sicher, ob es vom Stil her gut ist, alle Aufrufe, für die ```type``` nicht ```Integer.class``` ist, als String zu behandeln. Alternativ könnte man explizit auf String abprüfen und Aufrufe für alle anderen Typen mit einer ```IllegalStateException``` beantworten.

----

**(2)** Im Test ```multiple_task_tags``` ist mir bei der Verwendung des Tags ```???``` aufgefallen, dass man die Fragezeichen escapen muss ```\?\?\?```. Das ist kein Problem an sich, nur sollte der User zum Einen darauf hingewiesen werden (z.B. mit einem Hilfe-Icon neben den Textfeldern), zum Anderen sollten Tags, die **nur** '?' oder '\*' enthalten ignoriert werden, da sonst **gar keine** Tasks gefunden werden.

----

**(3)** In der Summary Tabelle eines Builds werden nicht immer alle Warning-Prioritäten aufgeführt, insbesondere dann, wenn die entsprechende Anzahl 0 ist. Ich habe versucht, ein Schema zu erkennen, wann die Tabelle einen Eintrag mit 0 Warnings einer Priorität enthält und wann nicht. Das ist mir nicht gelungen. In diesem Zusammenhang ist allerdings problematisch, wie die ```AbstractCodeStylePluginAction``` die Anzahlen der einzelnen Prioritäten extrahiert:

```Java
    public int getHighWarningNumber() {
        return getIntByXPath("//table[@id='analysis.summary']/tbody/tr/td[@class='pane'][2]");
    }
```
Da hier auf eine bestimmte Zelle zugegriffen wird, ist bei wechselnder Struktur der Tabelle nicht mehr gegeben, dass man auch die Anzahl erhält, die man eigentlich will. Mir ist das z.B. im Test ```status_thresholds``` passiert. In Step 1 beispielsweise, in dem nur Normal Priority Tasks vorhanden sind, wird in der Summary die **High Priority** Spalte nicht angezeigt, die **Low Priority** aber schon. Durch den expliziten Zugriff auf eine bestimmte Zelle erhält man nun anstatt der Anzahl der Normal Priority die Anzahl der Low Priority Tasks.
Ich denke, beim Extrahieren sollte man mit den Link-Adressen arbeiten. Allerdings ist es dann nicht mehr möglich auf 0 zu prüfen, da diese wiederum keinen Link darstellt.

----

**(4)** Ebenfalls im Test ```status_thresholds``` ist mir ein potenzieller Fehler des Task Scanner Plugins aufgefallen. Da das Szenario dieses Tests etwas komplexer ist und sich mit jedem Step die Anzahl der offenen Tasks ändert, wollte ich implizit nochmals die Berechnung der new / fixed Tasks mit prüfen. Dabei ist mir aufgefallen, dass ab Step 3 die ausgegebenen Veränderungen der Tasks nicht mit dem übereinstimmen, was ich erwarte.
In Step 3 beispielsweise fällt effektiv ein Low Priority Task (Tag: ```???```) weg und es kommt ein Normal Priority Task (Tag: ```XXX```) dazu. Das Plugin meldet aber 3 neue Tasks. Ich habe jeweils die erwarteten Veränderungen als Assertions implementiert und auskommentiert, damit Sie dieses Problem nachvollziehen können.

Das ist ein guter Punkt, den ich nicht bedacht habe. Danke.
In diesem simplen Anwendungsfall kann natürlich auf diese Option bei Erweiterung der obigen Liste verzichtet werden.
Ich plane in Richtung Wochenende nochmals einen Pull Request zu stellen. Da wird die Änderung dabei sein. Vielleicht können Sie das folgende Beispiel schonmal vorab bei sich einsetzen und ausprobieren. Risk Reduction Testing sozusagen. ;-)

```Java
private FreeStyleJob status_thresholds_step7(FreeStyleJob j, TaskScannerAction tsa){
        j.configure();
        j.addShellStep( "NEW=\"CLOSED\"\n" +
                        "for t in \"todo\" \"TODO\" \"XXX\" \"fixme\" \"FIXME\" \"Deprecated\"\n" +
                        "do\n" +
                        "  OLD=$t\n" +
                        "  for f in `ls`\n" +
                        "  do\n" +
                        "    if [ -f $f -a -r $f ]; then\n" +
                        "      sed \"s/$OLD/$NEW/\" \"$f\" > \"${f}.new\"\n" +
                        "      mv \"${f}.new\" \"$f\"\n" +
                        "    else\n" +
                        "      echo \"Error: Cannot read $f\"\n" +
                        "    fi\n" +
                        "  done\n" +
                        "done");
        j.save();

        final Build lastBuild = buildJobWithSuccess(j);
...
}
```