//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package de.ugoe.cs.autoquest.usability;

import static de.ugoe.cs.autoquest.usability.UsabilityDefectDescription.TEXT_FIELD_INPUT_RATIO;
import static de.ugoe.cs.autoquest.usability.UsabilityDefectDescription.TEXT_FIELD_INPUT_REPETITIONS;
import static de.ugoe.cs.autoquest.usability.UsabilityDefectDescription.TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO;
import static de.ugoe.cs.autoquest.usability.UsabilityDefectSeverity.HIGH;
import static de.ugoe.cs.autoquest.usability.UsabilityDefectSeverity.INFO;
import static de.ugoe.cs.autoquest.usability.UsabilityDefectSeverity.LOW;
import static de.ugoe.cs.autoquest.usability.UsabilityDefectSeverity.MEDIUM;

import org.junit.Test;

import de.ugoe.cs.autoquest.usability.UsabilityDefect;
import de.ugoe.cs.autoquest.usability.UsabilityEvaluationManager;

/**
 * TODO comment
 * 
 * @version $Revision: $ $Date: 18.07.2012$
 * @author 2012, last modified by $Author: pharms$
 */
public class TextInputStatisticsRuleTest extends AbstractUsabilityEvaluationTC {

    /**
     * TODO: comment
     * 
     */
    @Test
    public void testWithDifferentTextInputInteractionsOnly() {
        UsabilityEvaluationManager manager = new UsabilityEvaluationManager();

        // ===== check =====
        String spec =
            "UserSession {" +
            "  TextInput (bla) {}" +
            "}";
        UsabilityDefect[] expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "UserSession {" +
            "  TextInput (a) {}" +
            "  TextInput (b) {}" +
            "  TextInput (c) {}" +
            "  TextInput (d) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "UserSession {" +
            "  TextInput (a) {}" +
            "  TextInput (b) {}" +
            "  TextInput (c) {}" +
            "  TextInput (d) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Iteration {" +
            "  TextInput (bla) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (a) {}" +
            "  Sequence {" +
            "    TextInput (b) {}" +
            "    TextInput (c) {}" +
            "    TextInput (d) {}" +
            "    TextInput (e) {}" +
            "  }" +
            "  Iteration {" +
            "    TextInput (f) {}" +
            "  }" +
            "  TextInput (g) {}" +
            "  Selection {" +
            "    TextInput (h) {}" +
            "    TextInput (i) {}" +
            "    TextInput (j) {}" +
            "    TextInput (k) {}" +
            "  }" +
            "  Sequence {" +
            "    TextInput (l) {}" +
            "    Sequence {" +
            "      TextInput (m) {}" +
            "      TextInput (n) {}" +
            "      TextInput (o) {}" +
            "      TextInput (p) {}" +
            "    }" +
            "    Iteration {" +
            "      TextInput (q) {}" +
            "    }" +
            "    TextInput (r) {}" +
            "    Selection {" +
            "      TextInput (s) {}" +
            "      TextInput (t) {}" +
            "      TextInput (u) {}" +
            "      TextInput (v) {}" +
            "    }" +
            "  }" +
            "  Selection {" +
            "    TextInput (w) {}" +
            "    Sequence {" +
            "      TextInput (x) {}" +
            "      TextInput (y) {}" +
            "      TextInput (z) {}" +
            "      TextInput (aa) {}" +
            "    }" +
            "    Iteration {" +
            "      TextInput (ab) {}" +
            "    }" +
            "    TextInput (ac) {}" +
            "    Selection {" +
            "      TextInput (ad) {}" +
            "      TextInput (ae) {}" +
            "      TextInput (af) {}" +
            "      TextInput (ag) {}" +
            "    }" +
            "  }" +
            "  TextInput (ah) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));
    }

    /**
     * TODO: comment
     * 
     */
    @Test
    public void testCombinationsOfTextInputInteractionsAndOtherInteractions() {
        UsabilityEvaluationManager manager = new UsabilityEvaluationManager();

        // ===== check =====
        String spec =
            "Sequence {" +
            "  Interaction {}" +
            "  TextInput (a) {}" +
            "  TextInput (b) {}" +
            "  Interaction {}" +
            "  TextInput (c) {}" +
            "}";

        UsabilityDefect[] expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(LOW, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  Interaction {}" +
            "  TextInput (a) {}" +
            "  Interaction {}" +
            "  Interaction {}" +
            "  TextInput (c) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(INFO, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  Interaction {}" +
            "  TextInput (a) {}" +
            "  Interaction {}" +
            "  Interaction {}" +
            "  Interaction {}" +
            "}";

        expectedDefects = new UsabilityDefect[0];

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Selection {" +
            "  Interaction {}" +
            "  TextInput (a) {}" +
            "  TextInput (b) {}" +
            "  Interaction {}" +
            "  TextInput (c) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(LOW, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (a) {}" +
            "  Sequence {" +
            "    Interaction {}" +
            "    TextInput (b) {}" +
            "    TextInput (c) {}" +
            "    Interaction {}" +
            "    TextInput (d) {}" +
            "  }" +
            "  Iteration {" +
            "    TextInput (e) {}" +
            "  }" +
            "  Interaction {}" +
            "  Selection {" +
            "    Interaction {}" +
            "    TextInput (f) {}" +
            "    TextInput (g) {}" +
            "    Interaction {}" +
            "    TextInput (h) {}" +
            "    TextInput (i) {}" +
            "  }" +
            "  Sequence {" +
            "    TextInput (j) {}" +
            "    Sequence {" +
            "      TextInput (k) {}" +
            "      Interaction {}" +
            "      TextInput (l) {}" +
            "      TextInput (m) {}" +
            "      Interaction {}" +
            "      TextInput (n) {}" +
            "      TextInput (o) {}" +
            "    }" +
            "    Iteration {" +
            "      Interaction {}" +
            "    }" +
            "    Interaction {}" +
            "    Selection {" +
            "      TextInput (p) {}" +
            "      TextInput (q) {}" +
            "      TextInput (r) {}" +
            "      Interaction {}" +
            "      TextInput (s) {}" +
            "      TextInput (t) {}" +
            "      Interaction {}" +
            "      TextInput (u) {}" +
            "      TextInput (v) {}" +
            "    }" +
            "  }" +
            "  Selection {" +
            "    Interaction {}" +
            "    Sequence {" +
            "      TextInput (w) {}" +
            "      Interaction {}" +
            "      TextInput (x) {}" +
            "      TextInput (y) {}" +
            "      Interaction {}" +
            "    }" +
            "    Iteration {" +
            "      TextInput (z) {}" +
            "    }" +
            "    TextInput (aa) {}" +
            "    Selection {" +
            "      TextInput (ab) {}" +
            "      Interaction {}" +
            "      TextInput (ac) {}" +
            "      TextInput (ad) {}" +
            "      Interaction {}" +
            "      TextInput (ae) {}" +
            "    }" +
            "  }" +
            "  Interaction {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(LOW, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (a) {}" +
            "  Sequence {" +
            "    Interaction {}" +
            "    TextInput (b) {}" +
            "    Interaction {}" +
            "    Interaction {}" +
            "    TextInput (c) {}" +
            "  }" +
            "  Iteration {" +
            "    TextInput (d) {}" +
            "  }" +
            "  Interaction {}" +
            "  Selection {" +
            "    Interaction {}" +
            "    TextInput (e) {}" +
            "    Interaction {}" +
            "    Interaction {}" +
            "    TextInput (g) {}" +
            "    Interaction {}" +
            "  }" +
            "  Sequence {" +
            "    TextInput (i) {}" +
            "    Sequence {" +
            "      TextInput (j) {}" +
            "      Interaction {}" +
            "      TextInput (k) {}" +
            "      Interaction {}" +
            "      Interaction {}" +
            "      TextInput (m) {}" +
            "      Interaction {}" +
            "    }" +
            "    Iteration {" +
            "      Interaction {}" +
            "    }" +
            "    Interaction {}" +
            "    Selection {" +
            "      TextInput (o) {}" +
            "      Interaction {}" +
            "      Interaction {}" +
            "      Interaction {}" +
            "      Interaction {}" +
            "      TextInput (s) {}" +
            "      Interaction {}" +
            "      TextInput (t) {}" +
            "      TextInput (u) {}" +
            "    }" +
            "  }" +
            "  Selection {" +
            "    Interaction {}" +
            "    Sequence {" +
            "      TextInput (v) {}" +
            "      Interaction {}" +
            "      Interaction {}" +
            "      TextInput (x) {}" +
            "      Interaction {}" +
            "    }" +
            "    Iteration {" +
            "      TextInput (y) {}" +
            "    }" +
            "    TextInput (z) {}" +
            "    Selection {" +
            "      TextInput (aa) {}" +
            "      Interaction {}" +
            "      TextInput (ab) {}" +
            "      Interaction {}" +
            "      Interaction {}" +
            "      TextInput (ad) {}" +
            "    }" +
            "  }" +
            "  Interaction {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(INFO, TEXT_FIELD_INPUT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));
    }

    /**
     * TODO: comment
     * 
     */
    @Test
    public void testTextEntryRepetitions() {
        UsabilityEvaluationManager manager = new UsabilityEvaluationManager();

        // ===== check =====
        String spec =
            "Sequence {" +
            "  TextInput (a b c) {}" +
            "  Sequence {" +
            "    TextInput (a) {}" +
            "    TextInput (b) {}" +
            "    TextInput (c) {}" +
            "    TextInput (a) {}" +
            "  }" +
            "  Iteration {" +
            "    TextInput (a) {}" +
            "  }" +
            "  TextInput (a) {}" +
            "  Selection {" +
            "    TextInput (b c) {}" +
            "    TextInput (a) {}" +
            "    TextInput (a c) {}" +
            "    TextInput (b a) {}" +
            "  }" +
            "  Sequence {" +
            "    TextInput (b c) {}" +
            "    Sequence {" +
            "      TextInput (d a c) {}" +
            "      TextInput (b b b a) {}" +
            "      TextInput (a a c c) {}" +
            "      TextInput (b b a) {}" +
            "    }" +
            "  }" +
            "  TextInput (d) {}" +
            "}";

        UsabilityDefect[] expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_REPETITIONS) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (a b c d e f g h i j k l m) {}" +
            "  Sequence {" +
            "    TextInput (a) {}" +
            "    TextInput (b) {}" +
            "    TextInput (c) {}" +
            "    TextInput (d) {}" +
            "  }" +
            "  Iteration {" +
            "    TextInput (e) {}" +
            "  }" +
            "  TextInput (f) {}" +
            "  Selection {" +
            "    TextInput (g) {}" +
            "    TextInput (h) {}" +
            "    TextInput (i) {}" +
            "    TextInput (j) {}" +
            "  }" +
            "  Sequence {" +
            "    TextInput (k) {}" +
            "    Sequence {" +
            "      TextInput (l) {}" +
            "      TextInput (m) {}" +
            "      TextInput (n) {}" +
            "      TextInput (o) {}" +
            "    }" +
            "  }" +
            "  TextInput (p) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_REPETITIONS) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (a b c d e f g h i j k l m) {}" +
            "  Sequence {" +
            "    TextInput (a) {}" +
            "    TextInput (b) {}" +
            "    TextInput (c) {}" +
            "    TextInput (d) {}" +
            "  }" +
            "  Iteration {" +
            "    TextInput (e) {}" +
            "  }" +
            "  TextInput (a) {}" +
            "  Selection {" +
            "    TextInput (b) {}" +
            "    TextInput (c) {}" +
            "    TextInput (d) {}" +
            "    TextInput (e) {}" +
            "  }" +
            "  Sequence {" +
            "    TextInput (a) {}" +
            "    Sequence {" +
            "      TextInput (b) {}" +
            "      TextInput (c) {}" +
            "      TextInput (d) {}" +
            "      TextInput (e) {}" +
            "    }" +
            "  }" +
            "  TextInput (f) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(MEDIUM, TEXT_FIELD_INPUT_REPETITIONS) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (a b c d e f g h i j k l m) {}" +
            "  Sequence {" +
            "    TextInput (a) {}" +
            "    TextInput (b) {}" +
            "    TextInput (c) {}" +
            "    TextInput (a) {}" +
            "  }" +
            "  Iteration {" +
            "    TextInput (b) {}" +
            "  }" +
            "  TextInput (c) {}" +
            "  Selection {" +
            "    TextInput (a) {}" +
            "    TextInput (b) {}" +
            "    TextInput (c) {}" +
            "    TextInput (a) {}" +
            "  }" +
            "  Sequence {" +
            "    TextInput (b) {}" +
            "    Sequence {" +
            "      TextInput (c) {}" +
            "      TextInput (a) {}" +
            "      TextInput (b) {}" +
            "      TextInput (c) {}" +
            "    }" +
            "  }" +
            "  TextInput (a) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(MEDIUM, TEXT_FIELD_INPUT_REPETITIONS) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (a b c) {}" +
            "  Sequence {" +
            "    TextInput (a) {}" +
            "    TextInput (b) {}" +
            "    TextInput (c) {}" +
            "  }" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(LOW, TEXT_FIELD_INPUT_REPETITIONS) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (a b c) {}" +
            "  Sequence {" +
            "    TextInput (a) {}" +
            "    TextInput (a) {}" +
            "    TextInput (b) {}" +
            "  }" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(LOW, TEXT_FIELD_INPUT_REPETITIONS) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (a b c) {}" +
            "  Sequence {" +
            "    TextInput (a) {}" +
            "    TextInput (d) {}" +
            "    TextInput (e) {}" +
            "  }" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(INFO, TEXT_FIELD_INPUT_REPETITIONS) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

    }

    /**
     * TODO: comment
     * 
     */
    @Test
    public void testNoLetterOrDigitInput() {
        UsabilityEvaluationManager manager = new UsabilityEvaluationManager();

        // ===== check =====
        String spec =
            "Sequence {" +
            "  TextInput (_a_b_c_) {}" +
            "}";

        UsabilityDefect[] expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(HIGH, TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (12345_6789012345) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(MEDIUM, TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (123456789012345678901234567890_123456789012345) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(LOW, TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

        // ===== check =====
        spec =
            "Sequence {" +
            "  TextInput (1234567890123456789012345678901234567890123456789_01234567890" +
            "12345678901234567890123456789012345) {}" +
            "}";

        expectedDefects = new UsabilityDefect[]
            { new UsabilityDefect(HIGH, TEXT_FIELD_INPUT_RATIO),
              new UsabilityDefect(INFO, TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO) };

        assertUsabilityEvaluationResult
            (expectedDefects, manager.evaluateUsability(createTaskModel(spec)));

    }
}
