TIMED_TEST(DawgLexiconTests, forEachTest_DawgLexicon, TEST_TIMEOUT_DEFAULT) {
    DawgLexicon dlex;
    dlex.add("a");
    dlex.add("cc");
    dlex.add("bbb");
    Queue<std::string> expected {"a", "bbb", "cc"};
    for (std::string word : dlex) {
        std::string exp = expected.dequeue();
        assertEqualsString("DawgLexicon foreach", exp, word);
    }
}
TIMED_TEST(DawgLexiconTests, hashCodeTest_DawgLexicon, TEST_TIMEOUT_DEFAULT) {
    DawgLexicon dlex;
    dlex.add("a");
    dlex.add("abc");
    assertEqualsInt("hashcode of self dawglexicon", hashCode(dlex), hashCode(dlex));

    DawgLexicon copy = dlex;
    assertEqualsInt("hashcode of copy dawglexicon", hashCode(dlex), hashCode(copy));

    DawgLexicon dlex2;   // empty

    // shouldn't add two copies of same lexicon
    HashSet<DawgLexicon> hashdawg {dlex, copy, dlex2};
    assertEqualsInt("hashset of dawglexicon size", 2, hashdawg.size());
}
TIMED_TEST(DawgLexiconTests, compareTest_DawgLexicon, TEST_TIMEOUT_DEFAULT) {
    DawgLexicon dawg;
    dawg.add("a");
    dawg.add("b");
    dawg.add("c");
    DawgLexicon dawg2;
    dawg2.add("a");
    dawg2.add("ab");
    dawg2.add("bc");
    DawgLexicon dawg3;
    compareTestHelper(dawg, dawg2, "DawgLexicon", /* compareTo */ 1);
    compareTestHelper(dawg2, dawg, "DawgLexicon", /* compareTo */ -1);
    compareTestHelper(dawg, dawg, "DawgLexicon", /* compareTo */ 0);

    Set<DawgLexicon> sdlex {dawg, dawg2, dawg3};
    assertEqualsString("sdlex", "{{}, {\"a\", \"ab\", \"bc\"}, {\"a\", \"b\", \"c\"}}", sdlex.toString());
}
TIMED_TEST(DawgLexiconTests, basicTest_DawgLexicon, TEST_TIMEOUT_DEFAULT) {
    std::initializer_list<std::string> words = {
        "a",
        "ab",
        "aab",
        "aaab",
        "aardvark",
        "b",
        "banana"
    };
    std::initializer_list<std::string> badWords = {
        "abb",
        "ad",
        "and",
        "aaardvark",
        "aardvarks",
    };
    std::initializer_list<std::string> badPrefixes = {
        "aaaa",
        "abb",
        "aardvarz",
        "bb",
        "bananas",
        "c",
        "r",
        "z"
    };

    DawgLexicon dawg;
    for (std::string word : words) {
        dawg.add(word);
    }
    assertEquals("DawgLexicon size", words.size(), dawg.size());

    for (std::string word : words) {
        assertTrue("DawgLexicon contains " + word, dawg.contains(word));
    }

    for (std::string word : badWords) {
        assertFalse("DawgLexicon contains " + word, dawg.contains(word));
    }

    for (std::string word : words) {
        for (int i = 0; i < (int) word.length(); i++) {
            std::string prefix = word.substr(0, i);
            assertTrue("DawgLexicon containsPrefix " + word, dawg.containsPrefix(word));
        }
    }

    for (std::string word : badPrefixes) {
        assertFalse("DawgLexicon containsPrefix " + word, dawg.containsPrefix(word));
    }
}