Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more Tree concurrency tests #195

Merged
merged 1 commit into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ android.suppressUnsupportedOptionWarnings=android.suppressUnsupportedOptionWarni
kotlin.code.style=official
kotlin.mpp.stability.nowarn=true
GROUP=dev.yorkie
VERSION_NAME=0.4.20
VERSION_NAME=0.4.21-rc
POM_DESCRIPTION=Document store for building collaborative editing applications.
POM_INCEPTION_YEAR=2022
POM_URL=https://github.com/yorkie-team/yorkie-android-sdk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import dev.yorkie.TreeTest
import dev.yorkie.core.createClient
import dev.yorkie.document.json.OpCode.EditOpCode
import dev.yorkie.document.json.OpCode.StyleOpCode
import dev.yorkie.document.json.TestOperation.EditOperationType
import dev.yorkie.document.json.TestOperation.StyleOperationType
import dev.yorkie.document.json.TreeBuilder.element
import dev.yorkie.document.json.TreeBuilder.text
import kotlin.test.assertEquals
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith

Expand Down Expand Up @@ -210,6 +212,89 @@ class JsonTreeConcurrencyTest {
}
}

@Test
fun test_concurrent_style_and_style() {
runBlocking {
val root = element("r") {
element("p") {
text { "a" }
}
element("p") {
text { "b" }
}
element("p") {
text { "c" }
}
}
val initialXml = "<r><p>a</p><p>b</p><p>c</p></r>"

val ranges = listOf(
// equal: <p>b</p> - <p>b</p>
makeTwoRanges(Triple(3, -1, 6), Triple(3, -1, 6), "equal"),
// contain: <p>a</p><p>b</p><p>c</p> - <p>b</p>
makeTwoRanges(Triple(0, -1, 9), Triple(3, -1, 6), "contain"),
// intersect: <p>a</p><p>b</p> - <p>b</p><p>c</p>
makeTwoRanges(Triple(0, -1, 6), Triple(3, -1, 9), "intersect"),
// side-by-side: <p>a</p> - <p>b</p>
makeTwoRanges(Triple(0, -1, 3), Triple(3, -1, 6), "side-by-side"),
)

val styleOperations = listOf(
StyleOperationType(
RangeSelector.RangeAll,
StyleOpCode.StyleRemove,
"bold",
"",
"remove-bold",
),
StyleOperationType(
RangeSelector.RangeAll,
StyleOpCode.StyleSet,
"bold",
"aa",
"set-bold-aa",
),
StyleOperationType(
RangeSelector.RangeAll,
StyleOpCode.StyleSet,
"bold",
"bb",
"set-bold-bb",
),
StyleOperationType(
RangeSelector.RangeAll,
StyleOpCode.StyleRemove,
"italic",
"",
"remove-italic",
),
StyleOperationType(
RangeSelector.RangeAll,
StyleOpCode.StyleSet,
"italic",
"aa",
"set-italic-aa",
),
StyleOperationType(
RangeSelector.RangeAll,
StyleOpCode.StyleSet,
"italic",
"bb",
"set-italic-bb",
),
)

runTestConcurrency(
root,
initialXml,
ranges,
styleOperations,
styleOperations,
"concurrently-style-style-test",
)
}
}

@Test
fun test_concurrent_edit_and_style() {
runBlocking {
Expand Down Expand Up @@ -299,14 +384,14 @@ class JsonTreeConcurrencyTest {
val styleOperations = listOf(
StyleOperationType(
RangeSelector.RangeAll,
OpCode.StyleOpCode.StyleRemove,
StyleOpCode.StyleRemove,
"color",
"",
"remove-bold",
),
StyleOperationType(
RangeSelector.RangeAll,
OpCode.StyleOpCode.StyleSet,
StyleOpCode.StyleSet,
"bold",
"aa",
"set-bold-aa",
Expand All @@ -324,6 +409,248 @@ class JsonTreeConcurrencyTest {
}
}

@Ignore("should be resolved after JS SDK implementation")
@Test
fun test_concurrent_split_and_split() {
runBlocking {
val root = element("r") {
element("p") {
element("p") {
element("p") {
element("p") {
text { "abcd" }
}
element("p") {
text { "efgh" }
}
}
element("p") {
text { "ijkl" }
}
}
}
}
val initialXml = "<r><p><p><p><p>abcd</p><p>efgh</p></p><p>ijkl</p></p></p></r>"
val ranges = listOf(
// equal-single-element: <p>abcd</p>
makeTwoRanges(Triple(3, 6, 9), Triple(3, 6, 9), "equal-single"),
// equal-multiple-element: <p>abcd</p><p>efgh</p>
makeTwoRanges(Triple(3, 9, 15), Triple(3, 9, 15), "equal-multiple"),
// A contains B same level: <p>abcd</p><p>efgh</p> - <p>efgh</p>
makeTwoRanges(Triple(3, 9, 15), Triple(9, 12, 15), "A contains B same level"),
// A contains B multiple level: <p><p>abcd</p><p>efgh</p></p><p>ijkl</p> - <p>efgh</p>
makeTwoRanges(Triple(2, 16, 22), Triple(9, 12, 15), "A contains B multiple level"),
// side by side
makeTwoRanges(Triple(3, 6, 9), Triple(9, 12, 15), "B is next to A"),
)

val splitOperations = listOf(
EditOperationType(
RangeSelector.RangeFront,
EditOpCode.SplitUpdate,
null,
1,
"split-front-1",
),
EditOperationType(
RangeSelector.RangeOneQuarter,
EditOpCode.SplitUpdate,
null,
1,
"split-one-quarter-1",
),
EditOperationType(
RangeSelector.RangeThreeQuarter,
EditOpCode.SplitUpdate,
null,
1,
"split-three-quarter-1",
),
EditOperationType(
RangeSelector.RangeBack,
EditOpCode.SplitUpdate,
null,
1,
"split-back-1",
),
EditOperationType(
RangeSelector.RangeFront,
EditOpCode.SplitUpdate,
null,
2,
"split-front-2",
),
EditOperationType(
RangeSelector.RangeOneQuarter,
EditOpCode.SplitUpdate,
null,
2,
"split-one-quarter-2",
),
EditOperationType(
RangeSelector.RangeThreeQuarter,
EditOpCode.SplitUpdate,
null,
2,
"split-three-quarter-2",
),
EditOperationType(
RangeSelector.RangeBack,
EditOpCode.SplitUpdate,
null,
2,
"split-back-2",
),
)

runTestConcurrency(
root,
initialXml,
ranges,
splitOperations,
splitOperations,
"concurrently-split-split-test",
)
}
}

@Ignore("should be resolved after JS SDK implementation")
@Test
fun test_concurrent_split_and_edit() {
runBlocking {
val root = element("r") {
element("p") {
element("p") {
element("p") {
element("p") {
text { "abcd" }
attrs { mapOf("italic" to "a") }
}
element("p") {
text { "efgh" }
attrs { mapOf("italic" to "a") }
}
}
element("p") {
text { "ijkl" }
attrs { mapOf("italic" to "a") }
}
}
}
}
val initialXml =
"""<r><p><p><p italic="a">abcd</p><p italic="a">efgh</p></p>""" +
"""<p italic="a">ijkl</p></p></r>"""
val content = element("i")

val ranges = listOf(
// equal: <p>abcd</p>
makeTwoRanges(Triple(2, 5, 8), Triple(2, 5, 8), "equal"),
// A contains B: <p>abcd</p> - bc
makeTwoRanges(Triple(2, 5, 8), Triple(4, 5, 6), "A contains B"),
// B contains A: <p>abcd</p> - <p>abcd</p><p>efgh</p>
makeTwoRanges(Triple(2, 5, 8), Triple(2, 8, 14), "B contains A"),
// left node(text): <p>abcd</p> - ab
makeTwoRanges(Triple(2, 5, 8), Triple(3, 4, 5), "left node(text)"),
// right node(text): <p>abcd</p> - cd
makeTwoRanges(Triple(2, 5, 8), Triple(5, 6, 7), "right node(text)"),
// left node(element): <p>abcd</p><p>efgh</p> - <p>abcd</p>
makeTwoRanges(Triple(2, 8, 14), Triple(2, 5, 8), "left node(element)"),
// right node(element): <p>abcd</p><p>efgh</p> - <p>efgh</p>
makeTwoRanges(Triple(2, 8, 14), Triple(8, 11, 14), "right node(element)"),
// A -> B: <p>abcd</p> - <p>efgh</p>
makeTwoRanges(Triple(2, 5, 8), Triple(8, 11, 14), "A -> B"),
// B -> A: <p>efgh</p> - <p>abcd</p>
makeTwoRanges(Triple(8, 11, 14), Triple(2, 5, 8), "B -> A"),
)

val splitOperations = listOf(
EditOperationType(
RangeSelector.RangeMiddle,
EditOpCode.SplitUpdate,
null,
1,
"split-1",
),
EditOperationType(
RangeSelector.RangeMiddle,
EditOpCode.SplitUpdate,
null,
2,
"split-2",
),
)

val editOperations = listOf(
EditOperationType(
RangeSelector.RangeFront,
EditOpCode.EditUpdate,
content,
0,
"insertFront",
),
EditOperationType(
RangeSelector.RangeMiddle,
EditOpCode.EditUpdate,
content,
0,
"insertMiddle",
),
EditOperationType(
RangeSelector.RangeBack,
EditOpCode.EditUpdate,
content,
0,
"insertBack",
),
EditOperationType(
RangeSelector.RangeAll,
EditOpCode.EditUpdate,
content,
0,
"replace",
),
EditOperationType(
RangeSelector.RangeAll,
EditOpCode.EditUpdate,
null,
0,
"delete",
),
EditOperationType(
RangeSelector.RangeAll,
EditOpCode.MergeUpdate,
null,
0,
"merge",
),
StyleOperationType(
RangeSelector.RangeAll,
StyleOpCode.StyleSet,
"bold",
"aa",
"style",
),
StyleOperationType(
RangeSelector.RangeAll,
StyleOpCode.StyleRemove,
"italic",
"",
"remove-style",
),
)

runTestConcurrency(
root,
initialXml,
ranges,
splitOperations,
editOperations,
"concurrently-split-edit-test",
)
}
}

companion object {

private suspend fun runTestConcurrency(
Expand Down
Loading