/* * Copyright 2003-2015 JetBrains s.r.o. * * Licensed 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. */ package jetbrains.mps.text; import jetbrains.mps.text.BufferSnapshot.TextPosition; import jetbrains.mps.text.impl.TextBufferImpl; import org.jetbrains.annotations.NotNull; import org.junit.Assert; import org.junit.Test; import java.util.ArrayList; /** * @author Artem Tikhomirov */ public class TextBufferTest { private final TextAreaFactory myChunkFactory = new BasicTextAreaFactory(); private final String myLineSep = myChunkFactory.getLineSeparator(); @Test public void testSingleLineMarker() { TextBuffer tb = createTextBuffer(); tb.area().append("ABC"); tb.pushMark(); tb.area().append("DEF"); final TextMark mark = tb.popMark(); tb.area().append("GHI"); // BufferSnapshot t = tb.snapshot(tb.newLayout()); check(t, mark, "DEF", 0, 3, 0, 6); } @NotNull private TextBuffer createTextBuffer() { return new TextBufferImpl(myChunkFactory); } @Test public void testMultiLineMarker() { TextBuffer tb = createTextBuffer(); tb.area().append("ABC"); tb.pushMark(); tb.area().append("DEF").newLine(); tb.area().append("GHI").newLine(); tb.area().append("JKL"); final TextMark mark = tb.popMark(); tb.area().append("MNO"); // BufferSnapshot t = tb.snapshot(tb.newLayout()); check(t, mark, "DEF" + myLineSep + "GHI" + myLineSep + "JKL", 0, 3, 2, 3); } @Test public void testNestedMarker() { TextBuffer tb = createTextBuffer(); tb.area().append("ABC"); tb.pushMark(); tb.area().append("DEF"); tb.pushMark(); tb.area().newLine(); tb.area().append("GHI").newLine(); final TextMark innerMark = tb.popMark(); tb.area().append("JKL"); final TextMark outerMark = tb.popMark(); // BufferSnapshot t = tb.snapshot(tb.newLayout()); final String expectedInner = myLineSep + "GHI" + myLineSep; check(t, innerMark, expectedInner, 0, 6, 2, 0); String expectedOuter = "DEF" + expectedInner + "JKL"; check(t, outerMark, expectedOuter, 0, 3, 2, 3); } @Test public void testMarkerReplacedWithTextArea() { TextBuffer tb = createTextBuffer(); tb.area().append("ABC").newLine(); tb.pushMark(); tb.area().append("DEF").newLine(); // this is the line we are going to replace with another TextArea final TextMark mark = tb.popMark(); tb.pushTextArea(new BasicToken("inner")); tb.area().append("GHI").newLine(); tb.area().append("JKL").newLine(); tb.popTextArea(); tb.area().append("MNO"); // final BufferLayout l = tb.newLayout(); l.replace(mark, new BasicToken("inner")); BufferSnapshot t = tb.snapshot(l); final String expectedText = "ABC" + myLineSep + "GHI" + myLineSep + "JKL" + myLineSep + "MNO"; Assert.assertEquals(expectedText, t.getText().toString()); final String expectedInner = "GHI" + myLineSep + "JKL" + myLineSep; check(t, mark, expectedInner, 1, 0, 3, 0); } @Test public void testSubsequentChunksImplicitLayout() { TextBuffer tb = createTextBuffer(); tb.pushTextArea(new BasicToken("top")); tb.area().append("ABC").newLine(); tb.pushTextArea(new BasicToken("bottom")); tb.area().append("DEF").newLine(); tb.pushMark(); tb.area().append("GHI").newLine(); TextMark mark = tb.popMark(); tb.popTextArea(); tb.area().append("JKL").newLine(); // BufferSnapshot t = tb.snapshot(tb.newLayout()); String top = "ABC" + myLineSep + "JKL" + myLineSep; String bottom = "DEF" + myLineSep + "GHI" + myLineSep; Assert.assertEquals(top + bottom, t.getText().toString()); check(t, mark, "GHI" + myLineSep, 3, 0, 4, 0); } @Test public void testTwoZeroLengthMarksInTheSameLocation() { TextBuffer tb = createTextBuffer(); tb.area().append("ABC").newLine(); final TextMark m1 = tb.pushMark().popMark(); final TextMark m2 = tb.pushMark().popMark(); tb.area().append("GHI").newLine(); tb.pushTextArea(new BasicToken(2)); tb.area().append("EF").newLine(); tb.popTextArea(); tb.area().append("JKL"); tb.pushTextArea(new BasicToken(1)); tb.area().append("D"); tb.popTextArea(); // final BufferLayout l = tb.newLayout(); l.replace(m1, new BasicToken(1)); l.replace(m2, new BasicToken(2)); BufferSnapshot t = tb.snapshot(l); Assert.assertEquals("ABC" + myLineSep + "DEF" + myLineSep + "GHI" + myLineSep + "JKL", t.getText().toString()); check(t, m1, "D", 1, 0, 1, 1); check(t, m2, "EF" + myLineSep, 1, 1, 2, 0); } @Test public void testSameChunkIntoFewMarks() { TextBuffer tb = createTextBuffer(); final String[] lines = {"ABC", "DEF", "GHI"}; final ArrayList<TextMark> marks = new ArrayList<TextMark>(); for (String line : lines) { marks.add(tb.pushMark().popMark()); tb.area().append(line).newLine(); } tb.pushTextArea(new BasicToken("comment")); tb.area().append("// XXX").newLine(); tb.popTextArea(); // final BufferLayout l = tb.newLayout(); for (TextMark m : marks) { l.replace(m, new BasicToken("comment")); } BufferSnapshot t = tb.snapshot(l); StringBuilder expected = new StringBuilder(); for (String line : lines) { expected.append("// XXX").append(myLineSep); expected.append(line).append(myLineSep); } Assert.assertEquals(expected.toString(), t.getText().toString()); } private static void check(BufferSnapshot t, TextMark mark, String expectedText, int startLine, int startCol, int endLine, int endCol) { String text = t.getText(mark).toString(); Assert.assertEquals(expectedText, text); TextPosition start = t.getStart(mark); TextPosition end = t.getEnd(mark); Assert.assertEquals(startLine, start.line); Assert.assertEquals(startCol, start.column); Assert.assertEquals(endLine, end.line); Assert.assertEquals(endCol, end.column); } }