001: /*
002: * Copyright 2001-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.comparators;
017:
018: import java.util.Arrays;
019: import java.util.Comparator;
020: import java.util.LinkedList;
021: import java.util.List;
022: import java.util.Random;
023:
024: import junit.framework.Test;
025: import junit.framework.TestCase;
026: import junit.framework.TestSuite;
027:
028: /**
029: * Test class for FixedOrderComparator.
030: *
031: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
032: *
033: * @author David Leppik
034: * @author Stephen Colebourne
035: */
036: public class TestFixedOrderComparator extends TestCase {
037:
038: /**
039: * Top cities of the world, by population including metro areas.
040: */
041: public static final String topCities[] = new String[] { "Tokyo",
042: "Mexico City", "Mumbai", "Sao Paulo", "New York",
043: "Shanghai", "Lagos", "Los Angeles", "Calcutta",
044: "Buenos Aires" };
045:
046: //
047: // Initialization and busywork
048: //
049:
050: public TestFixedOrderComparator(String name) {
051: super (name);
052: }
053:
054: public static Test suite() {
055: return new TestSuite(TestFixedOrderComparator.class);
056: }
057:
058: public static void main(String args[]) {
059: junit.textui.TestRunner.run(suite());
060: }
061:
062: //
063: // Set up and tear down
064: //
065:
066: //
067: // The tests
068: //
069:
070: /**
071: * Tests that the constructor plus add method compares items properly.
072: */
073: public void testConstructorPlusAdd() {
074: FixedOrderComparator comparator = new FixedOrderComparator();
075: for (int i = 0; i < topCities.length; i++) {
076: comparator.add(topCities[i]);
077: }
078: String[] keys = (String[]) topCities.clone();
079: assertComparatorYieldsOrder(keys, comparator);
080: }
081:
082: /**
083: * Tests that the array constructor compares items properly.
084: */
085: public void testArrayConstructor() {
086: String[] keys = (String[]) topCities.clone();
087: String[] topCitiesForTest = (String[]) topCities.clone();
088: FixedOrderComparator comparator = new FixedOrderComparator(
089: topCitiesForTest);
090: assertComparatorYieldsOrder(keys, comparator);
091: // test that changing input after constructor has no effect
092: topCitiesForTest[0] = "Brighton";
093: assertComparatorYieldsOrder(keys, comparator);
094: }
095:
096: /**
097: * Tests the list constructor.
098: */
099: public void testListConstructor() {
100: String[] keys = (String[]) topCities.clone();
101: List topCitiesForTest = new LinkedList(Arrays.asList(topCities));
102: FixedOrderComparator comparator = new FixedOrderComparator(
103: topCitiesForTest);
104: assertComparatorYieldsOrder(keys, comparator);
105: // test that changing input after constructor has no effect
106: topCitiesForTest.set(0, "Brighton");
107: assertComparatorYieldsOrder(keys, comparator);
108: }
109:
110: /**
111: * Tests addAsEqual method.
112: */
113: public void testAddAsEqual() {
114: FixedOrderComparator comparator = new FixedOrderComparator(
115: topCities);
116: comparator.addAsEqual("New York", "Minneapolis");
117: assertEquals(0, comparator.compare("New York", "Minneapolis"));
118: assertEquals(-1, comparator.compare("Tokyo", "Minneapolis"));
119: assertEquals(1, comparator.compare("Shanghai", "Minneapolis"));
120: }
121:
122: /**
123: * Tests whether or not updates are disabled after a comparison is made.
124: */
125: public void testLock() {
126: FixedOrderComparator comparator = new FixedOrderComparator(
127: topCities);
128: assertEquals(false, comparator.isLocked());
129: comparator.compare("New York", "Tokyo");
130: assertEquals(true, comparator.isLocked());
131: try {
132: comparator.add("Minneapolis");
133: fail("Should have thrown an UnsupportedOperationException");
134: } catch (UnsupportedOperationException e) {
135: // success -- ignore
136: }
137:
138: try {
139: comparator.addAsEqual("New York", "Minneapolis");
140: fail("Should have thrown an UnsupportedOperationException");
141: } catch (UnsupportedOperationException e) {
142: // success -- ignore
143: }
144: }
145:
146: public void testUnknownObjectBehavior() {
147: FixedOrderComparator comparator = new FixedOrderComparator(
148: topCities);
149: try {
150: comparator.compare("New York", "Minneapolis");
151: fail("Should have thrown a IllegalArgumentException");
152: } catch (IllegalArgumentException e) {
153: // success-- ignore
154: }
155: try {
156: comparator.compare("Minneapolis", "New York");
157: fail("Should have thrown a IllegalArgumentException");
158: } catch (IllegalArgumentException e) {
159: // success-- ignore
160: }
161: assertEquals(FixedOrderComparator.UNKNOWN_THROW_EXCEPTION,
162: comparator.getUnknownObjectBehavior());
163:
164: comparator = new FixedOrderComparator(topCities);
165: comparator
166: .setUnknownObjectBehavior(FixedOrderComparator.UNKNOWN_BEFORE);
167: assertEquals(FixedOrderComparator.UNKNOWN_BEFORE, comparator
168: .getUnknownObjectBehavior());
169: LinkedList keys = new LinkedList(Arrays.asList(topCities));
170: keys.addFirst("Minneapolis");
171: assertComparatorYieldsOrder(keys.toArray(new String[0]),
172: comparator);
173:
174: assertEquals(-1, comparator.compare("Minneapolis", "New York"));
175: assertEquals(1, comparator.compare("New York", "Minneapolis"));
176: assertEquals(0, comparator.compare("Minneapolis", "St Paul"));
177:
178: comparator = new FixedOrderComparator(topCities);
179: comparator
180: .setUnknownObjectBehavior(FixedOrderComparator.UNKNOWN_AFTER);
181: keys = new LinkedList(Arrays.asList(topCities));
182: keys.add("Minneapolis");
183: assertComparatorYieldsOrder(keys.toArray(new String[0]),
184: comparator);
185:
186: assertEquals(1, comparator.compare("Minneapolis", "New York"));
187: assertEquals(-1, comparator.compare("New York", "Minneapolis"));
188: assertEquals(0, comparator.compare("Minneapolis", "St Paul"));
189:
190: }
191:
192: //
193: // Helper methods
194: //
195:
196: /** Shuffles the keys and asserts that the comparator sorts them back to
197: * their original order.
198: */
199: private void assertComparatorYieldsOrder(Object[] orderedObjects,
200: Comparator comparator) {
201: Object[] keys = (Object[]) orderedObjects.clone();
202:
203: // shuffle until the order changes. It's extremely rare that
204: // this requires more than one shuffle.
205:
206: boolean isInNewOrder = false;
207: while (keys.length > 1 && isInNewOrder == false) {
208: shuffle: {
209: Random rand = new Random();
210: for (int i = keys.length - 1; i > 0; i--) {
211: Object swap = keys[i];
212: int j = rand.nextInt(i + 1);
213: keys[i] = keys[j];
214: keys[j] = swap;
215: }
216: }
217:
218: testShuffle: {
219: for (int i = 0; i < keys.length && !isInNewOrder; i++) {
220: if (!orderedObjects[i].equals(keys[i])) {
221: isInNewOrder = true;
222: }
223: }
224: }
225: }
226:
227: // The real test: sort and make sure they come out right.
228:
229: Arrays.sort(keys, comparator);
230:
231: for (int i = 0; i < orderedObjects.length; i++) {
232: assertEquals(orderedObjects[i], keys[i]);
233: }
234: }
235:
236: }
|