/**
 * Tester class for KeyWord
 * Written for Programming Assignment 3, Summer 2014
 */
import java.util.*;
public class KeyWordTester {
	
	public static void main(String[] args) {
		testCtor();
		testGetWord();
		testGetOccurrences();
		testEquals();
		testCompareTo();
		System.out.println("Done testing KeyWord");
	}

	private static void testCtor() {
		String myWord = "word";
		String myWORD = "WORD";
		KeyWord entry;
		
		// test normal construction
		entry = new KeyWord(myWord);
		
		if (!(entry instanceof Comparable))
			error("KeyWord doesn't implement Comparable interface");
		if (!(entry instanceof Prioritizable))
			error("KeyWord doesn't implement Prioritizable interface");
		
		if (!entry.getWord().equals(myWord)) {
			error("ctor followed by getWord incorrect");
		}
		if (entry.getOccurrences() != 0) {
			error("ctor resulted in non-0 occurrences");
		}
		if (entry.getPriority() != 0) {
			error ("ctor resulted in non-0 priority");
		}
		
		// test bad arguments
		try {
			entry = new KeyWord(null);
			error("ctor didn't throw exception on null input");
		} catch (IllegalArgumentException e) {
			// expected
		} catch (Exception e) {
			error("ctor threw wrong exception on null input");
		}
		try {
			entry = new KeyWord("");
			error("ctor didn't throw exception on empty string");
		} catch (IllegalArgumentException e) {
			// expected
		} catch (Exception e) {
			error("ctor threw wrong exception on empty string");
		}
		
		// check case considerations
		entry = new KeyWord(myWORD);
		if (!entry.getWord().equals(myWord)) {
			error("ctor/getWord not case insensitive");
		}
	}
	
	private static void testGetWord() {
		String myWord1 = "word1";
		String myWord2 = "word2";
		KeyWord entry1 = new KeyWord(myWord1);
		KeyWord entry2 = new KeyWord(myWord2);
		if (entry2.getWord().equals(myWord1)) {
			error("word data member may be static - check");
		}
	}
	
	private static void testGetOccurrences() {
		String myWord1 = "word1";
		String myWord2 = "word2";
		KeyWord entry1 = new KeyWord(myWord1);
		KeyWord entry2 = new KeyWord(myWord2);
		int occur1, occur2;
		occur1 = entry1.getOccurrences();
		entry1.increment();
		
		occur2 = entry1.getOccurrences();
		if (occur1 + 1 != occur2)
			error("increment immediately after ctor incorrect");
		if (occur2 == entry2.getOccurrences())
			error("occurrence data member may be static - check");
		if (occur2 != entry1.getPriority())
			error("occurrences and priority not equal");
		
		for (int i = 0; i < 10; i++)
			entry1.increment();
		if (entry1.getOccurrences() != occur2 + 10)
			error("increment multiple times incorrect");
		if (entry1.getOccurrences() != entry1.getPriority())
			error("occurrences and priority not equal");
	}
	
	private static void testEquals() {
		String myWord1 = "word1";
		String myWord2 = "WORD1";
		KeyWord entry1 = new KeyWord(myWord1);
		KeyWord entry2 = new KeyWord(myWord2);
		
		if (!entry1.equals(entry2)) {
			error("equals is not case insensitive");
		}
		
		entry2 = new KeyWord(new String(myWord1));
		if (!entry1.equals(entry2)) {
			error("equals incorrect with identical words");
		}
		
		entry1.increment();
		entry1.increment();
		entry2 = new KeyWord(new String(myWord1));
		if (!entry1.equals(entry2)) {
			error("equals incorrect with identical words but diff occurences");
		}
		
		try {
			if (entry1.equals(null)) {
				error("equals with null returns true ");
			}
		} catch (NullPointerException e) {
			error("equals with null causes NullPointerException");
		} catch (Exception e) {
			error("equals with null threw an unexpected exception");
		}
		
		try {
			if (entry1.equals(myWord1)) {
				error("equals with non-KeyWord returns true");
			}
		} catch (Exception e) {
			error("equals with non-KeyWord threw an exception");
		}
	}
	
	private static void testCompareTo() {
		String myWord1 = "word1";
		String myWord2 = "word2";
		String myWord0 = "word0";
		String myWord3 = "WORD1";
		KeyWord entry0 = new KeyWord(myWord0);
		KeyWord entry1 = new KeyWord(myWord1);
		KeyWord entry2 = new KeyWord(myWord2);
		KeyWord entry11 = new KeyWord(myWord1);
		KeyWord entry3 = new KeyWord(myWord3);
		
		if (entry1.compareTo(entry11) != 0)	{
			error("compareTo on 2 equal but distinct KeyWords incorrect");
		}
		if (entry1.compareTo(entry3) != 0) {
			error("compareTo not case insensitive");
		}
		try {
			entry0.compareTo(null);
			error("compareTo with null did not throw NulPointerException");
		} catch (NullPointerException e) {
			//expected
		} catch (Exception e) {
			error("compareTo with null threw wrong exception");
		}
		
		if (!(entry0.compareTo(entry1) < 0 && entry1.compareTo(entry2) < 0
				&& entry2.compareTo(entry1) > 0 && entry1.compareTo(entry0) > 0)) {
			error("compareTo computes incorrect results");
		}
	}
	
	private static void error(String msg) {
		System.out.println(msg);
	}
}