More tests for Chars

This commit is contained in:
Clément Fournier 2020-11-15 23:44:27 +01:00
parent 3ca59ce12d
commit 91fb58355b
3 changed files with 98 additions and 18 deletions

View File

@ -10,12 +10,11 @@ import java.io.Writer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.regex.Pattern;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.internal.util.IteratorUtil.AbstractIterator;
/**
* View on a string which doesn't copy the array for subsequence operations.
* This view is immutable. Since it uses a string internally it benefits from
@ -72,7 +71,7 @@ public final class Chars implements CharSequence {
* @throws NullPointerException If the writer is null
*/
public void writeFully(@NonNull Writer writer) throws IOException {
writer.write(str, start, length());
write(writer, 0, length());
}
/**
@ -102,9 +101,7 @@ public final class Chars implements CharSequence {
* @throws IndexOutOfBoundsException See {@link String#getChars(int, int, char[], int)}
*/
public void getChars(int srcBegin, char @NonNull [] cbuf, int dstBegin, int count) {
if (count == 0) {
return;
}
validateRange(srcBegin, count, length());
int start = idx(srcBegin);
str.getChars(start, start + count, cbuf, dstBegin);
}
@ -414,30 +411,34 @@ public final class Chars implements CharSequence {
/**
* Returns an iterable over the lines of this char sequence. The lines
* are yielded without line separators.
* are yielded without line separators. For the purposes of this method,
* a line delimiter is {@code LF} or {@code CR+LF}.
*/
public Iterable<Chars> lines() {
return () -> new AbstractIterator<Chars>() {
return () -> new Iterator<Chars>() {
final int max = len;
int pos = 0;
@Override
protected void computeNext() {
if (pos >= max) {
done();
return;
}
public boolean hasNext() {
return pos < max;
}
@Override
public Chars next() {
int nl = indexOf('\n', pos);
Chars next;
if (nl < 0) {
setNext(subSequence(pos, max));
next = subSequence(pos, max);
pos = max;
return;
return next;
} else if (startsWith('\r', nl - 1)) {
setNext(subSequence(pos, nl - 1));
next = subSequence(pos, nl - 1);
} else {
setNext(subSequence(pos, nl));
next = subSequence(pos, nl);
}
pos = nl + 1;
return next;
}
};
}

View File

@ -6,6 +6,8 @@ package net.sourceforge.pmd.util.document;
import static net.sourceforge.pmd.util.CollectionUtil.listOf;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import org.junit.Assert;
@ -40,6 +42,44 @@ public class CharsTest {
Assert.assertEquals("bc", sb.toString());
}
@Test
public void appendCharsWithOffsets() {
StringBuilder sb = new StringBuilder();
Chars bc = Chars.wrap("abcd").slice(1, 2);
Assert.assertEquals("bc", bc.toString());
bc.appendChars(sb, 0, 1);
Assert.assertEquals("b", sb.toString());
}
@Test
public void write() throws IOException {
StringWriter writer = new StringWriter();
Chars bc = Chars.wrap("abcd").slice(1, 2);
Assert.assertEquals("bc", bc.toString());
bc.write(writer, 0, 1);
Assert.assertEquals("b", writer.toString());
writer = new StringWriter();
bc.writeFully(writer);
Assert.assertEquals("bc", writer.toString());
}
@Test
public void getChars() {
char[] arr = new char[4];
Chars bc = Chars.wrap("abcd").slice(1, 2);
bc.getChars(0, arr, 1, 2);
Assert.assertArrayEquals(arr, new char[] {0, 'b', 'c', 0});
Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(2, arr, 0, 1));
Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(-1, arr, 0, 1));
Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(0, arr, 0, 3));
Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(0, arr, 4, 3));
Assert.assertThrows(NullPointerException.class, () -> bc.getChars(0, null, 0, 0));
}
@Test
public void indexOf() {
Chars bc = Chars.wrap("aaaaabcdb").slice(5, 2);
@ -86,14 +126,20 @@ public class CharsTest {
Assert.assertTrue(bc.startsWith("bc"));
Assert.assertTrue(bc.startsWith("bc", 0));
Assert.assertTrue(bc.startsWith("c", 1));
Assert.assertTrue(bc.startsWith('c', 1)); //with a char
Assert.assertTrue(bc.startsWith("", 1));
Assert.assertTrue(bc.startsWith("", 0));
Assert.assertFalse(bc.startsWith("c", 0));
Assert.assertFalse(bc.startsWith('c', 0)); //with a char
Assert.assertFalse(bc.startsWith("bcd", 0));
Assert.assertFalse(bc.startsWith("xcd", 0));
Assert.assertFalse(bc.startsWith("b", -1));
Assert.assertFalse(bc.startsWith('b', -1)); //with a char
Assert.assertFalse(bc.startsWith("", -1));
Assert.assertFalse(bc.startsWith("", 5));
@ -140,4 +186,37 @@ public class CharsTest {
Assert.assertEquals(listOf(" ", " ", "bc "), lines);
}
@Test
public void testEqualsHashCode() {
Chars chars = Chars.wrap("a_a_b_c_s").slice(2, 5);
// -----
Assert.assertEquals(Chars.wrap("a_b_c"), chars);
Assert.assertNotEquals("a_b_c", chars);
Assert.assertEquals(Chars.wrap("a_b_c").hashCode(), chars.hashCode());
Assert.assertEquals(chars, chars);
Assert.assertEquals("a_b_c".hashCode(), Chars.wrap("a_b_c").hashCode());
Assert.assertEquals("a_b_c".hashCode(), chars.hashCode());
}
@Test
public void testContentEquals() {
Chars chars = Chars.wrap("a_a_b_c_s").slice(2, 5);
// -----
Assert.assertTrue(chars.contentEquals("a_b_c"));
Assert.assertTrue(chars.contentEquals(Chars.wrap("a_b_c")));
Assert.assertFalse(chars.contentEquals("a_b_c_--"));
Assert.assertFalse(chars.contentEquals(Chars.wrap("a_b_c_")));
Assert.assertFalse(chars.contentEquals(Chars.wrap("a_b-c")));
Assert.assertTrue(chars.contentEquals(Chars.wrap("A_B_C"), true));
}
}

View File

@ -62,7 +62,7 @@ public class XmlParserImpl {
public RootXmlNode parse(ParserTask task) {
String xmlData = task.getSourceText();
Document document = parseDocument(xmlData);
RootXmlNode root = new RootXmlNode(this, document, task.getTextDocument());
RootXmlNode root = new RootXmlNode(this, document, task);
DOMLineNumbers lineNumbers = new DOMLineNumbers(root, task.getTextDocument());
lineNumbers.determine();
nodeCache.put(document, root);