package com.oracle.truffle.api.test.source;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileWriter;
import org.junit.Test;
import com.oracle.truffle.api.TruffleFile;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest;
public class SourceSectionTest extends AbstractPolyglotTest {
private final Source emptySource = Source.newBuilder("", "", "emptySource").build();
private final Source emptyLineSource = Source.newBuilder("", "\n", "emptyLineSource").build();
private final Source shortSource = Source.newBuilder("", "01", "shortSource").build();
private final Source longSource = Source.newBuilder("", "01234\n67\n9\n", "long").build();
private final Source noContentSource = Source.newBuilder("", "", "name").content(Source.CONTENT_NONE).build();
@Test
public void emptySourceTest0() {
SourceSection section = emptySource.createSection(0, 0);
assertNotNull(section);
assertEquals(section.getCharacters(), "");
}
@Test
public void emptyLineTest0() {
SourceSection section = emptyLineSource.createSection(0, 0);
assertNotNull(section);
assertEquals(section.getCharacters(), "");
assertEquals(section.getCharIndex(), 0);
assertEquals(section.getCharLength(), 0);
assertEquals(section.getStartLine(), 1);
assertEquals(section.getStartColumn(), 1);
assertEquals(section.getEndLine(), 1);
assertEquals(section.getEndColumn(), 1);
SourceSection other = emptyLineSource.createSection(0, 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = emptyLineSource.createSection(1);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = emptyLineSource.createSection(1, 1, 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
}
@Test
public void emptyLineTest1() {
SourceSection section = emptyLineSource.createSection(0, 1);
assertNotNull(section);
assertEquals(section.getCharacters(), "\n");
assertEquals(section.getCharIndex(), 0);
assertEquals(section.getCharLength(), 1);
assertEquals(section.getStartLine(), 1);
assertEquals(section.getStartColumn(), 1);
assertEquals(section.getEndLine(), 1);
assertEquals(section.getEndColumn(), 1);
SourceSection other = emptyLineSource.createSection(0, 1);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = emptyLineSource.createSection(1, 1, 1);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = emptyLineSource.createSection(1, 1, 1, 1);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
}
@Test
public void emptyLineTest2() {
SourceSection section = emptyLineSource.createSection(1, 0);
assertNotNull(section);
assertEquals(section.getCharacters(), "");
assertEquals(section.getCharIndex(), 1);
assertEquals(section.getCharLength(), 0);
assertEquals(section.getStartLine(), 2);
assertEquals(section.getStartColumn(), 1);
SourceSection other = emptyLineSource.createSection(1, 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = emptyLineSource.createSection(2);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = emptyLineSource.createSection(2, 1, 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
}
@Test
public void emptySourceTest1() {
SourceSection section = emptySource.createSection(0, 0);
assertNotNull(section);
assertEquals(section.getCharIndex(), 0);
assertEquals(section.getCharLength(), 0);
assertEquals(section.getStartLine(), 1);
assertEquals(section.getEndLine(), 1);
assertEquals(section.getStartColumn(), 1);
assertEquals(section.getEndColumn(), 1);
assertEquals("", section.getCharacters());
SourceSection other = emptySource.createSection(0, 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = emptySource.createSection(1, 1, 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = emptySource.createSection(1, 1, 1, 1);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
}
@Test
public void emptySourceSectionOnLongSource() {
SourceSection section = longSource.createSection(longSource.getCharacters().length() - 1, 0);
assertNotNull(section);
assertEquals(longSource.getCharacters().length() - 1, section.getCharIndex());
assertEquals(0, section.getCharLength(), 0);
assertEquals(3, section.getStartLine());
assertEquals(3, section.getEndLine());
assertEquals(2, section.getStartColumn());
assertEquals(2, section.getEndColumn());
SourceSection other = longSource.createSection(longSource.getCharacters().length() - 1, 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = longSource.createSection(3, 2, 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
}
@Test
public void emptySourceSectionOnLongSourceEnd() {
SourceSection section = longSource.createSection(longSource.getCharacters().length(), 0);
assertNotNull(section);
assertEquals(longSource.getCharacters().length(), section.getCharIndex());
assertEquals(0, section.getCharLength(), 0);
assertEquals(4, section.getStartLine());
assertEquals(4, section.getEndLine());
assertEquals(1, section.getStartColumn());
assertEquals(1, section.getEndColumn());
SourceSection other = longSource.createSection(longSource.getCharacters().length(), 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = longSource.createSection(4, 1, 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
other = longSource.createSection(4, 1, 4, 1);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
}
@Test
public void emptySectionTest2() {
SourceSection section = shortSource.createSection(0, 0);
assertNotNull(section);
assertEquals(section.getCharacters(), "");
}
@Test
public void emptySectionTest3() {
SourceSection section = longSource.createSection(0, 0);
assertNotNull(section);
assertEquals(section.getCharacters(), "");
}
@Test
public void testAllSections() {
int sourceLength = longSource.getCharacters().length();
for (int i = 0; i <= sourceLength; i++) {
for (int j = i; j <= sourceLength; j++) {
int length = j - i;
SourceSection section = longSource.createSection(i, length);
int line1 = i <= 5 ? 1 : i <= 8 ? 2 : i <= 10 ? 3 : 4;
int col1 = i <= 5 ? i + 1 : i <= 8 ? i - 5 : i <= 10 ? i - 8 : i - 10;
int line2 = length == 0 ? line1 : j <= 6 ? 1 : j <= 9 ? 2 : 3;
int col2 = length == 0 ? col1 : j <= 6 ? j : j <= 9 ? j - 6 : j - 9;
assertEquals(i, section.getCharIndex());
assertEquals(length, section.getCharLength());
assertEquals(line1, section.getStartLine());
assertEquals(col1, section.getStartColumn());
assertEquals(line2, section.getEndLine());
assertEquals(col2, section.getEndColumn());
SourceSection other = longSource.createSection(line1, col1, length);
assertTrue(other.toString(), section.equals(other));
other = longSource.createSection(line1, col1, line2, col2);
if (length > 0 || j == sourceLength) {
assertTrue(other.toString(), section.equals(other));
} else {
assertEquals(1, other.getCharLength());
}
assertEquals(length, section.getCharacters().length());
}
}
}
@Test
public void testGetCode() {
assertEquals("01234", longSource.createSection(0, 5).getCharacters());
assertEquals("67", longSource.createSection(6, 2).getCharacters());
assertEquals("9", longSource.createSection(9, 1).getCharacters());
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange1() {
longSource.createSection(9, 5);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange2() {
longSource.createSection(-1, 1);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange3() {
longSource.createSection(1, -1);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange7() {
longSource.createSection(longSource.getCharacters().length() - 4, 5);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange8() {
longSource.createSection(longSource.getCharacters().length(), 1);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange9() {
longSource.createSection(longSource.getCharacters().length() + 1, 0);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange10() {
longSource.createSection(4, 1, 1);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange11() {
longSource.createSection(-1, 1, 1);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange12() {
longSource.createSection(1, 7, 1);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange13() {
shortSource.createSection(2);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange14() {
longSource.createSection(-1);
}
@Test(expected = IllegalArgumentException.class)
public void testOutOfRange15() {
longSource.createSection(5);
}
@Test
public void testUnavailable() {
SourceSection section = longSource.createUnavailableSection();
assertEquals(0, section.getCharEndIndex());
assertEquals(0, section.getCharIndex());
assertEquals(0, section.getCharLength());
assertEquals(1, section.getStartColumn());
assertEquals(1, section.getEndColumn());
assertEquals(1, section.getStartLine());
assertEquals(1, section.getEndLine());
assertSame(longSource, section.getSource());
assertFalse(section.isAvailable());
assertEquals("", section.getCharacters());
assertNotNull(section.toString());
SourceSection other = longSource.createUnavailableSection();
assertFalse(section.equals(other));
assertNotEquals(other.hashCode(), section.hashCode());
SourceSection other2 = shortSource.createUnavailableSection();
assertFalse(section.equals(other2));
assertNotEquals(other2.hashCode(), section.hashCode());
}
@Test
public void testEOF1() {
SourceSection section = shortSource.createSection(shortSource.getLength(), 0);
assertNotNull(section);
assertEquals(section.getCharIndex(), shortSource.getLength());
assertEquals(section.getCharLength(), 0);
assertEquals(section.getStartLine(), 1);
assertEquals(section.getEndLine(), 1);
assertEquals(section.getStartColumn(), 3);
assertEquals(section.getEndColumn(), 3);
assertEquals("", section.getCharacters());
SourceSection other = shortSource.createSection(shortSource.getLength(), 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
}
@Test
public void testEOF2() {
SourceSection section = longSource.createSection(longSource.getLength(), 0);
assertNotNull(section);
assertEquals(section.getCharIndex(), longSource.getLength());
assertEquals(section.getCharLength(), 0);
assertEquals(section.getStartLine(), 4);
assertEquals(section.getEndLine(), 4);
assertEquals(section.getStartColumn(), 1);
assertEquals(section.getEndColumn(), 1);
assertEquals("", section.getCharacters());
SourceSection other = longSource.createSection(longSource.getLength(), 0);
assertTrue(section.equals(other));
assertEquals(other.hashCode(), section.hashCode());
}
@Test
public void testFinalNL() {
int sourceLength = longSource.getCharacters().length();
SourceSection section = longSource.createSection(4);
assertNotNull(section);
assertEquals(sourceLength, section.getCharIndex());
assertEquals(0, section.getCharLength());
assertEquals(4, section.getStartLine());
assertEquals(4, section.getEndLine());
assertEquals(1, section.getStartColumn());
assertEquals(1, section.getEndColumn());
assertEquals("", section.getCharacters());
assertTrue(section.isAvailable());
}
@Test
public void onceObtainedAlwaysTheSame() throws Exception {
setupEnv();
File rawFile = File.createTempFile("hello", ".txt");
rawFile.deleteOnExit();
try (FileWriter w = new FileWriter(rawFile)) {
w.write("Hello world!");
}
TruffleFile sample = languageEnv.getPublicTruffleFile(rawFile.getPath());
Source complexHello = Source.newBuilder("", sample).build();
SourceSection helloTo = complexHello.createSection(6, 5);
assertEquals("world", helloTo.getCharacters());
try (FileWriter w = new FileWriter(rawFile)) {
w.write("Hi world!");
}
Source simpleHi = Source.newBuilder("", sample).build();
SourceSection hiTo = simpleHi.createSection(3, 5);
assertEquals("world", hiTo.getCharacters());
assertEquals("Previously allocated sections remain the same", "world", helloTo.getCharacters());
sample.delete();
}
@Test
public void testNoContent() {
SourceSection section = noContentSource.createSection(10);
checkNoContentSection(section, true, false, false, 10, 1, 10, 1, 0, 0, 0);
section = noContentSource.createSection(2, 5);
checkNoContentSection(section, false, false, true, 1, 1, 1, 1, 2, 7, 5);
section = noContentSource.createSection(1, -1, 3, -1);
checkNoContentSection(section, true, false, false, 1, 1, 3, 1, 0, 0, 0);
section = noContentSource.createSection(1, 2, 3, 4);
checkNoContentSection(section, true, true, false, 1, 2, 3, 4, 0, 0, 0);
assertFails(() -> noContentSource.createSection(2, 3, -1), UnsupportedOperationException.class);
assertFails(() -> noContentSource.createSection(-1), IllegalArgumentException.class);
assertFails(() -> noContentSource.createSection(1, -1), IllegalArgumentException.class);
assertFails(() -> noContentSource.createSection(-1, 1, 1, 1), IllegalArgumentException.class);
assertFails(() -> noContentSource.createSection(1, -1, 1, 1), IllegalArgumentException.class);
assertFails(() -> noContentSource.createSection(1, 1, -1, 1), IllegalArgumentException.class);
assertFails(() -> noContentSource.createSection(1, 1, 1, -1), IllegalArgumentException.class);
}
private static void checkNoContentSection(SourceSection section, boolean hasLines, boolean hasColumns, boolean hasIndex,
int startLine, int startColumn, int endLine, int endColumn, int startIndex, int endIndex, int length) {
assertEquals(hasLines, section.hasLines());
assertEquals(hasColumns, section.hasColumns());
assertEquals(hasIndex, section.hasCharIndex());
assertEquals(startLine, section.getStartLine());
assertEquals(startColumn, section.getStartColumn());
assertEquals(endLine, section.getEndLine());
assertEquals(endColumn, section.getEndColumn());
assertTrue(section.isAvailable());
assertFalse(section.getSource().hasCharacters());
assertEquals(startIndex, section.getCharIndex());
assertEquals(endIndex, section.getCharEndIndex());
assertEquals(length, section.getCharLength());
assertEquals("", section.getCharacters());
}
}