+++ /dev/null
-package org.apache.lucene.facet.taxonomy;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-
-import org.junit.Test;
-
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.facet.taxonomy.CategoryPath;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-public class TestCategoryPath extends LuceneTestCase {
-
- @Test
- public void testBasic() {
- CategoryPath p = new CategoryPath(0,0);
- assertEquals(0, p.length());
- for (int i=0; i<1000; i++) {
- p.add("hello");
- assertEquals(i+1, p.length());
- }
- }
-
- @Test
- public void testConstructorCapacity() {
- CategoryPath p = new CategoryPath(0,0);
- assertEquals(0, p.capacityChars());
- assertEquals(0, p.capacityComponents());
- assertEquals(0, p.length());
- p = new CategoryPath(5,18);
- assertEquals(5, p.capacityChars());
- assertEquals(18, p.capacityComponents());
- assertEquals(0, p.length());
- p = new CategoryPath(27,13);
- assertEquals(27, p.capacityChars());
- assertEquals(13, p.capacityComponents());
- assertEquals(0, p.length());
- }
-
- @Test
- public void testClear() {
- CategoryPath p = new CategoryPath(0,0);
- p.add("hi");
- p.add("there");
- assertEquals(2, p.length());
- p.clear();
- assertEquals(0, p.length());
- p.add("yo!");
- assertEquals(1, p.length());
- }
-
- @Test
- public void testTrim() {
- CategoryPath p = new CategoryPath(0,0);
- p.add("this");
- p.add("message");
- p.add("will");
- p.add("self");
- p.add("destruct");
- p.add("in");
- p.add("five");
- p.add("seconds");
- assertEquals(8, p.length());
- p.trim(3);
- assertEquals(5, p.length());
- p.trim(0); // no-op
- assertEquals(5, p.length());
- p.trim(-3); // no-op
- assertEquals(5, p.length());
- p.trim(1);
- assertEquals(4, p.length());
- p.trim(8); // clear
- assertEquals(0, p.length());
- p.add("yo!");
- assertEquals(1, p.length());
- p.trim(1); // clear
- assertEquals(0, p.length());
- }
-
- @Test
- public void testComponentsLimit() {
- // Test that we can add up to 2^15-1 components
- CategoryPath p = new CategoryPath(0,0);
- for (int i=0; i<32767; i++) {
- p.add("");
- assertEquals(i+1, p.length());
- }
- // Also see that in the current implementation, this is actually
- // the limit: if we add one more component, things break (because
- // we used a short to hold ncomponents). See that it breaks in the
- // way we expect it to:
- p.add(""); // this still works, but...
- assertEquals(-32768, p.length()); // now the length is wrong and negative
- }
-
- @Test
- public void testCharsLimit() {
- // Test that we can add up to 2^15-1 characters
- CategoryPath p = new CategoryPath(0,0);
- for (int i=0; i<8192; i++) {
- p.add("aaaa");
- }
- // Also see that in the current implementation, this is actually the
- // limit: If we add one more character, things break (because ends[]
- // is an array of shorts), and we actually get an exception.
- try {
- p.add("a");
- fail("Should have thrown an exception");
- } catch (ArrayIndexOutOfBoundsException e) {
- // good.
- }
- }
-
- @Test
- public void testToString() {
- CategoryPath p = new CategoryPath(0,0);
- // When the category is empty, we expect an empty string
- assertEquals("", p.toString('/'));
- // This is (deliberately, in our implementation) indistinguishable
- // from the case of a single empty component:
- p.add("");
- assertEquals("", p.toString('/'));
- // Check just one category (so no delimiter needed):
- p.clear();
- p.add("hello");
- assertEquals("hello", p.toString('/'));
- // Now for two categories:
- p.clear();
- p.add("hello");
- p.add("world");
- assertEquals("hello/world", p.toString('/'));
- // And for a thousand...
- p.clear();
- p.add("0");
- StringBuilder expected = new StringBuilder("0");
- for (int i=1; i<1000; i++) {
- String num = Integer.toString(i);
- p.add(num);
- expected.append('/');
- expected.append(num);
- }
- assertEquals(expected.toString(), p.toString('/'));
- // Check that toString() without a parameter just defaults to '/':
- assertEquals(expected.toString(), p.toString());
- }
-
- // testing toString() and its variants already test most of the appendTo()
- // code, but not all of it (the "eclemma" code-coverage tool discovered
- // this for us). Here we complete the coverage of the appendTo() methods:
- @Test
- public void testAppendTo() throws IOException {
- CategoryPath p = new CategoryPath(0,0);
- StringBuilder sb = new StringBuilder();
- p.appendTo(sb, '/');
- assertEquals(0, sb.length());
- p.appendTo(sb, '/', -1);
- assertEquals(0, sb.length());
- p.appendTo(sb, '/', 1);
- assertEquals(0, sb.length());
- p.appendTo(sb, '/', -1, 1);
- assertEquals(0, sb.length());
- }
-
- @Test
- public void testLastComponent() {
- CategoryPath p = new CategoryPath(1000,1000);
- // When the category is empty, we expect a null
- assertNull(p.lastComponent());
- for (int i=0; i<=100; i++) {
- String num = Integer.toString(i);
- p.add(num);
- assertEquals(num, p.lastComponent());
- }
- }
-
- @Test
- public void testGetComponent() {
- CategoryPath p = new CategoryPath(1000,1000);
- // When the category is empty, we expect a null
- assertNull(p.getComponent(0));
- assertNull(p.getComponent(1));
- assertNull(p.getComponent(-1));
- for (int i=0; i<=100; i++) {
- p.add(Integer.toString(i));
- for (int j=0; j<=i; j++) {
- assertEquals(j, Integer.parseInt(p.getComponent(j)));
- }
- assertNull(p.getComponent(-1));
- assertNull(p.getComponent(i+1));
- }
- }
-
- @Test
- public void testToStringPrefix() {
- CategoryPath p = new CategoryPath(0,0);
- p.add("hi");
- p.add("there");
- p.add("man");
- assertEquals("hi/there/man", p.toString('/'));
- assertEquals("", p.toString('/', 0));
- assertEquals("hi", p.toString('/', 1));
- assertEquals("hi/there", p.toString('/', 2));
- assertEquals("hi/there/man", p.toString('/', 3));
- assertEquals("hi/there/man", p.toString('/', 4));
- assertEquals("hi/there/man", p.toString('/', -1));
- }
-
- @Test
- public void testToStringSubpath() {
- CategoryPath p = new CategoryPath(0,0);
- assertEquals("", p.toString('/', 0, 0));
- p.add("hi");
- p.add("there");
- p.add("man");
- assertEquals("", p.toString('/', 0, 0));
- assertEquals("hi", p.toString('/', 0, 1));
- assertEquals("hi/there", p.toString('/', 0, 2));
- assertEquals("hi/there/man", p.toString('/', 0, 3));
- assertEquals("hi/there/man", p.toString('/', 0, 4));
- assertEquals("hi/there/man", p.toString('/', 0, -1));
- assertEquals("hi/there/man", p.toString('/', -1, -1));
- assertEquals("there/man", p.toString('/', 1, -1));
- assertEquals("man", p.toString('/', 2, -1));
- assertEquals("", p.toString('/', 3, -1));
- assertEquals("there/man", p.toString('/', 1, 3));
- assertEquals("there", p.toString('/', 1, 2));
- assertEquals("", p.toString('/', 1, 1));
- }
-
- @Test
- public void testDelimiterConstructor() {
- // Test that the constructor that takes a string and a delimiter
- // works correctly. Also check that it allocates exactly the needed
- // needed size for the array - not more.
- CategoryPath p = new CategoryPath("", '/');
- assertEquals(p.length(), 0);
- assertEquals(p.capacityChars(), 0);
- assertEquals(p.capacityComponents(), 0);
- p = new CategoryPath("hello", '/');
- assertEquals(p.length(), 1);
- assertEquals(p.capacityChars(), 5);
- assertEquals(p.capacityComponents(), 1);
- assertEquals(p.toString('@'), "hello");
- p = new CategoryPath("hi/there", '/');
- assertEquals(p.length(), 2);
- assertEquals(p.capacityChars(), 7);
- assertEquals(p.capacityComponents(), 2);
- assertEquals(p.toString('@'), "hi@there");
- p = new CategoryPath("how/are/you/doing?", '/');
- assertEquals(p.length(), 4);
- assertEquals(p.capacityChars(), 15);
- assertEquals(p.capacityComponents(), 4);
- assertEquals(p.toString('@'), "how@are@you@doing?");
- }
-
- @Test
- public void testDefaultConstructor() {
- // test that the default constructor (no parameters) currently
- // defaults to creating an object with a 0 initial capacity.
- // If we change this default later, we also need to change this
- // test.
- CategoryPath p = new CategoryPath();
- assertEquals(0, p.capacityChars());
- assertEquals(0, p.capacityComponents());
- assertEquals(0, p.length());
- assertEquals("", p.toString('/'));
- }
-
- @Test
- public void testAddEmpty() {
- // In the current implementation, p.add("") should add en empty
- // component (which is, admitingly, not a useful case. On the other
- // hand, p.add("", delimiter) should add no components at all.
- // Verify this:
- CategoryPath p = new CategoryPath(0, 0);
- p.add("");
- assertEquals(1, p.length());
- p.add("");
- assertEquals(2, p.length());
- p.add("", '/');
- assertEquals(2, p.length());
- p.clear();
- p.add("", '/');
- assertEquals(0, p.length());
- }
-
- @Test
- public void testDelimiterAdd() {
- // Test that the add() that takes a string and a delimiter
- // works correctly. Note that unlike the constructor test above,
- // we can't expect the capacity to grow to exactly the length of
- // the given category, so we do not test this.
- CategoryPath p = new CategoryPath(0, 0);
- p.add("", '/');
- assertEquals(0, p.length());
- assertEquals("", p.toString('@'), "");
- p.clear();
- p.add("hello", '/');
- assertEquals(p.length(), 1);
- assertEquals(p.toString('@'), "hello");
- p.clear();
- p.add("hi/there", '/');
- assertEquals(p.length(), 2);
- assertEquals(p.toString('@'), "hi@there");
- p.clear();
- p.add("how/are/you/doing?", '/');
- assertEquals(p.length(), 4);
- assertEquals(p.toString('@'), "how@are@you@doing?");
- // See that this is really an add, not replace:
- p.clear();
- p.add("hi/there", '/');
- assertEquals(p.length(), 2);
- assertEquals(p.toString('@'), "hi@there");
- p.add("how/are/you/doing", '/');
- assertEquals(p.length(), 6);
- assertEquals(p.toString('@'), "hi@there@how@are@you@doing");
- }
-
- @Test
- public void testCopyConstructor() {
- CategoryPath p = new CategoryPath(0,0);
- int expectedchars=0;
- for (int i=0; i<1000; i++) {
- CategoryPath clone = new CategoryPath(p);
- assertEquals(p.length(), clone.length());
- assertEquals(p.toString('/'), clone.toString('/'));
- // verify that the newly created clone has exactly the right
- // capacity, with no spare (while the original path p probably
- // does have spare)
- assertEquals(i, clone.capacityComponents());
- assertEquals(expectedchars, clone.capacityChars());
- // Finally, add another component to the path, for the next
- // round of this loop
- String num = Integer.toString(i);
- p.add(num);
- expectedchars+=num.length();
- }
- }
-
- @Test
- public void testPrefixCopyConstructor() {
- CategoryPath p = new CategoryPath(0,0);
- p.add("hi");
- p.add("there");
- p.add("man");
- assertEquals(p.length(), 3);
-
- CategoryPath p1 = new CategoryPath(p,2);
- assertEquals(2, p1.length());
- assertEquals("hi/there", p1.toString('/'));
- // the new prefix object should only take the space it needs:
- assertEquals(2, p1.capacityComponents());
- assertEquals(7, p1.capacityChars());
-
- p1 = new CategoryPath(p,1);
- assertEquals(1, p1.length());
- assertEquals("hi", p1.toString('/'));
- assertEquals(1, p1.capacityComponents());
- assertEquals(2, p1.capacityChars());
-
- p1 = new CategoryPath(p,0);
- assertEquals(0, p1.length());
- assertEquals("", p1.toString('/'));
- assertEquals(0, p1.capacityComponents());
- assertEquals(0, p1.capacityChars());
-
- // with all the following lengths, the prefix should be the whole path:
- int[] lengths = { 3, -1, 4 };
- for (int i=0; i<lengths.length; i++) {
- p1 = new CategoryPath(p, lengths[i]);
- assertEquals(3, p1.length());
- assertEquals("hi/there/man", p1.toString('/'));
- assertEquals(p, p1);
- assertEquals(3, p1.capacityComponents());
- assertEquals(10, p1.capacityChars());
- }
- }
-
- @Test
- public void testEquals() {
- // check that two empty paths are equal, even if they have different
- // capacities:
- CategoryPath p1 = new CategoryPath(0,0);
- CategoryPath p2 = new CategoryPath(1000,300);
- assertEquals(true, p1.equals(p2));
- // If we make p2 different, it is no longer equals:
- p2.add("hi");
- assertEquals(false, p1.equals(p2));
- // A categoryPath is definitely not equals to an object of some other
- // type:
- assertEquals(false, p1.equals(Integer.valueOf(3)));
- // Build two paths separately, and compare them
- p1.clear();
- p1.add("hello");
- p1.add("world");
- p2.clear();
- p2.add("hello");
- p2.add("world");
- assertEquals(true, p1.equals(p2));
- // Check that comparison really don't look at old data which might
- // be stored in the array
- p1.clear();
- p1.add("averylongcategoryname");
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hi");
- assertEquals(true, p1.equals(p2));
- // Being of the same length is obviously not enough to be equal
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hello");
- assertEquals(false, p1.equals(p2));
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("ho");
- assertEquals(false, p1.equals(p2));
- }
- @Test
- public void testHashCode() {
- // Note: in this test, we assume that if two paths are not equal,
- // their hash codes should come out differently. This is *not*
- // always the case, but in the examples we use below, it comes out
- // fine, and unless we have some really bad luck in changing our
- // hash function, this should also remain true in the future.
-
- // check that two empty paths are equal, even if they have different
- // capacities:
- CategoryPath p1 = new CategoryPath(0,0);
- CategoryPath p2 = new CategoryPath(1000,300);
- assertEquals(p1.hashCode(), p2.hashCode());
- // If we make p2 different, it is no longer equals:
- p2.add("hi");
- assertEquals(false, p1.hashCode()==p2.hashCode());
- // Build two paths separately, and compare them
- p1.clear();
- p1.add("hello");
- p1.add("world");
- p2.clear();
- p2.add("hello");
- p2.add("world");
- assertEquals(p1.hashCode(), p2.hashCode());
- // Check that comparison really don't look at old data which might
- // be stored in the array
- p1.clear();
- p1.add("averylongcategoryname");
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hi");
- assertEquals(p1.hashCode(), p2.hashCode());
- // Being of the same length is obviously not enough to be equal
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hello");
- assertEquals(false, p1.hashCode()==p2.hashCode());
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("ho");
- assertEquals(false, p1.hashCode()==p2.hashCode());
- }
-
- @Test
- public void testHashCodePrefix() {
- // First, repeat the tests of testHashCode() using hashCode(-1)
- // just to make sure nothing was broken in this variant:
- CategoryPath p1 = new CategoryPath(0,0);
- CategoryPath p2 = new CategoryPath(1000,300);
- assertEquals(p1.hashCode(-1), p2.hashCode(-1));
- p2.add("hi");
- assertEquals(false, p1.hashCode(-1)==p2.hashCode(-1));
- p1.clear();
- p1.add("hello");
- p1.add("world");
- p2.clear();
- p2.add("hello");
- p2.add("world");
- assertEquals(p1.hashCode(-1), p2.hashCode(-1));
- p1.clear();
- p1.add("averylongcategoryname");
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hi");
- assertEquals(p1.hashCode(-1), p2.hashCode(-1));
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hello");
- assertEquals(false, p1.hashCode(-1)==p2.hashCode(-1));
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("ho");
- assertEquals(false, p1.hashCode(-1)==p2.hashCode(-1));
-
- // Now move to testing prefixes:
- CategoryPath p = new CategoryPath();
- p.add("this");
- p.add("is");
- p.add("a");
- p.add("test");
- assertEquals(p.hashCode(), p.hashCode(4));
- assertEquals(new CategoryPath().hashCode(), p.hashCode(0));
- assertEquals(new CategoryPath(p, 1).hashCode(), p.hashCode(1));
- assertEquals(new CategoryPath(p, 2).hashCode(), p.hashCode(2));
- assertEquals(new CategoryPath(p, 3).hashCode(), p.hashCode(3));
- }
-
- @Test
- public void testLongHashCode() {
- // Note: in this test, we assume that if two paths are not equal,
- // their hash codes should come out differently. This is *not*
- // always the case, but in the examples we use below, it comes out
- // fine, and unless we have some really bad luck in changing our
- // hash function, this should also remain true in the future.
-
- // check that two empty paths are equal, even if they have different
- // capacities:
- CategoryPath p1 = new CategoryPath(0,0);
- CategoryPath p2 = new CategoryPath(1000,300);
- assertEquals(p1.longHashCode(), p2.longHashCode());
- // If we make p2 different, it is no longer equals:
- p2.add("hi");
- assertEquals(false, p1.longHashCode()==p2.longHashCode());
- // Build two paths separately, and compare them
- p1.clear();
- p1.add("hello");
- p1.add("world");
- p2.clear();
- p2.add("hello");
- p2.add("world");
- assertEquals(p1.longHashCode(), p2.longHashCode());
- // Check that comparison really don't look at old data which might
- // be stored in the array
- p1.clear();
- p1.add("averylongcategoryname");
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hi");
- assertEquals(p1.longHashCode(), p2.longHashCode());
- // Being of the same length is obviously not enough to be equal
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hello");
- assertEquals(false, p1.longHashCode()==p2.longHashCode());
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("ho");
- assertEquals(false, p1.longHashCode()==p2.longHashCode());
- }
-
- @Test
- public void testLongHashCodePrefix() {
- // First, repeat the tests of testLongHashCode() using longHashCode(-1)
- // just to make sure nothing was broken in this variant:
-
- // check that two empty paths are equal, even if they have different
- // capacities:
- CategoryPath p1 = new CategoryPath(0,0);
- CategoryPath p2 = new CategoryPath(1000,300);
- assertEquals(p1.longHashCode(-1), p2.longHashCode(-1));
- // If we make p2 different, it is no longer equals:
- p2.add("hi");
- assertEquals(false, p1.longHashCode(-1)==p2.longHashCode(-1));
- // Build two paths separately, and compare them
- p1.clear();
- p1.add("hello");
- p1.add("world");
- p2.clear();
- p2.add("hello");
- p2.add("world");
- assertEquals(p1.longHashCode(-1), p2.longHashCode(-1));
- // Check that comparison really don't look at old data which might
- // be stored in the array
- p1.clear();
- p1.add("averylongcategoryname");
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hi");
- assertEquals(p1.longHashCode(-1), p2.longHashCode(-1));
- // Being of the same length is obviously not enough to be equal
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("hello");
- assertEquals(false, p1.longHashCode(-1)==p2.longHashCode(-1));
- p1.clear();
- p1.add("hi");
- p2.clear();
- p2.add("ho");
- assertEquals(false, p1.longHashCode(-1)==p2.longHashCode(-1));
-
- // Now move to testing prefixes:
- CategoryPath p = new CategoryPath();
- p.add("this");
- p.add("is");
- p.add("a");
- p.add("test");
- assertEquals(p.longHashCode(), p.longHashCode(4));
- assertEquals(new CategoryPath().longHashCode(), p.longHashCode(0));
- assertEquals(new CategoryPath(p, 1).longHashCode(), p.longHashCode(1));
- assertEquals(new CategoryPath(p, 2).longHashCode(), p.longHashCode(2));
- assertEquals(new CategoryPath(p, 3).longHashCode(), p.longHashCode(3));
- }
-
- @Test
- public void testArrayConstructor() {
- CategoryPath p = new CategoryPath("hello", "world", "yo");
- assertEquals(3, p.length());
- assertEquals(12, p.capacityChars());
- assertEquals(3, p.capacityComponents());
- assertEquals("hello/world/yo", p.toString('/'));
-
- p = new CategoryPath(new String[0]);
- assertEquals(0, p.length());
- assertEquals(0, p.capacityChars());
- assertEquals(0, p.capacityComponents());
- }
-
- @Test
- public void testCharsNeededForFullPath() {
- String[] components = { "hello", "world", "yo" };
- CategoryPath p = new CategoryPath();
- assertEquals(0, p.charsNeededForFullPath());
- int expectedCharsNeeded = 0;
- for (int i=0; i<components.length; i++) {
- p.add(components[i]);
- expectedCharsNeeded += components[i].length();
- if (i>0) {
- expectedCharsNeeded++;
- }
- assertEquals(expectedCharsNeeded, p.charsNeededForFullPath());
- }
- }
-
- @Test
- public void testCopyToCharArray() {
- String[] components = { "hello", "world", "yo" };
- CategoryPath p = new CategoryPath(components);
- char[] charArray = new char[p.charsNeededForFullPath()];
- int numCharsCopied = 0;
-
- numCharsCopied = p.copyToCharArray(charArray, 0, 0, '.');
- assertEquals(0, numCharsCopied);
- assertEquals("", new String(charArray, 0, numCharsCopied));
-
- numCharsCopied = p.copyToCharArray(charArray, 0, 1, '.');
- assertEquals(5, numCharsCopied);
- assertEquals("hello", new String(charArray, 0, numCharsCopied));
-
- numCharsCopied = p.copyToCharArray(charArray, 0, 3, '.');
- assertEquals(14, numCharsCopied);
- assertEquals("hello.world.yo", new String(charArray, 0, numCharsCopied));
-
- numCharsCopied = p.copyToCharArray(charArray, 0, -1, '.');
- assertEquals(14, numCharsCopied);
- assertEquals("hello.world.yo", new String(charArray, 0, numCharsCopied));
- numCharsCopied = p.copyToCharArray(charArray, 0, 4, '.');
- assertEquals(14, numCharsCopied);
- assertEquals("hello.world.yo", new String(charArray, 0, numCharsCopied));
- }
-
- @Test
- public void testCharSerialization() throws Exception {
- CategoryPath[] testCategories = {
- new CategoryPath("hi", "there", "man"),
- new CategoryPath("hello"),
- new CategoryPath("what's", "up"),
- // See that an empty category, which generates a (char)0,
- // doesn't cause any problems in the middle of the serialization:
- new CategoryPath(),
- new CategoryPath("another", "example"),
- new CategoryPath(),
- new CategoryPath()
- };
- StringBuilder sb = new StringBuilder();
- for (int i=0; i<testCategories.length; i++) {
- testCategories[i].serializeAppendTo(sb);
- }
-
- CategoryPath tmp = new CategoryPath();
- int offset=0;
- for (int i=0; i<testCategories.length; i++) {
- // check equalsToSerialized, in a equal and non-equal case:
- assertTrue(testCategories[i].equalsToSerialized(sb, offset));
- assertFalse(new CategoryPath("Hello", "world").equalsToSerialized(sb, offset));
- assertFalse(new CategoryPath("world").equalsToSerialized(sb, offset));
- // and check hashCodeFromSerialized:
- assertEquals(testCategories[i].hashCode(), CategoryPath.hashCodeOfSerialized(sb, offset));
- // and check setFromSerialized:
- offset = tmp.setFromSerialized(sb, offset);
- assertEquals(testCategories[i], tmp);
- }
- assertEquals(offset, sb.length());
- // A similar test, for a much longer path (though not larger than the
- // 2^15-1 character limit that CategoryPath allows:
- sb = new StringBuilder();
- CategoryPath p = new CategoryPath();
- for (int i=0; i<1000; i++) {
- p.add(Integer.toString(i));
- }
- p.serializeAppendTo(sb);
- p.serializeAppendTo(sb);
- p.serializeAppendTo(sb);
- offset=0;
- assertTrue(p.equalsToSerialized(sb, offset));
- assertEquals(p.hashCode(), CategoryPath.hashCodeOfSerialized(sb, offset));
- offset = tmp.setFromSerialized(sb, offset);
- assertEquals(p, tmp);
- assertTrue(p.equalsToSerialized(sb, offset));
- assertEquals(p.hashCode(), CategoryPath.hashCodeOfSerialized(sb, offset));
- offset = tmp.setFromSerialized(sb, offset);
- assertEquals(p, tmp);
- assertTrue(p.equalsToSerialized(sb, offset));
- assertEquals(p.hashCode(), CategoryPath.hashCodeOfSerialized(sb, offset));
- offset = tmp.setFromSerialized(sb, offset);
- assertEquals(p, tmp);
- assertEquals(offset, sb.length());
-
- // Test the serializeAppendTo variant with a prefixLen
- p = new CategoryPath();
- for (int i=0; i<783; i++) {
- p.add(Integer.toString(i));
- }
- int[] prefixLengths = { 0, 574, 782, 783, 784, -1 };
- for (int prefixLen : prefixLengths) {
- sb = new StringBuilder();
- p.serializeAppendTo(prefixLen, sb);
- assertTrue(new CategoryPath(p, prefixLen).equalsToSerialized(sb, 0));
- }
-
- // Test the equalsToSerialized variant with a prefixLen
- // We use p and prefixLengths set above.
- for (int prefixLen : prefixLengths) {
- sb = new StringBuilder();
- new CategoryPath(p, prefixLen).serializeAppendTo(sb);
- assertTrue(p.equalsToSerialized(prefixLen, sb, 0));
- }
-
- // Check also the false case of equalsToSerialized with prefixLen:
- sb = new StringBuilder();
- new CategoryPath().serializeAppendTo(sb);
- assertTrue(new CategoryPath().equalsToSerialized(0, sb, 0));
- assertTrue(new CategoryPath("a", "b").equalsToSerialized(0, sb, 0));
- assertFalse(new CategoryPath("a", "b").equalsToSerialized(1, sb, 0));
- sb = new StringBuilder();
- new CategoryPath("a", "b").serializeAppendTo(sb);
- assertFalse(new CategoryPath().equalsToSerialized(0, sb, 0));
- assertFalse(new CategoryPath("a").equalsToSerialized(0, sb, 0));
- assertFalse(new CategoryPath("a").equalsToSerialized(1, sb, 0));
- assertFalse(new CategoryPath("a", "b").equalsToSerialized(0, sb, 0));
- assertFalse(new CategoryPath("a", "b").equalsToSerialized(1, sb, 0));
- assertTrue(new CategoryPath("a", "b").equalsToSerialized(2, sb, 0));
- assertTrue(new CategoryPath("a", "b", "c").equalsToSerialized(2, sb, 0));
- assertFalse(new CategoryPath("z", "b", "c").equalsToSerialized(2, sb, 0));
- assertFalse(new CategoryPath("aa", "b", "c").equalsToSerialized(2, sb, 0));
- }
-
- @Test
- public void testStreamWriterSerialization() throws Exception {
- CategoryPath[] testPaths = {
- new CategoryPath("hi", "there", "man"),
- new CategoryPath("hello"),
- new CategoryPath("date", "2009", "May", "13", "14", "59", "00"),
- // See that an empty category, which generates a (char)0,
- // doesn't cause any problems in the middle of the serialization:
- new CategoryPath(),
- new CategoryPath("another", "example")
- };
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- OutputStreamWriter osw = new OutputStreamWriter(baos, "UTF-8"); // UTF-8 is always supported.
- for (CategoryPath cp : testPaths) {
- cp.serializeToStreamWriter(osw);
- }
- osw.flush();
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- InputStreamReader isr = new InputStreamReader(bais, "UTF-8");
- CategoryPath[] checkPaths = {
- new CategoryPath(), new CategoryPath(), new CategoryPath(), new CategoryPath(), new CategoryPath()
- };
- for (int j = 0; j < checkPaths.length; j++) {
- checkPaths[j].deserializeFromStreamReader(isr);
- assertEquals("Paths not equal", testPaths[j], checkPaths[j]);
- }
- }
-
- @Test
- public void testCharSequenceCtor() throws Exception {
- CategoryPath[] testPaths = {
- new CategoryPath(new CS("hi"), new CS("there"), new CS("man")),
- new CategoryPath(new CS("hello")),
- new CategoryPath(new CS("date"), new CS("2009"), new CS("May"), new CS("13"),
- new CS("14"), new CS("59"), new CS("00")),
- new CategoryPath(),
- new CategoryPath(new CS("another"), new CS("example"))
- };
- assertEquals("Wrong capacity", 10, testPaths[0].capacityChars());
- assertEquals("Wrong capacity", 5, testPaths[1].capacityChars());
- assertEquals("Wrong capacity", 19, testPaths[2].capacityChars());
- assertEquals("Wrong capacity", 0, testPaths[3].capacityChars());
- assertEquals("Wrong capacity", 14, testPaths[4].capacityChars());
-
- assertEquals("Wrong component", "hi", testPaths[0].getComponent(0));
- assertEquals("Wrong component", "there", testPaths[0].getComponent(1));
- assertEquals("Wrong component", "man", testPaths[0].getComponent(2));
- assertEquals("Wrong component", "hello", testPaths[1].getComponent(0));
- assertEquals("Wrong component", "date", testPaths[2].getComponent(0));
- assertEquals("Wrong component", "2009", testPaths[2].getComponent(1));
- assertEquals("Wrong component", "May", testPaths[2].getComponent(2));
- assertEquals("Wrong component", "13", testPaths[2].getComponent(3));
- assertEquals("Wrong component", "14", testPaths[2].getComponent(4));
- assertEquals("Wrong component", "59", testPaths[2].getComponent(5));
- assertEquals("Wrong component", "00", testPaths[2].getComponent(6));
- assertNull("Not null component", testPaths[3].getComponent(0));
- assertEquals("Wrong component", "another", testPaths[4].getComponent(0));
- assertEquals("Wrong component", "example", testPaths[4].getComponent(1));
- }
-
- @Test
- public void testIsDescendantOf() throws Exception {
- CategoryPath[] testPaths = {
- new CategoryPath(new CS("hi"), new CS("there")),
- new CategoryPath(new CS("hi"), new CS("there"), new CS("man")),
- new CategoryPath(new CS("hithere"), new CS("man")),
- new CategoryPath(new CS("hi"), new CS("there"), new CS("mano")),
- new CategoryPath(),
- };
- assertTrue(testPaths[0].isDescendantOf(testPaths[0]));
- assertTrue(testPaths[0].isDescendantOf(testPaths[4]));
- assertFalse(testPaths[4].isDescendantOf(testPaths[0]));
- assertTrue(testPaths[1].isDescendantOf(testPaths[0]));
- assertTrue(testPaths[1].isDescendantOf(testPaths[1]));
- assertTrue(testPaths[3].isDescendantOf(testPaths[0]));
- assertFalse(testPaths[2].isDescendantOf(testPaths[0]));
- assertFalse(testPaths[2].isDescendantOf(testPaths[1]));
- assertFalse(testPaths[3].isDescendantOf(testPaths[1]));
- }
-
- @Test
- public void testCompareTo() {
- CategoryPath p = new CategoryPath("a/b/c/d", '/');
- CategoryPath pother = new CategoryPath("a/b/c/d", '/');
- assertTrue(pother.compareTo(p) == 0);
- pother = new CategoryPath("", '/');
- assertTrue(pother.compareTo(p) < 0);
- pother = new CategoryPath("a/b_/c/d", '/');
- assertTrue(pother.compareTo(p) > 0);
- pother = new CategoryPath("a/b/c", '/');
- assertTrue(pother.compareTo(p) < 0);
- pother = new CategoryPath("a/b/c/e", '/');
- assertTrue(pother.compareTo(p) > 0);
- pother = new CategoryPath("a/b/c//e", '/');
- assertTrue(pother.compareTo(p) < 0);
- }
-
- private static class CS implements CharSequence {
- public CS(String s) {
- this.ca = new char[s.length()];
- s.getChars(0, s.length(), this.ca, 0);
- }
- public char charAt(int index) {
- return this.ca[index];
- }
- public int length() {
- return this.ca.length;
- }
- public CharSequence subSequence(int start, int end) {
- return null; // not used.
- }
- private char[] ca;
- }
-
-}