Skip to content

Instantly share code, notes, and snippets.

@alwarren
Last active July 21, 2019 17:46
Show Gist options
  • Select an option

  • Save alwarren/7cbadb6ec9d2a39fda63f43f428f9381 to your computer and use it in GitHub Desktop.

Select an option

Save alwarren/7cbadb6ec9d2a39fda63f43f428f9381 to your computer and use it in GitHub Desktop.

Revisions

  1. alwarren revised this gist Jul 21, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion WordNetTest.java
    Original file line number Diff line number Diff line change
    @@ -19,7 +19,7 @@
    * // distance between nounA and nounB (defined below)
    * public int distance(String nounA, String nounB)
    *
    * // a integerToWord (second field of synsets.txt) that is the common ancestor of nounA and nounB
    * // a synset (second field of synsets.txt) that is the common ancestor of nounA and nounB
    * // in a shortest ancestral path (defined below)
    * public String sap(String nounA, String nounB)
    *
  2. alwarren revised this gist Jun 17, 2019. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -8,6 +8,6 @@ Note
    2. It requires removing the **_org.*_** restriction from auto import rules if you are using the IntelliJ project included in the course zip file.
    This is because the Junit5 development team used the based package **_org.junit.*_** instead of **_junit.*_** in many of the new libraries.
    3. It requires adding Junit5 dependencies.
    4. The test assumes console output for the test is logged (see the [IntelliJ Log Options documentation](https://www.jetbrains.com/help/idea/setting-log-options.html)). This is the primary motivation for the Values class.
    4. The test assumes console output for the test is logged (see the [IntelliJ Log Options documentation](https://www.jetbrains.com/help/idea/setting-log-options.html)). This is the primary motivation for the WordNetValues class.
    5. The Spy class used to verify API method names can be found at [https://git.io/fj2vM](https://git.io/fj2vM)

    2 changes: 1 addition & 1 deletion Values.java → WordNetValues.java
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@
    * Description: Static values and helper methods for JUnit5 unit tests.
    */

    public class Values {
    public class WordNetValues {
    public static final String PASSED = "PASSED";
    public static final String SUITE_TITLE_FORMAT = "\n%s Test Suite " + dateTime() + "\n";
    public static final String TEST_CLASS_FORMAT = " %s";
  3. alwarren revised this gist Jun 17, 2019. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -8,6 +8,6 @@ Note
    2. It requires removing the **_org.*_** restriction from auto import rules if you are using the IntelliJ project included in the course zip file.
    This is because the Junit5 development team used the based package **_org.junit.*_** instead of **_junit.*_** in many of the new libraries.
    3. It requires adding Junit5 dependencies.
    4. The test assumes console output for the test is logged (see the [IntelliJ Log Options documentation](https://www.jetbrains.com/help/idea/setting-log-options.html)). This is the primary motivation for the WordNetValues class.
    4. The test assumes console output for the test is logged (see the [IntelliJ Log Options documentation](https://www.jetbrains.com/help/idea/setting-log-options.html)). This is the primary motivation for the Values class.
    5. The Spy class used to verify API method names can be found at [https://git.io/fj2vM](https://git.io/fj2vM)

    2 changes: 1 addition & 1 deletion WordNetValues.java → Values.java
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@
    * Description: Static values and helper methods for JUnit5 unit tests.
    */

    public class WordNetValues {
    public class Values {
    public static final String PASSED = "PASSED";
    public static final String SUITE_TITLE_FORMAT = "\n%s Test Suite " + dateTime() + "\n";
    public static final String TEST_CLASS_FORMAT = " %s";
  4. alwarren created this gist Jun 12, 2019.
    13 changes: 13 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    Coursera Algorithms II
    WordNet Junit5 Test Suite
    =========================

    Note
    ----
    1. This test suite is not exaustive.
    2. It requires removing the **_org.*_** restriction from auto import rules if you are using the IntelliJ project included in the course zip file.
    This is because the Junit5 development team used the based package **_org.junit.*_** instead of **_junit.*_** in many of the new libraries.
    3. It requires adding Junit5 dependencies.
    4. The test assumes console output for the test is logged (see the [IntelliJ Log Options documentation](https://www.jetbrains.com/help/idea/setting-log-options.html)). This is the primary motivation for the WordNetValues class.
    5. The Spy class used to verify API method names can be found at [https://git.io/fj2vM](https://git.io/fj2vM)

    264 changes: 264 additions & 0 deletions WordNetTest.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,264 @@
    /**
    * Name: Al Warren
    * Date: 6/3/2019
    * Description: Test suite for an Immutable object type WordNet.
    *
    * API Requirements:
    *
    * public class WordNet {
    *
    * // constructor takes the name of the two input files
    * public WordNet(String synsets, String hypernyms)
    *
    * // returns all WordNet nouns
    * public Iterable<String> nouns()
    *
    * // is the word a WordNet noun?
    * public boolean isNoun(String word)
    *
    * // distance between nounA and nounB (defined below)
    * public int distance(String nounA, String nounB)
    *
    * // a integerToWord (second field of synsets.txt) that is the common ancestor of nounA and nounB
    * // in a shortest ancestral path (defined below)
    * public String sap(String nounA, String nounB)
    *
    * // do unit testing of this class
    * public static void main(String[] args)
    * }
    * }
    *
    * Corner Caases:
    *
    * Throw a java.lang.IllegalArgumentException in the following situations:
    * - Any argument to the constructor or an instance method is null
    * - The input to the constructor does not correspond to a rooted DAG.
    * - Any of the noun arguments in distance() or sap() is not a WordNet noun.
    *
    */

    @DisplayName(WordNetValues.SUITE_TITLE_WORDNET)
    public class WordNetTest {
    private static String synsets = "synsets11.txt";
    private static String hypernyms = "hypernyms11ManyPathsOneAncestor.txt";
    private static String synsets_not_dag = "synsets6.txt";
    private static String hypernyms_not_dag = "hypernyms6InvalidTwoRoots.txt";
    private static WordNet wordNet;

    @BeforeAll
    static void setup() {
    wordNet = new WordNet(synsets, hypernyms);
    StdOut.println(String.format(WordNetValues.SUITE_TITLE_FORMAT, WordNetValues.SUITE_TITLE_WORDNET));
    }

    @Nested
    @DisplayName(WordNetValues.TITLE_FUNCTIONAL)
    @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    class Functional {
    @BeforeAll
    void setup() {
    StdOut.println(String.format(WordNetValues.TEST_CLASS_FORMAT, WordNetValues.TITLE_FUNCTIONAL));
    }

    @Order(1)
    @DisplayName(WordNetValues.WORDNET_VERIFY_NOUNS)
    @Test void verify_nouns() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_VERIFY_NOUNS);
    List<String> expected = expectedNouns();
    List<String> actual = actualNouns();
    assertEquals(expected, actual);
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(2)
    @DisplayName(WordNetValues.WORDNET_VERIFY_NOUNS_CONTAINS_WORD_TRUE)
    @Test void verify_nouns_contains_word_true() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_VERIFY_NOUNS_CONTAINS_WORD_TRUE);
    String word = expectedNouns().get(0);
    assertTrue(wordNet.isNoun(word));
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(3)
    @DisplayName(WordNetValues.WORDNET_VERIFY_NOUNS_CONTAINS_WORD_FALSE)
    @Test void verify_nouns_contains_word_false() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_VERIFY_NOUNS_CONTAINS_WORD_FALSE);
    String word = expectedNouns().get(0) + "missing";
    assertFalse(wordNet.isNoun(word));
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(4)
    @DisplayName(WordNetValues.WORDNET_VERIFY_DISTANCE)
    @Test void verify_distance() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_VERIFY_DISTANCE);
    testDistance();
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(5)
    @DisplayName(WordNetValues.WORDNET_VERIFY_SAP)
    @Test void verify_sap() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_VERIFY_SAP);
    testSap();
    StdOut.println(WordNetValues.PASSED);
    }

    private void testSap() {
    String[] letters = {"a","b","c","d","e","f","g","h","i","j","k"};
    String[] expected = {"a","b","c","d","e","f","f","f","f","f","f"};
    for (int i = 0; i < letters.length; i++) {
    assertEquals(expected[i], wordNet.sap("a", letters[i]));
    }
    }

    private void testDistance() {
    String[] letters = {"a","b","c","d","e","f","g","h","i","j","k"};
    int[] expected = {0,1,1,1,1,2,3,3,3,3,4};
    for (int i = 0; i < letters.length; i++) {
    assertEquals(expected[i], wordNet.distance("a", letters[i]));
    }
    }
    }

    @Nested
    @DisplayName(WordNetValues.TITLE_CORNER_CASES)
    @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    class CornerCases {
    @BeforeAll
    void setup() {
    StdOut.println(String.format(WordNetValues.TEST_CLASS_FORMAT, WordNetValues.TITLE_CORNER_CASES));
    }

    @Order(1)
    @DisplayName(WordNetValues.VERIFY_NULL_CONSTRUCTOR_ARGUMENT_THROWS_EXCEPTION)
    @Test void throw_exception_on_null_constructor_argument() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.VERIFY_NULL_CONSTRUCTOR_ARGUMENT_THROWS_EXCEPTION);
    assertThrows(IllegalArgumentException.class, () -> {
    new WordNet(null, hypernyms);
    new WordNet(synsets, null);
    new WordNet(null, null);
    });
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(2)
    @DisplayName(WordNetValues.WORDNET_DIGRAPH_IS_NOT_DAG)

    @Test void thow_execption_ondigraph_is_not_dag() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_DIGRAPH_IS_NOT_DAG);
    assertThrows(IllegalArgumentException.class, () ->
    new WordNet(synsets_not_dag, hypernyms_not_dag)
    );
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(3)
    @DisplayName(WordNetValues.WORDNET_IS_NOUN_NULL_ARGUMENT_EXCEPTION)
    @Test void throw_exception_on_is_noun_null_argument() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_IS_NOUN_NULL_ARGUMENT_EXCEPTION);
    assertThrows(IllegalArgumentException.class, () ->
    wordNet.isNoun(null)
    );
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(4)
    @DisplayName(WordNetValues.WORDNET_DISTANCE_NULL_ARGUMENT_EXCEPTION)
    @Test void throw_exception_on_distance_null_argument() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_DISTANCE_NULL_ARGUMENT_EXCEPTION);
    assertThrows(IllegalArgumentException.class, () -> {
    wordNet.distance("", null);
    wordNet.distance(null, "");
    wordNet.distance(null, null);
    });
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(5)
    @DisplayName(WordNetValues.WORDNET_DISTANCE_ARGUMENT_NOT_A_WORD_EXCEPTION)
    @Test void throw_exception_on_distance_argument_not_a_word() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_DISTANCE_ARGUMENT_NOT_A_WORD_EXCEPTION);
    assertThrows(IllegalArgumentException.class, () -> {
    String word = expectedNouns().get(0);
    String missingWord = word + "missing";
    wordNet.distance(word, missingWord);
    wordNet.distance(missingWord, word);
    });
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(6)
    @DisplayName(WordNetValues.WORDNET_SAP_NULL_ARGUMENT_EXCEPTION)
    @Test void throw_exception_on_sap_null_argument() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_SAP_NULL_ARGUMENT_EXCEPTION);
    assertThrows(IllegalArgumentException.class, () -> {
    wordNet.sap("", null);
    wordNet.sap(null, "");
    wordNet.sap(null, null);
    });
    StdOut.println(WordNetValues.PASSED);
    }

    @Order(7)
    @DisplayName(WordNetValues.WORDNET_SAP_ARGUMENT_NOT_A_WORD_EXCEPTION)
    @Test void throw_exception_on_sap_argument_not_a_word() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.WORDNET_SAP_ARGUMENT_NOT_A_WORD_EXCEPTION);
    assertThrows(IllegalArgumentException.class, () -> {
    String word = expectedNouns().get(0);
    String missingWord = word + "missing";
    wordNet.sap(word, missingWord);
    wordNet.sap(missingWord, word);
    });
    StdOut.println(WordNetValues.PASSED);
    }
    }

    @Nested
    @DisplayName(WordNetValues.TITLE_API)
    @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    class Api {
    @BeforeAll
    void setup() {
    StdOut.println(String.format(WordNetValues.TEST_CLASS_FORMAT, WordNetValues.TITLE_API));
    }

    @DisplayName(WordNetValues.VERIFY_API_METHODS)
    @Test
    void verify_api_methods() {
    StdOut.printf(WordNetValues.TEST_FORMAT, WordNetValues.VERIFY_API_METHODS);
    List<String> expected = expectedMethods();
    List<String> actual = actualMethods();
    assertEquals(expected, actual);
    StdOut.println(WordNetValues.PASSED);
    }

    private List<String> expectedMethods() {
    List<String> expected = Arrays.asList("length", "ancestor", "length", "ancestor");
    Collections.sort(expected);

    return expected;
    }

    private List<String> actualMethods() {
    return Spy.publicMethodNames(SAP.class)
    .stream()
    .filter(s -> !s.equals("main"))
    .sorted()
    .collect(Collectors.toList());
    }
    }
    private List<String> expectedNouns() {
    return Arrays.asList("h", "d", "i", "e", "a", "j", "f", "b", "k", "g", "c");
    }

    private List<String> actualNouns() {
    WordNet wordNet = new WordNet("synsets11.txt", "hypernyms11ManyPathsOneAncestor.txt");
    List<String> list = new ArrayList<>();
    for (String noun : wordNet.nouns())
    list.add(noun);
    return list;
    }
    }
    58 changes: 58 additions & 0 deletions WordNetValues.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@
    import java.text.SimpleDateFormat;
    import java.util.Date;

    /**
    * Name:
    * Date:
    * Description: Static values and helper methods for JUnit5 unit tests.
    */

    public class WordNetValues {
    public static final String PASSED = "PASSED";
    public static final String SUITE_TITLE_FORMAT = "\n%s Test Suite " + dateTime() + "\n";
    public static final String TEST_CLASS_FORMAT = " %s";
    public static final String TEST_FORMAT = " %s => ";

    public static final String VERIFY_NULL_CONSTRUCTOR_ARGUMENT_THROWS_EXCEPTION = "Null constructor argument throws required exception";
    public static final String VERIFY_API_METHODS = "Expected methods";

    public static final String TITLE_API = "API Tests";
    public static final String TITLE_CORNER_CASES = "Corner Case Tests";
    public static final String TITLE_FUNCTIONAL = "Functional Tests";

    public static final String SUITE_TITLE_WORDNET = "WordNet";
    public static final String SUITE_TITLE_SAP = "SAP";
    public static final String SUITE_TITLE_OUTCAST = "Outcast";

    public static final String WORDNET_IS_NOUN_NULL_ARGUMENT_EXCEPTION = "Null isNoun() argument throws required exeception";
    public static final String WORDNET_DISTANCE_NULL_ARGUMENT_EXCEPTION = "Null distance() argument throws required exeception";
    public static final String WORDNET_SAP_NULL_ARGUMENT_EXCEPTION = "Null sap() argument throws required exeception";
    public static final String WORDNET_SAP_ARGUMENT_NOT_A_WORD_EXCEPTION = "An sap() argument that is not a word throws required exeception";
    public static final String WORDNET_DISTANCE_ARGUMENT_NOT_A_WORD_EXCEPTION = "A distance() argument that is not a word throws required exeception";
    public static final String WORDNET_DIGRAPH_IS_NOT_DAG = "Digraph is not rooted DAG throws expected exception";
    public static final String WORDNET_VERIFY_NOUNS = "WordNet nouns are correct";
    public static final String WORDNET_VERIFY_NOUNS_CONTAINS_WORD_TRUE = "WordNet isNoun() for existing word is true";
    public static final String WORDNET_VERIFY_NOUNS_CONTAINS_WORD_FALSE = "WordNet isNount() for missing word is false";
    public static final String WORDNET_VERIFY_DISTANCE = "WordNet distance() is correct";
    public static final String WORDNET_VERIFY_SAP = "WordNet sap() is correct";

    public static final String SAP_LENGTH_ARGUMENT_EXCEPTION = "Null length() argument throws required exeception";
    public static final String SAP_LENGTH_ITERABLE_FIRST_ARGUMENT_HAS_NULL = "Null values in length() first iterable argument throws required exeception";
    public static final String SAP_LENGTH_ITERABLE_SECOND_ARGUMENT_HAS_NULL = "Null values in length() second iterable argument throws required exeception";
    public static final String SAP_LENGTH_ITERABLE_FIRST_ARGUMENT_VERTEX_ERROR = "Invalid vertex in length() first argument throws required exeception";
    public static final String SAP_LENGTH_ITERABLE_SECOND_ARGUMENT_VERTEX_ERROR = "Invalid vertex in length() second argument throws required exeception";

    public static final String SAP_ANCESTOR_ARGUMENT_EXCEPTION = "Null ancestor() argument throws required exeception";
    public static final String SAP_ANCESTOR_ITERABLE_FIRST_ARGUMENT_EXCEPTION = "Null values in ancestor() first iterable argument throws required exeception";
    public static final String SAP_ANCESTOR_ITERABLE_SECOND_ARGUMENT_EXCEPTION = "Null values in ancestor() second iterable argument throws required exeception";
    public static final String SAP_ANCESTOR_ITERABLE_FIRST_ARGUMENT_VERTEX_ERROR = "Invalid vertex in ancestor() first argument throws required exeception";
    public static final String SAP_ANCESTOR_ITERABLE_SECOND_ARGUMENT_VERTEX_ERROR = "Invalid vertex in ancestor() second argument throws required exeception";

    public static final String OUTCAST_NULL_OUTCAST_ARGUMENT = "Null outcast() argument throws required exception";

    public static String dateTime() {
    String pattern = "yyyy-MM-dd h:mm a";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
    return simpleDateFormat.format(new Date());
    }
    }
    17 changes: 17 additions & 0 deletions test-output
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    WordNet Test Suite 2019-06-12 11:11 AM
    API Tests
    Expected methods => PASSED
    Corner Case Tests
    Null constructor argument throws required exception => PASSED
    Digraph is not rooted DAG throws expected exception => PASSED
    Null isNoun() argument throws required exeception => PASSED
    Null distance() argument throws required exeception => PASSED
    A distance() argument that is not a word throws required exeception => PASSED
    Null sap() argument throws required exeception => PASSED
    An sap() argument that is not a word throws required exeception => PASSED
    Functional Tests
    WordNet nouns are correct => PASSED
    WordNet isNoun() for existing word is true => PASSED
    WordNet isNount() for missing word is false => PASSED
    WordNet distance() is correct => PASSED
    WordNet sap() is correct => PASSED