1   package org.marketchangers.prayer.lucene;
2   
3   import java.io.IOException;
4   import java.lang.reflect.Modifier;
5   import java.util.ArrayList;
6   import java.util.Collection;
7   import java.util.Hashtable;
8   
9   import junit.framework.TestCase;
10  
11  import org.apache.lucene.analysis.standard.StandardAnalyzer;
12  import org.apache.lucene.document.Document;
13  import org.apache.lucene.index.IndexReader;
14  import org.apache.lucene.index.IndexWriter;
15  import org.apache.lucene.index.Term;
16  import org.apache.lucene.index.TermDocs;
17  import org.apache.lucene.index.TermEnum;
18  import org.apache.lucene.index.TermFreqVector;
19  import org.apache.lucene.index.TermPositions;
20  import org.apache.lucene.search.BooleanQuery;
21  import org.apache.lucene.search.Query;
22  import org.apache.lucene.search.Searchable;
23  import org.apache.lucene.store.RAMDirectory;
24  import org.marketchangers.prayer.PrayerRequest;
25  import org.marketchangers.prayer.PrayerRequestQuery;
26  import org.marketchangers.prayer.PrayerRequestSearcher;
27  
28  import com.mockobjects.ExpectationCounter;
29  import com.mockobjects.ExpectationList;
30  import com.mockobjects.dynamic.Mock;
31  import com.mockobjects.util.Verifier;
32  
33  /***
34   * @author <a href="mailto:mtodd@wc-group.com">Matthew Todd</a>
35   */
36  public class LucenePrayerRequestSearcherTest extends TestCase {
37  	private PrayerRequestSearcher prayerRequestSearcher;
38  
39  	private Mock provider;
40  	private MockIndexReader reader;
41  	private Mock searcher;
42  	private MockIndexWriter writer;
43  
44  	// --------------------------------------------- SetUp and TearDown Methods
45  	protected void setUp() throws IOException {
46  		provider = new Mock(IndexProvider.class);
47  		reader = new MockIndexReader();
48  		searcher = new Mock(Searchable.class);
49  		writer = new MockIndexWriter();
50  
51  		prayerRequestSearcher =
52  			new LucenePrayerRequestSearcher((IndexProvider) provider.proxy());
53  	}
54  
55  	protected void tearDown() {
56  		provider.verify();
57  		reader.verify();
58  		searcher.verify();
59  		writer.verify();
60  	}
61  
62  	// ----------------------------------------------------------- Test Methods
63  	public void testWritesDocumentsIntoTheDirectoryOnIndex() {
64  		PrayerRequest request = new PrayerRequest();
65  		Document document = new Document();
66  
67  		provider.expectAndReturn("getWriter", writer);
68  		provider.expectAndReturn("translateToDocument", request, document);
69  		writer.expectAddDocument(document);
70  		writer.expectClose();
71  
72  		prayerRequestSearcher.index(request);
73  	}
74  
75  	public void testIndexMethodIsSynchronized() throws NoSuchMethodException {
76  		assertTrue(
77  			Modifier.isSynchronized(
78  				prayerRequestSearcher
79  					.getClass()
80  					.getMethod("index", new Class[] { PrayerRequest.class })
81  					.getModifiers()));
82  	}
83  
84  	public void testSearchSomehow() {
85  		// TODO Figure out how to test the Lucene code with Mocks.
86  		// Too many of their classes are final, and they don't use interfaces.
87  	}
88  
89  	public void testSearchReturnsAnEmptyListIfThereAreNoRequestors() {
90  		PrayerRequestQuery emptyQuery = new PrayerRequestQuery(new Hashtable());
91  		assertEquals(0, prayerRequestSearcher.search(emptyQuery).size());
92  	}
93  
94  	public void testDelete() throws IOException {
95  		provider.expectAndReturn("getReader", reader);
96  		reader.expectDeleteDocument(0);
97  		reader.expectClose();
98  		prayerRequestSearcher.delete(0);
99  	}
100 
101 	public void doNotTestUpdateStatus() {
102 		PrayerRequest request = new PrayerRequest();
103 		Query query = new BooleanQuery();
104 		provider.expectAndReturn("translateToQuery", request, query);
105 		provider.expectAndReturn("getReader", reader);
106 		provider.expectAndReturn("getSearcher", searcher);
107 
108 		reader.expectDeleteDocument(0);
109 		reader.expectClose();
110 
111 		prayerRequestSearcher.updateStatus(request);
112 	}
113 
114 	// ------------------------------------------------- Private Helper Classes
115 	private static class MockIndexReader extends IndexReader {
116 		private ExpectationCounter close;
117 		private ExpectationList documents;
118 		public MockIndexReader() throws IOException {
119 			super(new RAMDirectory());
120 			this.close = new ExpectationCounter("Close");
121 			this.documents = new ExpectationList("Documents");
122 		}
123 		public void doDelete(int i) {
124 		}
125 		public TermPositions termPositions() {
126 			return null;
127 		}
128 		public void doSetNorm(int doc, String field, byte value) {
129 		}
130 
131 		public Collection getIndexedFieldNames(boolean b) {
132 			return null;
133 		}
134 		public void doCommit() {
135 		}
136 		public int maxDoc() {
137 			return 1;
138 		}
139 		public void doUndeleteAll() {
140 		}
141 		public void doClose() {
142 		}
143 		public boolean isDeleted(int i) {
144 			return false;
145 		}
146 		public Document document(int i) {
147 			return new Document();
148 		}
149 		public void setNorm(int doc, String field, float value) {
150 		}
151 		public Collection getFieldNames() {
152 			return new ArrayList();
153 		}
154 		public Collection getFieldNames(boolean bool) {
155 			return new ArrayList();
156 		}
157 		public TermDocs termDocs() {
158 			return null;
159 		}
160 		public TermEnum terms() {
161 			return null;
162 		}
163 		public TermEnum terms(Term term) {
164 			return null;
165 		}
166 		public TermFreqVector getTermFreqVector(int docNumber, String field) {
167 			return null;
168 		}
169 		public TermFreqVector[] getTermFreqVectors(int docNumber) {
170 			return null;
171 		}
172 		public int numDocs() {
173 			return 10;
174 		}
175 		public void norms(String field, byte[] bytes, int offset)
176 			throws IOException {
177 
178 		}
179 		public byte[] norms(String field) {
180 			return new byte[1];
181 		}
182 		public boolean hasDeletions() {
183 			return false;
184 		}
185 
186 		public void verify() {
187 			Verifier.verifyObject(this);
188 		}
189 		public boolean isDeleted() {
190 			return false;
191 		}
192 		public void doDelete() {
193 
194 		}
195 
196 		public int docFreq(Term t) {
197 			return 0;
198 		}
199 
200 		public void expectDeleteDocument(int i) {
201 			//documents.addExpected(new Integer(i));
202 			documents.setExpectNothing();
203 		}
204 		public void expectClose() {
205 
206 			close.setExpected(0);
207 		}
208 
209 	}
210 
211 	private static class MockIndexWriter extends IndexWriter {
212 		private ExpectationCounter close;
213 		private ExpectationList documents;
214 
215 		public MockIndexWriter() throws IOException {
216 			super(new RAMDirectory(), new StandardAnalyzer(), true);
217 
218 			this.close = new ExpectationCounter("Close");
219 			this.documents = new ExpectationList("Documents");
220 		}
221 
222 		public void addDocument(Document d) {
223 			documents.addActual(d);
224 		}
225 
226 		public void close() {
227 			close.inc();
228 		}
229 
230 		public void expectAddDocument(Document d) {
231 			documents.addExpected(d);
232 		}
233 
234 		public void expectClose() {
235 			close.setExpected(1);
236 		}
237 
238 		public void verify() {
239 			Verifier.verifyObject(this);
240 		}
241 
242 	}
243 }