feat: 一部のパースができるように
This commit is contained in:
parent
daed5fb235
commit
815425f01e
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
## What is it?
|
## What is it?
|
||||||
|
|
||||||
|
***abc**d**e**f*
|
||||||
|
|
||||||
This repository contains a simple library project, intended to demonstrate
|
This repository contains a simple library project, intended to demonstrate
|
||||||
a [Kotlin Multiplatform](https://kotlinlang.org/docs/multiplatform.html) library that is deployable
|
a [Kotlin Multiplatform](https://kotlinlang.org/docs/multiplatform.html) library that is deployable
|
||||||
to [Maven Central](https://central.sonatype.com/).
|
to [Maven Central](https://central.sonatype.com/).
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
package io.github.kotlin.fibonacci
|
|
||||||
|
|
||||||
actual val firstElement: Int = 1
|
|
||||||
actual val secondElement: Int = 2
|
|
|
@ -1,12 +0,0 @@
|
||||||
package io.github.kotlin.fibonacci
|
|
||||||
|
|
||||||
import kotlin.test.Test
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
|
|
||||||
class AndroidFibiTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test 3rd element`() {
|
|
||||||
assertEquals(3, generateFibi().take(3).last())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,18 +2,70 @@ package dev.usbharu.markdown
|
||||||
|
|
||||||
import kotlin.collections.List
|
import kotlin.collections.List
|
||||||
|
|
||||||
sealed class AstNode
|
sealed class AstNode {
|
||||||
data class RootNode(val node: AstNode) : AstNode()
|
open fun print(): String {
|
||||||
data class BodyNode(val body: List<AstNode>) : AstNode()
|
return toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class RootNode(val node: AstNode) : AstNode() {
|
||||||
|
override fun print(): String {
|
||||||
|
return node.print()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class BodyNode(val body: List<AstNode>) : AstNode() {
|
||||||
|
override fun print(): String {
|
||||||
|
return body.joinToString("\n") { it.print() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sealed class BlockNode : AstNode()
|
sealed class BlockNode : AstNode()
|
||||||
|
|
||||||
data class HeaderNode(val header: Int, val headerText: HeaderText?) : BlockNode()
|
data class HeaderNode(val header: Int, val headerTextNode: HeaderTextNode?) : BlockNode() {
|
||||||
data class HeaderText(val text: String) : BlockNode()
|
override fun print(): String {
|
||||||
|
return "#".repeat(header) + " " + headerTextNode?.print().orEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class HeaderTextNode(val text: String) : BlockNode() {
|
||||||
|
override fun print(): String {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sealed interface QuotableNode
|
sealed interface QuotableNode
|
||||||
data class QuoteNode(val nodes: List<QuotableNode>) : AstNode(), QuotableNode
|
data class QuoteNode(val nodes: List<QuotableNode>) : AstNode(), QuotableNode
|
||||||
data object SeparatorNode : BlockNode()
|
data object SeparatorNode : BlockNode() {
|
||||||
|
override fun print(): String {
|
||||||
|
return "---"
|
||||||
|
}
|
||||||
|
}
|
||||||
sealed class ListNode : BlockNode()
|
sealed class ListNode : BlockNode()
|
||||||
data class DiscListNode(val node: InlineNode, val childList: List<ListNode>) : ListNode()
|
data class DiscListNode(val node: InlineNode, val childList: List<ListNode>) : ListNode()
|
||||||
data class DecimalListNode(val node: InlineNode, val childList: List<ListNode>) : ListNode()
|
data class DecimalListNode(val node: InlineNode, val childList: List<ListNode>) : ListNode()
|
||||||
|
data class ParagraphNode(val nodes: List<InlineNode>) : ListNode() {
|
||||||
|
override fun print(): String {
|
||||||
|
return nodes.joinToString("\n") { it.print() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sealed class InlineNode : AstNode(), QuotableNode
|
sealed class InlineNode : AstNode(), QuotableNode
|
||||||
|
data class ItalicNode(val nodes: MutableList<InlineNode>) : InlineNode() {
|
||||||
|
override fun print(): String {
|
||||||
|
return nodes.joinToString("", prefix = "*", postfix = "*") { it.print() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class BoldNode(val nodes: MutableList<InlineNode>) : InlineNode() {
|
||||||
|
override fun print(): String {
|
||||||
|
return nodes.joinToString("", prefix = "**", postfix = "**") { it.print() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class StrikeThroughNode(val nodes: List<InlineNode>) : InlineNode()
|
||||||
|
data class PlainText(val text: String) : InlineNode() {
|
||||||
|
override fun print(): String {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,172 @@ package dev.usbharu.markdown
|
||||||
import kotlin.collections.List
|
import kotlin.collections.List
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
fun parse(tokens: List<Token>) {
|
fun parse(tokens: List<Token>): AstNode {
|
||||||
|
val iterator = PeekableTokenIterator(tokens)
|
||||||
|
|
||||||
|
|
||||||
|
val nodes = mutableListOf<AstNode>()
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
val node = when (val next = iterator.next()) {
|
||||||
|
is Asterisk -> paragraph(next, iterator)
|
||||||
|
is Break -> null
|
||||||
|
is CheckBox -> TODO()
|
||||||
|
is CodeBlock -> TODO()
|
||||||
|
is CodeBlockLanguage -> TODO()
|
||||||
|
Exclamation -> TODO()
|
||||||
|
is Header -> header(next, iterator)
|
||||||
|
is Html -> TODO()
|
||||||
|
is InlineCodeBlock -> TODO()
|
||||||
|
is dev.usbharu.markdown.List -> TODO()
|
||||||
|
ParenthesesEnd -> TODO()
|
||||||
|
ParenthesesStart -> TODO()
|
||||||
|
is Quote -> TODO()
|
||||||
|
is Separator -> separator(next, iterator)
|
||||||
|
SquareBracketEnd -> TODO()
|
||||||
|
SquareBracketStart -> TODO()
|
||||||
|
is Strike -> TODO()
|
||||||
|
is Text -> paragraph(next, iterator)
|
||||||
|
is Url -> TODO()
|
||||||
|
is UrlTitle -> TODO()
|
||||||
|
is Whitespace -> TODO()
|
||||||
|
}
|
||||||
|
if (node != null) {
|
||||||
|
nodes.add(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RootNode(BodyNode(nodes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun separator(separator: Separator, iterator: PeekableTokenIterator): AstNode {
|
||||||
|
return SeparatorNode
|
||||||
|
}
|
||||||
|
|
||||||
|
fun header(header: Header, iterator: PeekableTokenIterator): AstNode {
|
||||||
|
val peekOrNull = iterator.peekOrNull()
|
||||||
|
val headerTextNode = if (peekOrNull is Text) {
|
||||||
|
iterator.next()
|
||||||
|
HeaderTextNode(peekOrNull.text)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
return HeaderNode(header.count, headerTextNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun paragraph(token: Token, iterator: PeekableTokenIterator): AstNode {
|
||||||
|
return ParagraphNode(inline(token, iterator))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inline(token: Token, iterator: PeekableTokenIterator): MutableList<InlineNode> {
|
||||||
|
println("inline start token:$token")
|
||||||
|
iterator.print()
|
||||||
|
val node = when (token) {
|
||||||
|
is Asterisk -> asterisk(token, iterator)
|
||||||
|
Exclamation -> TODO()
|
||||||
|
is InlineCodeBlock -> TODO()
|
||||||
|
ParenthesesEnd -> TODO()
|
||||||
|
ParenthesesStart -> TODO()
|
||||||
|
SquareBracketEnd -> TODO()
|
||||||
|
SquareBracketStart -> TODO()
|
||||||
|
is Strike -> TODO()
|
||||||
|
is Text -> plainText(token, iterator)
|
||||||
|
is Url -> TODO()
|
||||||
|
is UrlTitle -> TODO()
|
||||||
|
is Whitespace -> TODO()
|
||||||
|
else -> TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
return mutableListOf(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun plainText(token: Text, iterator: PeekableTokenIterator): PlainText {
|
||||||
|
return PlainText(token.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun asterisk(token: Asterisk, iterator: PeekableTokenIterator): InlineNode {
|
||||||
|
var count = token.count
|
||||||
|
var node: InlineNode? = null
|
||||||
|
while ((count > 0)) {
|
||||||
|
if (count == 3) {
|
||||||
|
val italicBold = italic(token, iterator, 3)
|
||||||
|
if (italicBold != null) {
|
||||||
|
return italicBold
|
||||||
|
}
|
||||||
|
count--
|
||||||
|
}
|
||||||
|
if (count == 2) {
|
||||||
|
val italicBold = italic(token, iterator, 2)
|
||||||
|
if (italicBold != null) {
|
||||||
|
if (node == null) {
|
||||||
|
node = italicBold
|
||||||
|
count = 1
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
when (node) {
|
||||||
|
is BoldNode -> node.nodes.add(italicBold)
|
||||||
|
is ItalicNode -> node.nodes.add(italicBold)
|
||||||
|
else -> TODO()
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count--
|
||||||
|
}
|
||||||
|
if (count == 1) {
|
||||||
|
val italicBold = italic(token, iterator, 1)
|
||||||
|
if (italicBold != null) {
|
||||||
|
if (node == null) {
|
||||||
|
node = italicBold
|
||||||
|
count = 2
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
when (node) {
|
||||||
|
is BoldNode -> node.nodes.add(italicBold)
|
||||||
|
is ItalicNode -> node.nodes.add(italicBold)
|
||||||
|
else -> TODO()
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun italic(token: Asterisk, iterator: PeekableTokenIterator, count: Int): InlineNode? {
|
||||||
|
println("italic $count")
|
||||||
|
iterator.print()
|
||||||
|
var counter = 0
|
||||||
|
val tokens = mutableListOf<Token>()
|
||||||
|
while (iterator.peekOrNull(counter) != null &&
|
||||||
|
iterator.peekOrNull(counter) !is Break &&
|
||||||
|
iterator.peekOrNull(counter) !is Asterisk
|
||||||
|
) {
|
||||||
|
tokens.add(iterator.peekOrNull(counter)!!)
|
||||||
|
println(tokens)
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
if (iterator.peekOrNull(counter) != null &&
|
||||||
|
(iterator.peekOrNull(counter) is Asterisk &&
|
||||||
|
(iterator.peekOrNull(counter) as Asterisk).count == count)
|
||||||
|
) {
|
||||||
|
println("italic found!!! $count")
|
||||||
|
iterator.skip(counter + 1)
|
||||||
|
val inline = inline(tokens.first(), PeekableTokenIterator(tokens))
|
||||||
|
|
||||||
|
return when (count) {
|
||||||
|
1 -> ItalicNode(inline)
|
||||||
|
2 -> BoldNode(inline)
|
||||||
|
3 -> ItalicNode(mutableListOf(BoldNode(inline)))
|
||||||
|
else -> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
println("return null")
|
||||||
|
iterator.print()
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -35,4 +35,28 @@ class PeekableStringIterator(private val list: List<String>) : Iterator<String>
|
||||||
fun peekOrNull(): String? = list.getOrNull(index)
|
fun peekOrNull(): String? = list.getOrNull(index)
|
||||||
|
|
||||||
fun current(): Int = index
|
fun current(): Int = index
|
||||||
|
}
|
||||||
|
|
||||||
|
class PeekableTokenIterator(private val tokens: List<Token>) : Iterator<Token> {
|
||||||
|
private var index = 0
|
||||||
|
override fun hasNext(): Boolean = index < tokens.size
|
||||||
|
override fun next(): Token = try {
|
||||||
|
tokens[index++]
|
||||||
|
} catch (e: IndexOutOfBoundsException) {
|
||||||
|
index -= 1; throw NoSuchElementException(e.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun peekOrNull(): Token? = tokens.getOrNull(index)
|
||||||
|
|
||||||
|
fun peekOrNull(offset: Int): Token? = tokens.getOrNull(index + offset)
|
||||||
|
|
||||||
|
fun current(): Int = index
|
||||||
|
fun skip(count: Int = 0) {
|
||||||
|
index += count
|
||||||
|
}
|
||||||
|
|
||||||
|
fun print() {
|
||||||
|
println("token: $tokens\nindex: $index")
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -128,6 +128,41 @@ class LexerTest {
|
||||||
assertContentEquals(listOf(Header(1), Text("#a")), actual)
|
assertContentEquals(listOf(Header(1), Text("#a")), actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun ヘッダー後の改行() {
|
||||||
|
val lexer = Lexer()
|
||||||
|
|
||||||
|
val actual = lexer.lex("# a\n# b")
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
|
||||||
|
assertContentEquals(
|
||||||
|
listOf(
|
||||||
|
Header(1),
|
||||||
|
Text("a"),
|
||||||
|
Break(1),
|
||||||
|
Header(1),
|
||||||
|
Text("b")
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun ヘッダー複数() {
|
||||||
|
val lexer = Lexer()
|
||||||
|
|
||||||
|
val actual = lexer.lex("# a a a")
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
|
||||||
|
assertContentEquals(
|
||||||
|
listOf(
|
||||||
|
Header(1),
|
||||||
|
Text("a a a"),
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun 引用() {
|
fun 引用() {
|
||||||
val lexer = Lexer()
|
val lexer = Lexer()
|
||||||
|
@ -507,6 +542,25 @@ class LexerTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun アスタリスク複数2() {
|
||||||
|
val lexer = Lexer()
|
||||||
|
|
||||||
|
val actual = lexer.lex("***a**b*")
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
|
||||||
|
assertContentEquals(
|
||||||
|
listOf(
|
||||||
|
Asterisk(3, '*'),
|
||||||
|
Text("a"),
|
||||||
|
Asterisk(2, '*'),
|
||||||
|
Text("b"),
|
||||||
|
Asterisk(1, '*'),
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun アンダーバー() {
|
fun アンダーバー() {
|
||||||
val lexer = Lexer()
|
val lexer = Lexer()
|
||||||
|
|
|
@ -0,0 +1,252 @@
|
||||||
|
package dev.usbharu.markdown
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class ParserTest {
|
||||||
|
@Test
|
||||||
|
fun header() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(listOf(Header(1), Text("a b c")))
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
HeaderNode(1, HeaderTextNode("a b c"))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun header複数() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(listOf(Header(1), Text("a b c"), Break(1), Header(2), Text("d e f")))
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
HeaderNode(1, HeaderTextNode("a b c")),
|
||||||
|
HeaderNode(2, HeaderTextNode("d e f")),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun asterisk() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(listOf(Asterisk(1, '*'), Text("a"), Asterisk(1, '*')))
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
ParagraphNode(listOf(ItalicNode(mutableListOf(PlainText("a")))))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun asterisk2() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.asterisk(
|
||||||
|
Asterisk(1, '*'), PeekableTokenIterator(listOf(Text("a"), Asterisk(1, '*')))
|
||||||
|
)
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun bold() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(listOf(Asterisk(2, '*'), Text("a"), Asterisk(2, '*')))
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
ParagraphNode(listOf(BoldNode(mutableListOf(PlainText("a")))))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun italicBold() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(listOf(Asterisk(3, '*'), Text("a"), Asterisk(3, '*')))
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
ParagraphNode(listOf(ItalicNode(mutableListOf(BoldNode(mutableListOf(PlainText("a")))))))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun italicとbold() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(
|
||||||
|
listOf(
|
||||||
|
Asterisk(3, '*'), Text("a"), Asterisk(2, '*'), Text("b"), Asterisk(1, '*')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
ParagraphNode(
|
||||||
|
listOf(
|
||||||
|
BoldNode(
|
||||||
|
mutableListOf(
|
||||||
|
PlainText("a"), ItalicNode(mutableListOf(PlainText("b")))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun italicとbold2() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(
|
||||||
|
listOf(
|
||||||
|
Asterisk(3, '*'), Text("a"), Asterisk(1, '*'), Text("b"), Asterisk(2, '*')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
ParagraphNode(
|
||||||
|
listOf(
|
||||||
|
ItalicNode(
|
||||||
|
mutableListOf(
|
||||||
|
PlainText("a"), BoldNode(mutableListOf(PlainText("b")))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun plainText() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(
|
||||||
|
listOf(
|
||||||
|
Text("hello")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
ParagraphNode(
|
||||||
|
listOf(
|
||||||
|
PlainText("hello")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun separator() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(listOf(Separator(3, '-')))
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
SeparatorNode
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun separator2() {
|
||||||
|
val parser = Parser()
|
||||||
|
|
||||||
|
val actual = parser.parse(listOf(Separator(3, '-'), Break(1), Separator(3, '-')))
|
||||||
|
|
||||||
|
println(actual)
|
||||||
|
println(actual.print())
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
RootNode(
|
||||||
|
BodyNode(
|
||||||
|
listOf(
|
||||||
|
SeparatorNode,
|
||||||
|
SeparatorNode,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), actual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +0,0 @@
|
||||||
package io.github.kotlin.fibonacci
|
|
||||||
|
|
||||||
actual val firstElement: Int = 3
|
|
||||||
actual val secondElement: Int = 5
|
|
|
@ -1,12 +0,0 @@
|
||||||
package io.github.kotlin.fibonacci
|
|
||||||
|
|
||||||
import kotlin.test.Test
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
|
|
||||||
class LinuxFibiTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test 3rd element`() {
|
|
||||||
assertEquals(8, generateFibi().take(3).last())
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue