mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[formatter tests] new way of specifying test formatting model
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 com.intellij.formatting
|
||||
|
||||
import com.intellij.formatting.*
|
||||
import com.intellij.formatting.engine.testModel.TestBlock
|
||||
import com.intellij.openapi.util.TextRange
|
||||
|
||||
|
||||
class BlockAttributes(val alignment: Alignment? = null, val wrap: Wrap? = null, val indent: Indent? = null, val spacing: Spacing? = null)
|
||||
|
||||
class CompositeTestBlock(startOffset: Int,
|
||||
attributes: BlockAttributes,
|
||||
private val children: List<TestBlockBase>) : TestBlockBase(startOffset, attributes)
|
||||
{
|
||||
override fun getSubBlocks() = children
|
||||
override fun isLeaf() = false
|
||||
override val endOffset = children.last().endOffset
|
||||
}
|
||||
|
||||
class LeafTestBlock(startOffset: Int, attributes: BlockAttributes, val text: String) : TestBlockBase(startOffset, attributes) {
|
||||
override fun getSubBlocks() = emptyList<Block>()
|
||||
override fun isLeaf() = true
|
||||
override val endOffset = startOffset + text.length
|
||||
}
|
||||
|
||||
abstract class TestBlockBase(val startOffset: Int,
|
||||
private val attributes: BlockAttributes) : Block {
|
||||
|
||||
override fun getAlignment() = attributes.alignment
|
||||
override fun getTextRange() = TextRange(startOffset, endOffset)
|
||||
override fun getWrap() = attributes.wrap
|
||||
override fun getIndent() = attributes.indent
|
||||
override fun getSpacing(child1: Block?, child2: Block) = attributes.spacing
|
||||
|
||||
override fun getChildAttributes(newChildIndex: Int): ChildAttributes = ChildAttributes.DELEGATE_TO_NEXT_CHILD
|
||||
override fun isIncomplete() = false
|
||||
|
||||
abstract val endOffset: Int
|
||||
|
||||
}
|
||||
|
||||
class AttributesProvider {
|
||||
|
||||
private val alignments = hashMapOf<Int, Alignment>()
|
||||
|
||||
fun extract(text: String): BlockAttributes {
|
||||
val attributes: List<String> = text.split(",").map(String::trim)
|
||||
val alignment = getAlignment(attributes)
|
||||
return BlockAttributes(alignment = alignment)
|
||||
}
|
||||
|
||||
private fun getAlignment(attributes: List<String>): Alignment? {
|
||||
val index = attributes.find { it.startsWith("a") }?.substring(1)?.toInt()
|
||||
if (index == null || index < 0) return null
|
||||
|
||||
var alignment = alignments[index]
|
||||
if (alignment != null) {
|
||||
return alignment
|
||||
}
|
||||
|
||||
alignment = AlignmentImpl(true, Alignment.Anchor.LEFT)
|
||||
alignments[index] = alignment
|
||||
return alignment
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun TestBlock.Composite.toFormattingBlock(startOffset: Int): CompositeTestBlock {
|
||||
val childBlocks = mutableListOf<TestBlockBase>()
|
||||
val attributesProvider = AttributesProvider()
|
||||
var previousStartOffset = startOffset
|
||||
|
||||
children.forEach {
|
||||
val block = when (it) {
|
||||
is TestBlock.Composite -> {
|
||||
val composite = it.toFormattingBlock(previousStartOffset)
|
||||
previousStartOffset = composite.endOffset
|
||||
composite
|
||||
}
|
||||
is TestBlock.Leaf -> {
|
||||
val attributes = attributesProvider.extract(it.attributes)
|
||||
val leaf = LeafTestBlock(previousStartOffset, attributes, it.text)
|
||||
previousStartOffset = leaf.endOffset
|
||||
leaf
|
||||
}
|
||||
is TestBlock.Space -> {
|
||||
previousStartOffset += it.text.length
|
||||
null
|
||||
}
|
||||
}
|
||||
block?.let { childBlocks.add(it) }
|
||||
}
|
||||
|
||||
val attributes = attributesProvider.extract(attributes)
|
||||
return CompositeTestBlock(startOffset, attributes, childBlocks)
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 com.intellij.formatting.engine
|
||||
|
||||
import com.intellij.formatting.FormatTextRanges
|
||||
import com.intellij.formatting.FormatterImpl
|
||||
import com.intellij.formatting.engine.testModel.TestFormattingModel
|
||||
import com.intellij.formatting.engine.testModel.getRoot
|
||||
import com.intellij.formatting.toFormattingBlock
|
||||
import com.intellij.openapi.editor.EditorFactory
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import junit.framework.TestCase
|
||||
import org.junit.Test
|
||||
|
||||
class FormatterEngineTests : LightPlatformTestCase() {
|
||||
|
||||
@Test
|
||||
fun `test simple alignment`() {
|
||||
doTest(
|
||||
"""
|
||||
[a0]fooooo [a1]foo
|
||||
[a0]go [a1]boo
|
||||
""",
|
||||
"""
|
||||
fooooo foo
|
||||
go boo
|
||||
""")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun doTest(before: String, expectedText: String) {
|
||||
val root = getRoot(before.trimStart())
|
||||
val rootFormattingBlock = root.toFormattingBlock(0)
|
||||
val beforeText = root.text
|
||||
|
||||
val document = EditorFactory.getInstance().createDocument(beforeText)
|
||||
val model = TestFormattingModel(rootFormattingBlock, document)
|
||||
|
||||
val settings = CodeStyleSettings()
|
||||
val textRanges = FormatTextRanges(TextRange(0, document.textLength - 1), true)
|
||||
|
||||
val formatter = FormatterImpl()
|
||||
formatter.format(model, settings, settings.indentOptions, textRanges)
|
||||
|
||||
TestCase.assertEquals(document.text, expectedText.trimStart())
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 com.intellij.formatting.engine.testModel
|
||||
|
||||
import com.intellij.formatting.Block
|
||||
import com.intellij.formatting.FormattingDocumentModel
|
||||
import com.intellij.formatting.FormattingModel
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.util.text.CharArrayUtil
|
||||
|
||||
class TestFormattingModel(private val rootBlock: Block,
|
||||
private val document: Document) : FormattingModel, FormattingDocumentModel {
|
||||
|
||||
override fun getRootBlock() = rootBlock
|
||||
|
||||
override fun getDocumentModel() = this
|
||||
|
||||
override fun replaceWhiteSpace(textRange: TextRange, whiteSpace: String): TextRange {
|
||||
WriteCommandAction.runWriteCommandAction(null) {
|
||||
document.replaceString(textRange.startOffset, textRange.endOffset, whiteSpace)
|
||||
}
|
||||
return TextRange(textRange.startOffset, textRange.startOffset + whiteSpace.length)
|
||||
}
|
||||
|
||||
override fun shiftIndentInsideRange(node: ASTNode, range: TextRange, indent: Int): TextRange {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun commitChanges() {
|
||||
}
|
||||
|
||||
override fun getLineNumber(offset: Int) = document.getLineNumber(offset)
|
||||
|
||||
override fun getLineStartOffset(line: Int) = document.getLineStartOffset(line)
|
||||
|
||||
override fun getText(textRange: TextRange) = document.getText(textRange)
|
||||
|
||||
override fun getTextLength() = document.textLength
|
||||
|
||||
override fun getDocument() = document
|
||||
|
||||
override fun containsWhiteSpaceSymbolsOnly(startOffset: Int, endOffset: Int): Boolean {
|
||||
return CharArrayUtil.containsOnlyWhiteSpaces(document.getText(TextRange(startOffset, endOffset)))
|
||||
}
|
||||
|
||||
override fun adjustWhiteSpaceIfNecessary(whiteSpaceText: CharSequence,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
nodeAfter: ASTNode?,
|
||||
changedViaPsi: Boolean): CharSequence {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 com.intellij.formatting.engine.testModel
|
||||
|
||||
enum class Label {
|
||||
SPACE,
|
||||
LPARENTH,
|
||||
RPARENTH,
|
||||
ATTR_START,
|
||||
ATTR_END,
|
||||
TEXT
|
||||
}
|
||||
|
||||
private class TestBlockTreeBuilder {
|
||||
private val stack = mutableListOf(TestBlock.Composite(""))
|
||||
private var recentSeenAttributes: String? = null
|
||||
|
||||
fun attributes(attributes: String) {
|
||||
recentSeenAttributes = attributes
|
||||
}
|
||||
|
||||
fun compositeBlockStart() {
|
||||
val lastChild = TestBlock.Composite(recentSeenAttributes!!)
|
||||
recentSeenAttributes = null
|
||||
|
||||
top().addChild(lastChild)
|
||||
stack.add(lastChild)
|
||||
}
|
||||
|
||||
fun space(text: String) {
|
||||
if (recentSeenAttributes != null) leafBlock("")
|
||||
|
||||
val space = TestBlock.Space(text)
|
||||
top().addChild(space)
|
||||
}
|
||||
|
||||
fun leafBlock(text: String) {
|
||||
top().addChild(TestBlock.Leaf(recentSeenAttributes!!, text))
|
||||
recentSeenAttributes = null
|
||||
}
|
||||
|
||||
private fun top() = stack.last()
|
||||
|
||||
fun compositeBlockEnd() {
|
||||
if (recentSeenAttributes != null) leafBlock("")
|
||||
|
||||
stack.removeAt(stack.lastIndex)
|
||||
}
|
||||
|
||||
fun rootBlock(): TestBlock.Composite {
|
||||
if (recentSeenAttributes != null) leafBlock("")
|
||||
|
||||
return stack.first()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestModelParser(private val text: String) {
|
||||
private val builder = TestBlockTreeBuilder()
|
||||
|
||||
private fun getLabel(c: Char): Label {
|
||||
return when (c) {
|
||||
' ', '\n' -> Label.SPACE
|
||||
'[' -> Label.ATTR_START
|
||||
']' -> Label.ATTR_END
|
||||
'(' -> Label.LPARENTH
|
||||
')' -> Label.RPARENTH
|
||||
else -> Label.TEXT
|
||||
}
|
||||
}
|
||||
|
||||
fun parse(): TestBlock {
|
||||
var currentIndex = 0
|
||||
|
||||
while (currentIndex < text.length) {
|
||||
val char = text[currentIndex]
|
||||
val label = getLabel(char)
|
||||
|
||||
currentIndex = when (label) {
|
||||
Label.ATTR_START -> handleAttributes(currentIndex)
|
||||
Label.ATTR_END -> currentIndex + 1
|
||||
Label.TEXT -> handleText(currentIndex)
|
||||
Label.LPARENTH -> handleLParenth(currentIndex)
|
||||
Label.RPARENTH -> handleRParenth(currentIndex)
|
||||
Label.SPACE -> handleSpace(currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
return builder.rootBlock()
|
||||
}
|
||||
|
||||
private fun handleSpace(currentIndex: Int): Int {
|
||||
val spaceEnd = text.firstIndexOfAnyLabel(currentIndex, Label.ATTR_START)
|
||||
builder.space(text.substring(currentIndex, spaceEnd))
|
||||
return spaceEnd
|
||||
}
|
||||
|
||||
private fun handleLParenth(currentIndex: Int): Int {
|
||||
builder.compositeBlockStart()
|
||||
return currentIndex + 1
|
||||
}
|
||||
|
||||
private fun handleRParenth(currentIndex: Int): Int {
|
||||
builder.compositeBlockEnd()
|
||||
return currentIndex + 1
|
||||
}
|
||||
|
||||
private fun handleText(currentIndex: Int): Int {
|
||||
val textEnd = text.firstIndexOfAnyLabel(currentIndex, Label.SPACE, Label.ATTR_START, Label.RPARENTH)
|
||||
val blockText = text.substring(currentIndex, textEnd)
|
||||
builder.leafBlock(blockText)
|
||||
return textEnd
|
||||
}
|
||||
|
||||
private fun handleAttributes(currentIndex: Int): Int {
|
||||
val attrsEnd = text.firstIndexOfLabel(currentIndex, Label.ATTR_END)
|
||||
builder.attributes(text.substring(currentIndex + 1, attrsEnd))
|
||||
return attrsEnd
|
||||
}
|
||||
|
||||
private fun String.firstIndexOfLabel(start: Int, label: Label): Int {
|
||||
val indexOfLabel = substring(start).indexOfFirst { getLabel(it) == label }
|
||||
return if (indexOfLabel > 0) start + indexOfLabel else length
|
||||
}
|
||||
|
||||
private fun String.firstIndexOfAnyLabel(start: Int, vararg labels: Label): Int {
|
||||
val allLabels = labels.toHashSet()
|
||||
val indexOfLabel = substring(start).indexOfFirst { allLabels.contains(getLabel(it)) }
|
||||
return if (indexOfLabel > 0) start + indexOfLabel else length
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
sealed class TestBlock {
|
||||
abstract val text: String
|
||||
|
||||
class Space(override val text: String) : TestBlock()
|
||||
|
||||
class Leaf(val attributes: String, override val text: String) : TestBlock()
|
||||
|
||||
class Composite(val attributes: String) : TestBlock() {
|
||||
val children = mutableListOf<TestBlock>()
|
||||
fun addChild(block: TestBlock) = children.add(block)
|
||||
override val text: String
|
||||
get() = children.joinToString("", transform = { it.text })
|
||||
}
|
||||
}
|
||||
|
||||
fun getRoot(text: String): TestBlock.Composite {
|
||||
val parser = TestModelParser(text)
|
||||
return parser.parse() as TestBlock.Composite
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 com.intellij.formatting.engine.testModelTests
|
||||
|
||||
import com.intellij.formatting.Block
|
||||
import com.intellij.formatting.CompositeTestBlock
|
||||
import com.intellij.formatting.engine.testModel.getRoot
|
||||
import com.intellij.formatting.toFormattingBlock
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.testFramework.Assertions
|
||||
import com.intellij.testFramework.Assertions.assertThat
|
||||
import com.intellij.util.containers.TreeTraversal
|
||||
import org.junit.Test
|
||||
|
||||
class TestFormattingModelBuilderTest {
|
||||
|
||||
@Test
|
||||
fun `test model with correct ranges is built`() {
|
||||
val root = getRoot(
|
||||
"""[a0]foo [a1]goo
|
||||
[]hoo
|
||||
[a1]([a2]qoo [a2]woo [a3]([]roo []too))"""
|
||||
)
|
||||
|
||||
val rootFormattingBlock = root.toFormattingBlock(0)
|
||||
|
||||
val subBlocks = rootFormattingBlock.subBlocks
|
||||
Assertions.assertThat(subBlocks).hasSize(4)
|
||||
|
||||
Assertions.assertThat(subBlocks.last().subBlocks).hasSize(3)
|
||||
Assertions.assertThat(subBlocks.last().subBlocks.last().subBlocks).hasSize(2)
|
||||
|
||||
assertLeafRanges(rootFormattingBlock, 0..3, 12..15, 30..33, 34..37, 50..53, 60..63, 64..67)
|
||||
}
|
||||
|
||||
private fun assertLeafRanges(rootFormattingBlock: CompositeTestBlock, vararg ranges: IntRange) {
|
||||
val textRanges = ranges.map { TextRange(it.start, it.endInclusive) }
|
||||
val leafs = TreeTraversal.LEAVES_DFS.createIterator<Block>(rootFormattingBlock.subBlocks, { it.subBlocks }).toList()
|
||||
Assertions.assertThat(textRanges).isEqualTo(leafs.map { it.textRange })
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `test alignment parsing`() {
|
||||
val root = getRoot("[a0]foo [a1]goo [a0]hoo")
|
||||
val rootBlock = root.toFormattingBlock(0)
|
||||
assertLeafRanges(rootBlock, 0..3, 4..7, 8..11)
|
||||
|
||||
val children = rootBlock.subBlocks
|
||||
|
||||
assertThat(children[0].alignment).isNotNull()
|
||||
assertThat(children[1].alignment).isNotNull()
|
||||
assertThat(children[0].alignment).isEqualTo(children[2].alignment)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test empty block`() {
|
||||
val root = getRoot(
|
||||
"""[a0]fooooo [a1]
|
||||
[a0]go [a1]boo
|
||||
""").toFormattingBlock(0)
|
||||
|
||||
val children = root.subBlocks
|
||||
|
||||
assertThat(children).hasSize(4)
|
||||
assertThat(children[0].alignment).isEqualTo(children[2].alignment)
|
||||
assertThat(children[1].alignment).isEqualTo(children[3].alignment)
|
||||
|
||||
assertThat(children[1].textRange.isEmpty).isTrue()
|
||||
}
|
||||
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 com.intellij.formatting.engine.testModelTests
|
||||
|
||||
import com.intellij.formatting.engine.testModel.TestBlock
|
||||
import com.intellij.formatting.engine.testModel.getRoot
|
||||
import com.intellij.testFramework.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
|
||||
class TestModelParserTest {
|
||||
|
||||
@Test
|
||||
fun `test simple block parsing`() {
|
||||
val children = getBlocks("[a1]block")
|
||||
assertThat(children).hasSize(1)
|
||||
|
||||
val child = children[0]
|
||||
assertLeaf(child, "a1", "block")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test block with no attributes`() {
|
||||
val children = getBlocks("[]block")
|
||||
assertThat(children).hasSize(1)
|
||||
|
||||
val child = children[0]
|
||||
assertLeaf(child, "", "block")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test empty block with no attributes`() {
|
||||
val children = getBlocks("[]")
|
||||
assertThat(children).hasSize(1)
|
||||
|
||||
val child = children[0]
|
||||
assertLeaf(child, "", "")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test multiple blocks`() {
|
||||
val children = getRoot("[a1]foo \n\n\n \n\n\n [a2]goo").children
|
||||
assertThat(children).hasSize(3)
|
||||
|
||||
assertLeaf(children[0], "a1", "foo")
|
||||
assertSpace(children[1], " \n\n\n \n\n\n ")
|
||||
assertLeaf(children[2], "a2", "goo")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test simple block with space`() {
|
||||
val children = getBlocks("[a1]foo \n ")
|
||||
assertThat(children).hasSize(2)
|
||||
|
||||
assertLeaf(children[0], "a1", "foo")
|
||||
assertSpace(children[1], " \n ")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test composite block`() {
|
||||
var children = getBlocks("[]([]foo \n \n \n [a3]goo)")
|
||||
assertThat(children).hasSize(1)
|
||||
|
||||
children = (children[0] as TestBlock.Composite).children
|
||||
assertThat(children).hasSize(3)
|
||||
assertLeaf(children[0], "", "foo")
|
||||
assertSpace(children[1], " \n \n \n ")
|
||||
assertLeaf(children[2], "a3", "goo")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test multiple composite blocks`() {
|
||||
var children = getBlocks("[]([]([]foo \n\n\n []goo) \n\n\n []([]woo))")
|
||||
assertThat(children).hasSize(1)
|
||||
|
||||
children = (children[0] as TestBlock.Composite).children
|
||||
assertThat(children).hasSize(3)
|
||||
|
||||
assertThat((children[0] as TestBlock.Composite).children).hasSize(3)
|
||||
assertThat((children[2] as TestBlock.Composite).children).hasSize(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test nested composite blocks`() {
|
||||
var children = getBlocks("[a0]([a1]([a2]([a3]([a4]foo))))")
|
||||
|
||||
for (i in 0..3) {
|
||||
assertThat(children).hasSize(1)
|
||||
val child = children[0] as TestBlock.Composite
|
||||
assertThat(child.attributes).isEqualTo("a$i")
|
||||
children = child.children
|
||||
}
|
||||
|
||||
val leaf = children[0] as TestBlock.Leaf
|
||||
assertThat(leaf.attributes).isEqualTo("a4")
|
||||
assertThat(leaf.text).isEqualTo("foo")
|
||||
}
|
||||
|
||||
private fun assertLeaf(testBlock: TestBlock, attrs: String, text: String) {
|
||||
val leaf = testBlock as TestBlock.Leaf
|
||||
assertThat(leaf.text).isEqualTo(text)
|
||||
assertThat(leaf.attributes).isEqualTo(attrs)
|
||||
}
|
||||
|
||||
private fun assertSpace(testBlock: TestBlock, space: String) {
|
||||
val leaf = testBlock as TestBlock.Space
|
||||
assertThat(leaf.text).isEqualTo(space)
|
||||
}
|
||||
|
||||
private fun getBlocks(text: String): MutableList<TestBlock> {
|
||||
val root = getRoot(text)
|
||||
val children = root.children
|
||||
return children
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user