More tests
This commit is contained in:
12 files changed
+102
-85
No files matched your search
@@ -69,7 +69,7 @@ class NioTextFile extends BaseCloseable implements TextFile {
|
||||
public void writeContents(TextFileContent content) throws IOException {
|
||||
ensureOpen();
|
||||
if (isReadOnly()) {
|
||||
throw new ReadOnlyFileException();
|
||||
throw new ReadOnlyFileException(this);
|
||||
}
|
||||
try (BufferedWriter bw = Files.newBufferedWriter(path, charset)) {
|
||||
if (content.getLineTerminator().equals(TextFileContent.NORMALIZED_LINE_TERM)) {
|
||||
|
||||
@@ -10,4 +10,8 @@ package net.sourceforge.pmd.lang.document;
|
||||
*/
|
||||
public class ReadOnlyFileException extends UnsupportedOperationException {
|
||||
|
||||
public ReadOnlyFileException(TextFile textFile) {
|
||||
super("Read only: " + textFile.getPathId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -109,7 +109,7 @@ public interface TextFile extends Closeable {
|
||||
* @throws ReadOnlyFileException If this text source is read-only
|
||||
*/
|
||||
default void writeContents(TextFileContent content) throws IOException {
|
||||
throw new ReadOnlyFileException();
|
||||
throw new ReadOnlyFileException(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,11 +30,16 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
*/
|
||||
public final class TextFileContent {
|
||||
|
||||
// the three line terminators we handle.
|
||||
private static final String CRLF = "\r\n";
|
||||
private static final String LF = "\n";
|
||||
private static final String CR = "\r";
|
||||
|
||||
/**
|
||||
* The normalized line ending used to replace platform-specific
|
||||
* line endings in the {@linkplain #getNormalizedText() normalized text}.
|
||||
*/
|
||||
public static final String NORMALIZED_LINE_TERM = "\n";
|
||||
public static final String NORMALIZED_LINE_TERM = LF;
|
||||
|
||||
/** The normalized line ending as a char. */
|
||||
public static final char NORMALIZED_LINE_TERM_CHAR = '\n';
|
||||
@@ -225,10 +230,10 @@ public final class TextFileContent {
|
||||
if (afterCr && c != NORMALIZED_LINE_TERM_CHAR) {
|
||||
// we saw a \r last iteration, but didn't copy it
|
||||
// it's not followed by an \n
|
||||
newLineTerm = "\r";
|
||||
newLineTerm = CR;
|
||||
newLineOffset = bufOffset + i + offsetDiff;
|
||||
if (i > 0) {
|
||||
cbuf[i - 1] = '\n'; // replace the \r with a \n
|
||||
cbuf[i - 1] = NORMALIZED_LINE_TERM_CHAR; // replace the \r with a \n
|
||||
} else {
|
||||
// The CR was trailing a buffer, so it's not in the current buffer and wasn't copied.
|
||||
// Append a newline.
|
||||
@@ -236,10 +241,10 @@ public final class TextFileContent {
|
||||
}
|
||||
} else {
|
||||
if (afterCr) {
|
||||
newLineTerm = "\r\n";
|
||||
newLineTerm = CRLF;
|
||||
|
||||
if (i > 0) {
|
||||
cbuf[i - 1] = '\n'; // replace the \r with a \n
|
||||
cbuf[i - 1] = NORMALIZED_LINE_TERM_CHAR; // replace the \r with a \n
|
||||
// copy up to and including the \r, which was replaced
|
||||
result.append(cbuf, nextCharToCopy, i - nextCharToCopy);
|
||||
nextCharToCopy = i + 1; // set the next char to copy to after the \n
|
||||
@@ -249,7 +254,7 @@ public final class TextFileContent {
|
||||
offsetDiff--;
|
||||
} else {
|
||||
// just \n
|
||||
newLineTerm = "\n";
|
||||
newLineTerm = LF;
|
||||
}
|
||||
newLineOffset = bufOffset + i + offsetDiff + 1;
|
||||
}
|
||||
@@ -275,7 +280,7 @@ public final class TextFileContent {
|
||||
if (afterCr) { // we're at EOF, so it's not followed by \n
|
||||
result.append(NORMALIZED_LINE_TERM);
|
||||
positionerBuilder.addLineEndAtOffset(bufOffset);
|
||||
detectedLineTerm = detectLineTerm(detectedLineTerm, "\r", fallbackLineSep);
|
||||
detectedLineTerm = detectLineTerm(detectedLineTerm, CR, fallbackLineSep);
|
||||
}
|
||||
|
||||
if (detectedLineTerm == null) {
|
||||
|
||||
@@ -18,7 +18,7 @@ public final class TextPos2d implements Comparable<TextPos2d> {
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
|
||||
assert line > 0 && column > 0 : "Invalid position" + parThis();
|
||||
assert line > 0 && column > 0 : "Invalid position " + toTupleString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,10 +44,6 @@ public final class TextPos2d implements Comparable<TextPos2d> {
|
||||
return new TextPos2d(line, column);
|
||||
}
|
||||
|
||||
private String parThis() {
|
||||
return "(" + this + ")";
|
||||
}
|
||||
|
||||
|
||||
/** Compares the start offset, then the length of a region. */
|
||||
@Override
|
||||
|
||||
@@ -4,12 +4,18 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.document;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A place in a text document, represented as line/column information.
|
||||
*/
|
||||
public final class TextRange2d implements Comparable<TextRange2d> {
|
||||
private static final Comparator<TextRange2d> COMPARATOR =
|
||||
Comparator.comparingInt(TextRange2d::getStartLine)
|
||||
.thenComparingInt(TextRange2d::getStartColumn)
|
||||
.thenComparingInt(TextRange2d::getEndLine)
|
||||
.thenComparingInt(TextRange2d::getEndColumn);
|
||||
|
||||
private final int startLine;
|
||||
private final int startCol;
|
||||
@@ -69,11 +75,7 @@ public final class TextRange2d implements Comparable<TextRange2d> {
|
||||
|
||||
@Override
|
||||
public int compareTo(TextRange2d o) {
|
||||
int cmp = getStartPos().compareTo(o.getStartPos());
|
||||
if (cmp != 0) {
|
||||
return cmp;
|
||||
}
|
||||
return getEndPos().compareTo(o.getEndPos());
|
||||
return COMPARATOR.compare(this, o);
|
||||
}
|
||||
|
||||
public boolean contains(TextRange2d range) {
|
||||
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.document.internal;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
|
||||
/**
|
||||
* Discovers the languages applicable to a file.
|
||||
*/
|
||||
public class LanguageDiscoverer {
|
||||
|
||||
|
||||
private final Language forcedLanguage;
|
||||
|
||||
/**
|
||||
* Build a new instance.
|
||||
*
|
||||
* @param forcedLanguage If non-null, all files will be assigned this language.
|
||||
*/
|
||||
public LanguageDiscoverer(Language forcedLanguage) {
|
||||
this.forcedLanguage = forcedLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Languages of a given source file.
|
||||
*
|
||||
* @param sourceFile The file.
|
||||
*
|
||||
* @return The Languages for the source file, may be empty.
|
||||
*/
|
||||
public List<Language> getLanguagesForFile(Path sourceFile) {
|
||||
return getLanguagesForFile(sourceFile.getFileName().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Languages of a given source file.
|
||||
*
|
||||
* @param fileName The file name.
|
||||
*
|
||||
* @return The Languages for the source file, may be empty.
|
||||
*/
|
||||
public List<Language> getLanguagesForFile(String fileName) {
|
||||
if (forcedLanguage != null) {
|
||||
return Collections.singletonList(forcedLanguage);
|
||||
}
|
||||
String extension = getExtension(fileName);
|
||||
return LanguageRegistry.findByExtension(extension);
|
||||
}
|
||||
|
||||
// Get the extensions from a file
|
||||
private String getExtension(String fileName) {
|
||||
return StringUtils.substringAfterLast(fileName, ".");
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,13 @@ public class FileLocationTest {
|
||||
assertEquals(2, loc.getEndColumn());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToRange() {
|
||||
TextRange2d range2d = TextRange2d.range2d(1, 1, 1, 2);
|
||||
FileLocation loc = FileLocation.range("fname", range2d);
|
||||
assertEquals(range2d, loc.toRange2d());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
FileLocation loc = FileLocation.range("fname", TextRange2d.range2d(1, 1, 1, 2));
|
||||
|
||||
@@ -63,6 +63,10 @@ public class SourceCodePositionerTest {
|
||||
assertEquals("abcd\ndef".length(), positioner.offsetFromLineColumn(2, 4));
|
||||
|
||||
assertEquals("abcd\ndefghi\r\n".length(), positioner.offsetFromLineColumn(3, 1));
|
||||
assertEquals(source.length(), positioner.offsetFromLineColumn(4, 4));
|
||||
assertEquals(-1, positioner.offsetFromLineColumn(4, 5));
|
||||
assertEquals(source.length(), positioner.offsetFromLineColumn(5, 1));
|
||||
assertEquals(-1, positioner.offsetFromLineColumn(5, 2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -50,11 +50,22 @@ public class TextFilesTest {
|
||||
assertEquals(Chars.wrap("some content"), tf.readContents().getNormalizedText());
|
||||
assertFalse("readonly", tf.isReadOnly());
|
||||
|
||||
// write with CRLF
|
||||
tf.writeContents(
|
||||
TextFileContent.fromCharSeq("new content")
|
||||
TextFileContent.fromCharSeq("new content\r\n")
|
||||
);
|
||||
|
||||
assertEquals(Chars.wrap("new content"), tf.readContents().getNormalizedText());
|
||||
TextFileContent read = tf.readContents();
|
||||
// is normalized to LF when rereading
|
||||
assertEquals(Chars.wrap("new content\n"), read.getNormalizedText());
|
||||
// but line terminator is detected as CRLF
|
||||
assertEquals("\r\n", read.getLineTerminator());
|
||||
|
||||
tf.writeContents(
|
||||
TextFileContent.fromCharSeq("new content\n")
|
||||
);
|
||||
|
||||
assertEquals(Chars.wrap("new content\n"), tf.readContents().getNormalizedText());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,13 +113,21 @@ public class TextFilesTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReaderFileEscape() throws IOException {
|
||||
public void testReaderFile() throws IOException {
|
||||
Path file = makeTmpFile(StandardCharsets.UTF_8, "some\r\ncontent");
|
||||
try (TextFile tf = TextFile.forReader(Files.newBufferedReader(file, StandardCharsets.UTF_8), "filename", dummyVersion)) {
|
||||
assertEquals("filename", tf.getPathId());
|
||||
assertEquals("filename", tf.getDisplayName());
|
||||
assertEquals(dummyVersion, tf.getLanguageVersion());
|
||||
assertEquals(Chars.wrap("some\ncontent"), tf.readContents().getNormalizedText());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReaderFileIsReadOnly() throws IOException {
|
||||
Path file = makeTmpFile(StandardCharsets.UTF_8, "some\r\ncontent");
|
||||
try (TextFile tf = TextFile.forReader(Files.newBufferedReader(file, StandardCharsets.UTF_8), "filename", dummyVersion)) {
|
||||
assertTrue("readonly", tf.isReadOnly());
|
||||
assertThrows(ReadOnlyFileException.class, () -> tf.writeContents(
|
||||
TextFileContent.fromCharSeq("new content")
|
||||
));
|
||||
@@ -140,6 +159,7 @@ public class TextFilesTest {
|
||||
@Test
|
||||
public void testStringFileIsReadonly() throws IOException {
|
||||
try (TextFile tf = TextFile.forCharSeq("contents", "filename", dummyVersion)) {
|
||||
assertTrue("readonly", tf.isReadOnly());
|
||||
assertThrows(ReadOnlyFileException.class, () -> tf.writeContents(
|
||||
TextFileContent.fromCharSeq("new content")
|
||||
));
|
||||
|
||||
@@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.document;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.Test;
|
||||
@@ -33,4 +34,25 @@ public class TextPos2dTest {
|
||||
MatcherAssert.assertThat(pos.toString(), containsString("!debug only!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
TextPos2d pos = TextPos2d.pos2d(1, 1);
|
||||
TextPos2d pos2 = TextPos2d.pos2d(1, 2);
|
||||
assertNotEquals(pos, pos2);
|
||||
assertEquals(pos, TextPos2d.pos2d(1, 1));
|
||||
assertEquals(pos2, pos2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareTo() {
|
||||
TextPos2d pos = TextPos2d.pos2d(1, 1);
|
||||
TextPos2d pos2 = TextPos2d.pos2d(1, 2);
|
||||
TextPos2d pos3 = TextPos2d.pos2d(2, 1);
|
||||
|
||||
assertEquals(-1, pos.compareTo(pos2));
|
||||
assertEquals(-1, pos.compareTo(pos3));
|
||||
assertEquals(-1, pos2.compareTo(pos3));
|
||||
assertEquals(1, pos2.compareTo(pos));
|
||||
assertEquals(0, pos.compareTo(pos));
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ package net.sourceforge.pmd.lang.document;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.Test;
|
||||
@@ -22,6 +23,25 @@ public class TextRange2dTest {
|
||||
assertEquals(pos, pos2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
TextRange2d pos = TextRange2d.range2d(1, 1, 1, 1);
|
||||
TextRange2d pos2 = TextRange2d.range2d(1, 1, 1, 2);
|
||||
assertNotEquals(pos, pos2);
|
||||
assertEquals(pos, pos);
|
||||
assertEquals(pos2, pos2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareTo() {
|
||||
TextRange2d pos = TextRange2d.range2d(1, 1, 1, 1);
|
||||
TextRange2d pos2 = TextRange2d.range2d(1, 1, 1, 2);
|
||||
|
||||
assertEquals(-1, pos.compareTo(pos2));
|
||||
assertEquals(1, pos2.compareTo(pos));
|
||||
assertEquals(0, pos.compareTo(pos));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
TextRange2d range = TextRange2d.range2d(1, 2, 3, 4);
|
||||
|
||||
Reference in new issue
Block a user