Create spell checker that uses dictionary that stores its wo
Create spell checker that uses dictionary that stores its words in a balanced binary tree.
Tasks and Requirements
NOTE: Naming is critical in the tasks and requirements described below. If the names don\'t match those described below exactly, your project will not be graded.
Create a copy of the Java SE Project Template. The project name must follow this pattern: {FLname}_SpellChecker_{TERM}, where {FLname} is replaced by the first letter of your first name plus your last name, and {TERM} is the current semester and year. E.g. if your name is Maria Marciano and it\'s Fall 2014, your project name must be MMarciano_SpellChecker_F14.
Create a package named spellchecker in your project.
BinaryTreeNode class:
Download BinaryTreeNode.java, and put it in the spellchecker package.
Your BinaryTree class must use BinaryTreeNode to store its words.
Do not modify BinaryTreeNode.java.
BasicDictionary class:
Download the Dictionary.java interface and put it in the spellchecker package.
Read the comments above each method to understand what they are supposed to do.
Create a new class named BasicDictionary in the spellchecker package. In the class creation wizard, click the Add (interface) button, and search for Dictionary. Check the \"Inherited abstract methods\" box. Click Finish. Eclipse will create the class and automatically add method stubs that meet the Dictionary interface.
You do not modify the Dictionary interface. You add your code to the BasicDictionary class.
BasicDictionary must use a binary tree to store the words in the dictionary. BasicDictionary can hold the root of the binary tree, but a stronger design would use a separate BinaryTree class.
You must write your own binary tree code.
BasicSpellChecker class:
Download the SpellChecker.java interface and put it in the spellchecker package.
Read the comments above each method to understand what they are supposed to do.
In BasicSpellChecker, modify the public class BasicSpellChecker to include implements SpellChecker.
You can use Eclipse\'s QuickFix support to add the required methods to BasicSpellChecker.
You do not modify the SpellChecker interface. You add your spell-checking code to BasicSpellChecker\'s methods.
Add the unit testing classes. These classes will be used to test the code that you write.
Create a new package in the src folder called sbccunittest. To be clear: sbccunittest should be a child of the src folder, not of the spellchecker package.
Download SpellCheckerTester.java into sbccunittest.
Download test_files.zip into your project root and unzip them into your project\'s root folder.
Spell-checking notes
Be sure to read the SpellChecker.spellCheck() documentation carefully. It specifies the regular expression that you must use for iterating through words in the document.
It also describes an instance variable of BasicSpellChecker that you need to create and update - the current spell checking index.
Also be sure to read the SpellChecker.replaceText() documentation carefully. It describes how the spell checking index is to be adjusted when replaceText() is called.
Note that the test documents are Windows files, which means that each line ends with \ \ (i.e. two characters).
Ignore case when comparing words.
Unit Testing
Debug all java compilation Errors (see the Problems view). The unit tests can\'t be run until these errors are fixed.
In the Package Explorer, right-click on the sbccunittest package | Run As... | JUnit Test.
Initially, all of the tests will probably fail. However, as you add functionality to the BasicDictionary class, tests will begin to pass.
Work on BasicDictionary first. Continue adding functionality to the BasicDictionary until all of the dictionary tests (see Scoring section below) pass. Then start working on BasicSpellChecker and its associated tests.
There is no user interface requirement for this assignment. However, you might find it interesting to build a simple console interface that allows the user to specify a dictionary and a text document to spell check. When an unknown word is found, give the user options to ignore the word, change it themselves, replace it with the preceeding/succeeding word, or end the spell checking. When spell checking is completed, overwrite the original text document with the spell-checked version.
** When importing the dictionary, build a complete tree.
MARK ANDEZSON Www.ANDERTOONS COM 2 3 2 +3 CAT OO ANDERSON \"It\'s a blackboard. There is no spell check.\"Solution
MeinTesting.java
package spellchecker;
import static java.lang.System.*;
import static org.apache.commons.io.FileUtils.*;
import java.io.*;
public class MeinTesting {
int treeDepth;
public static void main(String[] args) {
String[] wholeFile = null;
try {
wholeFile = readFileToString(new File(\"full_dictionary.txt\")).split(\"\ \");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
out.println(\"WholeSize\" + wholeFile.length);
out.println(wholeFile[0].compareTo(wholeFile[1]));
out.println(wholeFile[2].compareTo(wholeFile[3]));
String previous = \"\'AAAbo\";
int count = 0;
for (String curr : wholeFile) {
if (previous.compareToIgnoreCase(curr) > 0) {
out.println(\"Miss Found:\" + previous + \"::\" + curr);
count++;
}
previous = curr;
}
out.println(\"Count:\" + count);
int x = 1;
BasicDictionary B = new BasicDictionary();
try {
// B.importCompleteFile(\"full_dictionary.txt\");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.print(B.getTreeDepth(B));
}
private static int findInsertPoint(int n) {
int fullTreeCount = 0;
int x = 1;
int maxDepth = 0;
// This could be organized better so that X isn\'t changed after being added
// to fullTreeCount to make later math a bit easier.
while (fullTreeCount < n) {
fullTreeCount = fullTreeCount + x;
x = x * 2;
maxDepth++;
}
int lastComplete = (x / 2) - 1;
int lastRow = n - lastComplete;
int tippingPoint = x / 4;
int insertStartPoint;
if (lastRow > tippingPoint) {
insertStartPoint = lastComplete / 2 + tippingPoint;
} else {
insertStartPoint = lastComplete / 2 + lastRow;
}
out.print(\"X:\" + x + \" Last Row:\" + lastRow + \" \\t\\t\" + \"InsertStart:\" + insertStartPoint + \"\\tTipping\\t\"
+ tippingPoint + \"\\t\\t\");
return maxDepth;
}
}
BasicDictionary.java
package spellchecker;
import static org.apache.commons.io.FileUtils.*;
import java.io.*;
import java.util.*;
import org.apache.commons.io.*;
public class BasicDictionary implements Dictionary {
private BinaryTree BT;
private int count;
int treeDepth;
public BasicDictionary() {
BT = new BinaryTree();
count = 0;
}
public void importFileRandom(String filename) throws Exception {
String wholeFile = FileUtils.readFileToString(new File(filename));
BT = new BinaryTree(); // clear old dictionary
String[] st = wholeFile.split(\"\ \");
int itemsInArray = st.length;
Random rand = new Random();
while (itemsInArray != 0) {
int random = rand.nextInt(itemsInArray);
this.add(st[random]);
st[random] = st[itemsInArray - 1];
itemsInArray--;
}
}
public void importFile(String filename) throws Exception {
String wholeFile = FileUtils.readFileToString(new File(filename));
BT = new BinaryTree(); // clear old dictionary
// TODO: Make this use \ \ or \ based on system
String[] st = wholeFile.split(\"\ \");
insertCompleteFromArray(st);
}
private void insertCompleteFromArray(String[] st) {
int insertPoint = findInsertPoint(st.length);
// TODO: This should never happen - throw exception?
if (st.length == 0)
return;
BT.insert(st[insertPoint]);
if (st.length == 2) {
BT.insert(st[1]);
BT.insert(st[0]);
} else if (st.length != 1) {
String[] left = Arrays.copyOfRange(st, 0, insertPoint);
insertCompleteFromArray(left);
String[] right = Arrays.copyOfRange(st, insertPoint + 1, st.length);
insertCompleteFromArray(right);
}
return;
}
private int findInsertPoint(int n) {
// My overly complicated version
int fullTreeCount = 0;
int x = 1;
// TODO: Re-factor
// Find the size of a full tree that will hold this many nodes
while (fullTreeCount < n) {
fullTreeCount = fullTreeCount + x;
x = x * 2;
}
int lastComplete = (x / 2) - 1; // nodes would be in the bottom row of the full tree
int lastRow = n - lastComplete; // nodes will be in the bottom row of this tree
int tippingPoint = x / 4; // halfway through bottom row - point where nodes are put in the right subtree
int insertStartPoint;
if (lastRow > tippingPoint) {
insertStartPoint = lastComplete / 2 + tippingPoint;
} else {
insertStartPoint = lastComplete / 2 + lastRow;
}
return insertStartPoint;
}
public void load(String filename) throws Exception {
List<String> lines = FileUtils.readLines(new File(filename));
BT = new BinaryTree();
for (String word : lines) {
add(word);
}
}
@Override
public void save(String filename) throws Exception {
ArrayList<String> result = BT.preOrderTraverse();
File outFile = new File(filename);
writeLines(outFile, result);
}
public String[] find(String word) {
String S[] = { \"\", \"\" };
BinaryTreeNode curr = this.getRoot();
while (true) {
int comp = curr.value.compareToIgnoreCase(word);
if (comp > 0) {
S[1] = curr.value;
if (curr.left == null) {
return S;
} else {
curr = curr.left;
}
} else if (comp < 0) {
S[0] = curr.value;
if (curr.right == null) {
return S;
} else {
curr = curr.right;
}
} else {
return null;
}
}
}
@Override
public void add(String word) {
BT.insert(word.trim());
count++; // TODO check that word isn\'t reinserted
}
@Override
public BinaryTreeNode getRoot() {
return BT.top;
}
public ArrayList<String> inOrder() {
return BT.inOrderTraverse();
}
public ArrayList<String> preOrder() {
return BT.preOrderTraverse();
}
public int getTreeDepth(Dictionary dictionary) {
treeDepth = 0;
goDeeper(dictionary.getRoot(), 0);
return treeDepth;
}
private void goDeeper(BinaryTreeNode node, int depth) {
if (node != null) {
depth++;
if (depth > treeDepth)
treeDepth = depth;
if (node.left != null)
goDeeper(node.left, depth);
if (node.right != null)
goDeeper(node.right, depth);
}
}
@Override
public int getCount() {
return count;
}
}
BasicSpellChecker.java
package spellchecker;
import static org.apache.commons.io.FileUtils.*;
import java.io.*;
import java.util.regex.*;
public class BasicSpellChecker implements SpellChecker {
BasicDictionary D;
String currentDoc;
int indexInDoc;
public BasicSpellChecker() {
super();
D = new BasicDictionary();
indexInDoc = 0;
currentDoc = \"\";
}
@Override
public void importDictionary(String filename) throws Exception {
D.importFile(filename);
}
@Override
public void loadDictionary(String filename) throws Exception {
D.load(filename);
}
@Override
public void saveDictionary(String filename) throws Exception {
D.save(filename);
}
@Override
public void loadDocument(String filename) throws Exception {
currentDoc = readFileToString(new File(filename));
}
@Override
public void saveDocument(String filename) throws Exception {
writeStringToFile(new File(filename), currentDoc);
}
@Override
public String getText() {
return currentDoc;
}
@Override
public String[] spellCheck(boolean continueFromPrevious) {
// Start from beginning or last checked word?
indexInDoc = (continueFromPrevious) ? indexInDoc : 0;
Pattern P = Pattern.compile(\"\\\\b[\\\\w|\']+\\\\b\");
Matcher M = P.matcher(currentDoc);
// loop through current doc until Dictionary.Find() returns a non-null
while (M.find(indexInDoc)) {
int startX;
String word = M.group();
startX = M.start();
indexInDoc = M.end();
String[] result = D.find(word);
if (result != null) {
String[] retVal = { word, Integer.toString(startX), result[0], result[1] };
return retVal;
}
}
return null;
}
@Override
public void addWordToDictionary(String word) {
D.add(word);
}
@Override
public void replaceText(int startIndex, int endIndex, String replacementText) {
String tempDoc = currentDoc.substring(0, startIndex) + replacementText + currentDoc.substring(endIndex);
currentDoc = tempDoc;
int oldLength = endIndex - startIndex;
int newLength = replacementText.length();
indexInDoc = endIndex + (newLength - oldLength);
}
}
BinaryTree.java
package spellchecker;
import java.util.*;
public class BinaryTree {
public BinaryTreeNode top;
public BinaryTree() {
super();
// TODO Auto-generated constructor stub
top = null;
}
public void insert(String word) {
word = word.trim(); // Needed to deal with \ on windows machines
if (top == null) { // inserting into empty tree
top = new BinaryTreeNode(word);
return;
}
// Tree not empty - start at the top
BinaryTreeNode curr = top;
// TODO: re-factor so newBinaryTreeNode and return statement
// code only exist in one place
while (true) {
int comp = curr.value.compareToIgnoreCase(word);
if (comp > 0) { // word is to left
if (curr.left == null) {
curr.left = new BinaryTreeNode(word);
return;
} else {
curr = curr.left;
}
} else if (comp < 0) { // word is to the right
if (curr.right == null) {
curr.right = new BinaryTreeNode(word);
return;
} else {
curr = curr.right;
}
} else { // word already in dictionary - we\'re done here.
return;
}
}
}
// All traversals have their public function that calls the internal recursive function
public ArrayList<String> inOrderTraverse() {
ArrayList<String> result = inOrderTraverse(top);
return result;
}
private ArrayList<String> inOrderTraverse(BinaryTreeNode node) {
ArrayList<String> returnValue;
if (node == null) {
returnValue = new ArrayList<String>();
return returnValue;
}
returnValue = inOrderTraverse(node.left);
returnValue.add(node.value);
returnValue.addAll((inOrderTraverse(node.right)));
return returnValue;
}
public ArrayList<String> preOrderTraverse() {
ArrayList<String> result = preOrderTraverse(top);
return result;
}
private ArrayList<String> preOrderTraverse(BinaryTreeNode node) {
ArrayList<String> returnValue;
if (node == null) {
returnValue = new ArrayList<String>();
return returnValue;
}
returnValue = new ArrayList<String>();
returnValue.add(node.value);
returnValue.addAll(preOrderTraverse(node.left));
returnValue.addAll(preOrderTraverse(node.right));
return returnValue;
}
public ArrayList<String> postOrderTraverse() {
ArrayList<String> result = postOrderTraverse(top);
return result;
}
private ArrayList<String> postOrderTraverse(BinaryTreeNode node) {
ArrayList<String> returnValue;
if (node == null) {
returnValue = new ArrayList<String>();
return returnValue;
}
returnValue = postOrderTraverse(node.left);
returnValue.addAll(postOrderTraverse(node.right));
returnValue.add(node.value);
return returnValue;
}
}
BinaryTreeNode.java
package spellchecker;
public class BinaryTreeNode {
public BinaryTreeNode left;
public BinaryTreeNode right;
public String value;
BinaryTreeNode(String value) {
this.value = value;
}
BinaryTreeNode(BinaryTreeNode node) {
left = node.left;
right = node.right;
value = node.value;
}
}
Dictionary.java
package spellchecker;
public interface Dictionary {
/**
* Replaces the current dictionary with words imported from the specified text file. Words in the file are in
* lexicographical (ASCII) order, one word per line.
*
*/
public void importFile(String filename) throws Exception;
/**
* Loads the specified file from a previously saved dictionary tree file. The file format is text, with one word per
* line.
*
*/
public void load(String filename) throws Exception;
/**
* Saves the dictionary tree to the specified file in preorder. The file format is text, with one word per line.
*
*/
public void save(String filename) throws Exception;
public String[] find(String word);
/**
* Adds the given word to the dictionary\'s binary tree. Duplicates are ignored.
*
* @param word
*/
public void add(String word);
/**
*
* @return Returns a reference to the root node of the binary tree.
*/
public BinaryTreeNode getRoot();
/**
*
* @return Returns the number of words in the dictionary.
*/
public int getCount();
}
SpellChecker.java
package spellchecker;
public interface SpellChecker {
/**
* Replaces the current dictionary with words imported from the specified text file. Words in the file are in
* lexicographical (ASCII) order, one word per line.
*
*/
public void importDictionary(String filename) throws Exception;
/**
* Loads the specified file from a previously saved dictionary tree file. The file format is text, with one word per
* line.
*
*/
public void loadDictionary(String filename) throws Exception;
/**
* Saves the dictionary tree to the specified file in preorder. The file format is text, with one word per line.
*
*/
public void saveDictionary(String filename) throws Exception;
/**
* Loads the specified text document.
*/
public void loadDocument(String filename) throws Exception;
/**
* Saves the specified text document.
*
*/
public void saveDocument(String filename) throws Exception;
/**
*
* @return Returns the text in the text editor.
*/
public String getText();
public String[] spellCheck(boolean continueFromPrevious);
public void addWordToDictionary(String word);
public void replaceText(int startIndex, int endIndex, String replacementText);
}
SpellCheckerTester.java
package sbccunittest;
import static org.junit.Assert.*;
import java.io.*;
import java.util.*;
import org.apache.commons.io.*;
import org.junit.*;
import spellchecker.*;
import spellchecker.Dictionary;
public class SpellCheckerTester {
public static String newline = System.getProperty(\"line.separator\");
public static int totalScore = 0;
public static int extraCredit = 0;
@BeforeClass
public static void beforeTesting() {
totalScore = 0;
extraCredit = 0;
}
@AfterClass
public static void afterTesting() {
System.out.println(\"Estimated score (assuming no late penalties, etc.) = \" + totalScore);
System.out.println(\"Estimated extra credit (assuming on time submission) = \" + extraCredit);
}
@Test(timeout = 10000)
public void testImportFile() throws Exception {
Dictionary dictionary = new BasicDictionary();
dictionary.importFile(\"full_dictionary.txt\");
assertNotNull(\"Dictionary.getRoot() should not be null.\", dictionary.getRoot());
int depth = getTreeDepth(dictionary);
int maxDepth = 100;
if (depth > maxDepth)
fail(\"The tree depth is \" + depth + \" is greater than the maximum allowed depth of \" + maxDepth + \".\");
dictionary.save(\"full_dictionary.pre\");
String s = FileUtils.readFileToString(new File(\"full_dictionary.pre\"));
String[] parts = s.split(\"\ \");
assertEquals(175169, parts.length);
totalScore += 12;
}
@Test(timeout = 10000)
public void testImportFileCompleteTree() throws Exception {
Dictionary dictionary = new BasicDictionary();
dictionary.importFile(\"full_dictionary.txt\");
assertNotNull(\"Dictionary.getRoot() should not be null.\", dictionary.getRoot());
int depth = getTreeDepth(dictionary);
int maxDepth = 18;
if (depth > maxDepth)
fail(\"The tree depth is \" + depth + \", which is greater than the maximum allowed depth of \" + maxDepth
+ \".\");
dictionary.save(\"full_dictionary.pre\");
String s = FileUtils.readFileToString(new File(\"full_dictionary.pre\"));
String[] parts = s.split(\"\ \");
assertEquals(175169, parts.length);
extraCredit += 5;
}
int treeDepth;
public int getTreeDepth(Dictionary dictionary) {
treeDepth = 0;
goDeeper(dictionary.getRoot(), 0);
return treeDepth;
}
private void goDeeper(BinaryTreeNode node, int depth) {
if (node != null) {
depth++;
if (depth > treeDepth)
treeDepth = depth;
if (node.left != null)
goDeeper(node.left, depth);
if (node.right != null)
goDeeper(node.right, depth);
}
}
@Test(timeout = 10000)
public void testLoad() throws Exception {
Dictionary dictionary = new BasicDictionary();
dictionary.load(\"dict_14.pre\");
assertNotNull(\"Dictionary.getRoot() should not be null.\", dictionary.getRoot());
int depth = getTreeDepth(dictionary);
assertEquals(6, depth);
totalScore += 8;
}
@Test(timeout = 10000)
public void testSave() throws Exception {
Dictionary dictionary = new BasicDictionary();
String[] words = new String[] { \"bull\", \"are\", \"genetic\", \"cotton\", \"dolly\", \"florida\", \"each\", \"bull\" };
for (String word : words)
dictionary.add(word);
dictionary.save(\"test_save.pre\");
String s = FileUtils.readFileToString(new File(\"test_save.pre\"));
String[] parts = s.split(\"\ \");
assertEquals(words.length - 1, parts.length);
for (int ndx = 0; ndx < parts.length; ndx++)
assertEquals(words[ndx], parts[ndx].trim().toLowerCase());
totalScore += 8;
}
@Test(timeout = 10000)
public void testFind() throws Exception {
Dictionary dictionary = new BasicDictionary();
String dictionaryPath = \"dict_14.pre\";
dictionary.load(dictionaryPath);
checkWord(dictionary, dictionaryPath, \"cotton\", null);
checkWord(dictionary, dictionaryPath, \"CottoN\", null);
checkWord(dictionary, dictionaryPath, \"Cotto\", new String[] { \"bull\", \"cotton\" });
checkWord(dictionary, dictionaryPath, \"mit\", new String[] { \"life\", \"mite\" });
checkWord(dictionary, dictionaryPath, \"mite\", null);
checkWord(dictionary, dictionaryPath, \"just\", null);
totalScore += 8;
}
private void checkWord(Dictionary dictionary, String dictionaryPath, String word, String[] expectedResult) {
String[] result = dictionary.find(word);
if (expectedResult != null) {
if (result != null) {
assertEquals(expectedResult[0], result[0]);
assertEquals(expectedResult[1], result[1]);
} else
fail(\"Didn\'t find \" + word + \" in \" + dictionaryPath);
} else {
if (result != null) {
fail(\"The dictionary returned \" + (result.length > 0 ? result[0] : \"an empty array\")
+ \" but should have returned null because \" + word + \" does exist in \" + dictionaryPath);
}
}
}
@Test
public void testLoadDocument() throws Exception {
String dictionaryText = FileUtils.readFileToString(new File(\"small_dictionary.txt\"));
String[] words = dictionaryText.split(newline);
Random rng = new Random();
String doc = words[rng.nextInt(words.length)].trim() + \" \" + words[rng.nextInt(words.length)].trim() + \" \"
+ words[rng.nextInt(words.length)].trim() + \" \" + words[rng.nextInt(words.length)].trim() + \" \"
+ words[rng.nextInt(words.length)].trim();
FileUtils.write(new File(\"random_doc.txt\"), doc);
SpellChecker basicSpellChecker = new BasicSpellChecker();
basicSpellChecker.loadDocument(\"random_doc.txt\");
String text = basicSpellChecker.getText();
assertEquals(doc, text);
totalScore += 2;
}
@Test
public void testSpellCheckWithOneUnknownWord() throws Exception {
SpellChecker basicSpellChecker = new BasicSpellChecker();
String dictionaryImportPath = \"small_dictionary.txt\";
String dictionaryPath = \"small_dictionary.pre\";
String documentPath = \"small_document_one_unknown.txt\";
basicSpellChecker.importDictionary(dictionaryImportPath);
basicSpellChecker.saveDictionary(dictionaryPath);
basicSpellChecker.loadDocument(documentPath);
String[] result;
result = basicSpellChecker.spellCheck(false);
if (result == null)
fail(\"There should be one unknown word in \" + documentPath + \" when the dictionary is \"
+ dictionaryImportPath);
else {
assertEquals(\"explosins\", result[0]);
assertEquals(\"87\", result[1]);
assertEquals(\"ever\", result[2]);
assertEquals(\"explosions\", result[3]);
}
totalScore += 6;
}
@Test
public void testSpellCheckReplaceOneUnknownWord() throws Exception {
SpellChecker basicSpellChecker = new BasicSpellChecker();
String dictionaryImportPath = \"small_dictionary.txt\";
String dictionaryPath = \"small_dictionary.pre\";
String documentPath = \"small_document_one_unknown.txt\";
basicSpellChecker.importDictionary(dictionaryImportPath);
basicSpellChecker.saveDictionary(dictionaryPath);
basicSpellChecker.loadDocument(documentPath);
String[] result;
// Spell-check and find one word misspelled.
result = basicSpellChecker.spellCheck(false);
if (result == null)
fail(\"There should be one unknown word in \" + documentPath + \" when the dictionary is \"
+ dictionaryImportPath);
else {
assertEquals(\"explosins\", result[0]);
assertEquals(\"87\", result[1]);
assertEquals(\"ever\", result[2]);
assertEquals(\"explosions\", result[3]);
}
// Replace it with the second suggestion.
int startIndex = Integer.parseInt(result[1]);
int endIndex = startIndex + result[0].length();
basicSpellChecker.replaceText(startIndex, endIndex, result[3]);
// Check against corrected.
String text = basicSpellChecker.getText();
String expected = FileUtils.readFileToString(new File(\"small_document_one_unknown_corrected.txt\"));
assertEquals(expected, text);
totalScore += 6;
}
@Test
public void testSpellCheckNoUnknownWords() throws Exception {
SpellChecker basicSpellChecker = new BasicSpellChecker();
String dictionaryImportPath = \"small_dictionary.txt\";
String dictionaryPath = \"small_dictionary.pre\";
String documentPath = \"small_document.txt\";
basicSpellChecker.importDictionary(dictionaryImportPath);
basicSpellChecker.saveDictionary(dictionaryPath);
basicSpellChecker.loadDocument(documentPath);
String[] result;
result = basicSpellChecker.spellCheck(false);
if (result != null)
fail(\"There should be no unknown words in \" + documentPath + \" when the dictionary is \" + dictionaryPath);
totalScore += 4;
}
@Test
public void testSpellCheckReplaceUnknowns() throws Exception {
SpellChecker basicSpellChecker = new BasicSpellChecker();
String dictionaryImportPath = \"small_dictionary.txt\";
String dictionaryPath = \"small_dictionary.pre\";
String documentPath = \"small_document_four_unknown.txt\";
basicSpellChecker.importDictionary(dictionaryImportPath);
basicSpellChecker.saveDictionary(dictionaryPath);
basicSpellChecker.loadDocument(documentPath);
String[] result;
// Find first unknown
result = basicSpellChecker.spellCheck(false);
if (result == null)
fail(\"Failed to find the first unknown word in \" + documentPath + \" when the dictionary is \"
+ dictionaryImportPath);
else {
assertEquals(\"explosins\", result[0]);
assertEquals(\"87\", result[1]);
assertEquals(\"ever\", result[2]);
assertEquals(\"explosions\", result[3]);
}
// Replace it with the successor word
int startIndex = Integer.parseInt(result[1]);
int endIndex = startIndex + result[0].length();
basicSpellChecker.replaceText(startIndex, endIndex, result[3]);
// find the 2nd unknown (the word \"which\")
result = basicSpellChecker.spellCheck(true);
if (result == null)
fail(\"Failed to find the second unknown word in \" + documentPath + \" when the dictionary is \"
+ dictionaryImportPath);
else {
assertEquals(\"which\", result[0]);
assertEquals(\"130\", result[1]);
assertEquals(\"use\", result[2]);
assertEquals(\"with\", result[3]);
}
// Add this word to the dictionary
String wordToAdd = result[0];
basicSpellChecker.addWordToDictionary(result[0]);
// find the 3rd unknown (the word \"vast\")
result = basicSpellChecker.spellCheck(true);
if (result == null)
fail(\"Failed to find the third unknown word in \" + documentPath + \" when the dictionary is \"
+ dictionaryImportPath);
else {
assertEquals(\"vast\", result[0]);
assertEquals(\"275\", result[1]);
assertEquals(\"use\", result[2]);
assertEquals(\"which\", result[3]);
}
// Find third unknown
result = basicSpellChecker.spellCheck(true);
if (result == null)
fail(\"Failed to find the fourth unknown word in \" + documentPath + \" when the dictionary is \"
+ dictionaryImportPath);
else {
assertEquals(\"cuosmos\", result[0]);
assertEquals(\"280\", result[1]);
assertEquals(\"cosmos\", result[2]);
assertEquals(\"dozen\", result[3]);
}
// Replace it with the predecessor word
startIndex = Integer.parseInt(result[1]);
endIndex = startIndex + result[0].length();
basicSpellChecker.replaceText(startIndex, endIndex, result[2]);
// Verify document is correct
String expectedText = FileUtils.readFileToString(new File(\"small_document_four_unknown_corrected.txt\"));
String actualText = basicSpellChecker.getText();
assertEquals(expectedText, actualText);
// Verify the saved document is correct
basicSpellChecker.saveDocument(\"small_document_four_unknown_after_spellchecking.txt\");
actualText = FileUtils.readFileToString(new File(\"small_document_four_unknown_after_spellchecking.txt\"));
assertEquals(expectedText, actualText);
// Verify the dictionary is correct
basicSpellChecker.saveDictionary(\"small_dictionary_after_spellchecking.pre\");
String dictText = FileUtils.readFileToString(new File(\"small_dictionary_after_spellchecking.pre\"));
if (!dictText.contains(wordToAdd))
fail(\"Dictionary file didn\'t contain \" + wordToAdd + \".\");
totalScore += 4;
}
@Test
public void testSpellCheckNoSuccessor() throws Exception {
SpellChecker basicSpellChecker = new BasicSpellChecker();
String dictionaryImportPath = \"small_dictionary.txt\";
String dictionaryPath = \"small_dictionary.pre\";
String documentPath = \"small_document_test_no_successor.txt\";
basicSpellChecker.importDictionary(dictionaryImportPath);
basicSpellChecker.saveDictionary(dictionaryPath);
basicSpellChecker.loadDocument(documentPath);
String[] result;
// Find first unknown
result = basicSpellChecker.spellCheck(false);
if (result == null)
fail(\"Failed to find the first unknown word in \" + documentPath + \" when the dictionary is \"
+ dictionaryImportPath);
else {
assertEquals(\"zebras\", result[0]);
assertEquals(\"87\", result[1]);
assertEquals(\"with\", result[2]);
assertEquals(\"\", result[3]);
}
totalScore += 2;
}
}


















