vcs: add tests for LineStatusTrackerManager

This commit is contained in:
Aleksey Pivovarov
2018-03-14 16:27:12 +03:00
parent 2a9a45e078
commit 4718fd94b4
7 changed files with 716 additions and 188 deletions
@@ -61,11 +61,10 @@ import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.testFramework.LightVirtualFile
import com.intellij.util.EventDispatcher
import com.intellij.util.concurrency.AppExecutorUtil
import com.intellij.util.concurrency.Semaphore
import com.intellij.util.ui.UIUtil
import com.intellij.vcsUtil.VcsUtil
import org.jetbrains.annotations.CalledInAny
import org.jetbrains.annotations.CalledInAwt
import org.jetbrains.annotations.CalledInBackground
import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.*
import java.nio.charset.Charset
import java.util.*
@@ -956,6 +955,43 @@ class LineStatusTrackerManager(
})
}
}
@TestOnly
fun waitUntilBaseContentsLoaded() {
val semaphore = Semaphore()
semaphore.down()
loader.addAfterUpdateRunnable(Runnable {
semaphore.up()
})
val start = System.currentTimeMillis()
while (true) {
if (ApplicationManager.getApplication().isDispatchThread) {
UIUtil.dispatchAllInvocationEvents()
}
if (semaphore.waitFor(10)) {
return
}
if (System.currentTimeMillis() - start > 2000) {
throw IllegalStateException("Couldn't await base contents")
}
}
}
@TestOnly
fun releaseAllTrackers() {
synchronized(LOCK) {
forcedDocuments.clear()
for (data in trackers.values) {
unregisterTrackerInCLM(data)
data.tracker.release()
}
trackers.clear()
}
}
}
@@ -0,0 +1,261 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vcs
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.editor.Document
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project
import com.intellij.openapi.vcs.BaseLineStatusTrackerTestCase.Companion.parseInput
import com.intellij.openapi.vcs.changes.*
import com.intellij.openapi.vcs.changes.committed.MockAbstractVcs
import com.intellij.openapi.vcs.ex.LineStatusTracker
import com.intellij.openapi.vcs.ex.PartialLocalLineStatusTracker
import com.intellij.openapi.vcs.ex.Range
import com.intellij.openapi.vcs.impl.LineStatusTrackerManager
import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl
import com.intellij.openapi.vcs.impl.projectlevelman.AllVcses
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.testFramework.RunAll
import com.intellij.util.ThrowableRunnable
import com.intellij.vcsUtil.VcsUtil
abstract class BaseLineStatusTrackerManagerTest : LightPlatformTestCase() {
protected lateinit var vcs: MyMockVcs
protected lateinit var changeProvider: MyMockChangeProvider
protected lateinit var clm: ChangeListManagerImpl
protected lateinit var lstm: LineStatusTrackerManager
protected lateinit var dirtyScopeManager: VcsDirtyScopeManagerImpl
protected lateinit var testRoot: VirtualFile
protected lateinit var vcsManager: ProjectLevelVcsManagerImpl
protected var arePartialChangelistsSupported: Boolean = true
override fun setUp() {
super.setUp()
testRoot = runWriteAction {
VfsUtil.markDirtyAndRefresh(false, false, true, ourProject.baseDir)
VfsUtil.createDirectoryIfMissing(ourProject.baseDir, getTestName(true))
}
vcs = MyMockVcs(ourProject)
changeProvider = MyMockChangeProvider()
vcs.changeProvider = changeProvider
clm = ChangeListManagerImpl.getInstanceImpl(ourProject)
lstm = LineStatusTrackerManager.getInstanceImpl(ourProject)
dirtyScopeManager = VcsDirtyScopeManager.getInstance(ourProject) as VcsDirtyScopeManagerImpl
vcsManager = ProjectLevelVcsManager.getInstance(ourProject) as ProjectLevelVcsManagerImpl
vcsManager.registerVcs(vcs)
vcsManager.directoryMappings = listOf(VcsDirectoryMapping(testRoot.path, vcs.name))
vcsManager.waitForInitialized()
assertTrue(vcsManager.hasActiveVcss())
try {
resetTestState()
}
catch (e: Throwable) {
super.tearDown()
throw e
}
}
override fun tearDown() {
RunAll()
.append(ThrowableRunnable { resetChanges() })
.append(ThrowableRunnable { resetChangelists() })
.append(ThrowableRunnable { resetSettings() })
.append(ThrowableRunnable { lstm.releaseAllTrackers() })
.append(ThrowableRunnable { vcsManager.directoryMappings = emptyList() })
.append(ThrowableRunnable { AllVcses.getInstance(ourProject).unregisterManually(vcs) })
.append(ThrowableRunnable { runWriteAction { testRoot.delete(this) } })
.append(ThrowableRunnable { super.tearDown() })
.run()
}
protected fun resetTestState() {
resetChanges()
resetChangelists()
resetSettings()
resetTestRootContent()
}
private fun resetTestRootContent() {
VfsUtil.markDirtyAndRefresh(false, true, true, testRoot)
runWriteAction { testRoot.children.forEach { child -> child.delete(this) } }
}
private fun resetSettings() {
VcsApplicationSettings.getInstance().ENABLE_PARTIAL_CHANGELISTS = true
VcsApplicationSettings.getInstance().SHOW_LST_GUTTER_MARKERS = true
VcsApplicationSettings.getInstance().SHOW_WHITESPACES_IN_LST = true
arePartialChangelistsSupported = true
}
private fun resetChanges() {
changeProvider.changes.clear()
changeProvider.files.clear()
clm.waitUntilRefreshed()
}
private fun resetChangelists() {
clm.addChangeList(LocalChangeList.DEFAULT_NAME, null)
clm.setDefaultChangeList(LocalChangeList.DEFAULT_NAME)
for (changeListName in clm.changeLists.map { it.name }) {
if (changeListName != LocalChangeList.DEFAULT_NAME) clm.removeChangeList(changeListName)
}
clm.waitUntilRefreshed()
}
protected fun addLocalFile(name: String, content: String): VirtualFile {
val file = runWriteAction {
val file = testRoot.createChildData(this, name)
VfsUtil.saveText(file, parseInput(content))
file
}
assertFalse(changeProvider.files.contains(file))
changeProvider.files.add(file)
return file
}
protected fun removeLocalFile(name: String) {
val file = runWriteAction {
val file = VfsUtil.findRelativeFile(testRoot, name)
file!!.delete(this)
file
}
assertTrue(changeProvider.files.contains(file))
changeProvider.files.remove(file)
}
protected fun setBaseVersion(name: String, baseContent: String?) {
val filePath = VcsUtil.getFilePath(testRoot, name)
val contentRevision: ContentRevision? = when (baseContent) {
null -> null
else -> SimpleContentRevision(parseInput(baseContent), filePath, "HEAD")
}
changeProvider.changes[filePath] = contentRevision
}
protected fun removeBaseVersion(name: String) {
val filePath = VcsUtil.getFilePath(testRoot, name)
changeProvider.changes.remove(filePath)
}
protected fun refreshCLM() {
dirtyScopeManager.markEverythingDirty()
clm.scheduleUpdate()
clm.waitUntilRefreshed()
}
protected fun releaseUnneededTrackers() {
runWriteAction { } // LineStatusTrackerManager.MyApplicationListener.afterWriteActionFinished
}
protected val VirtualFile.change: Change? get() = clm.getChange(this)
protected val VirtualFile.tracker: LineStatusTracker<*>? get() = lstm.getLineStatusTracker(this)
protected val VirtualFile.document: Document get() = FileDocumentManager.getInstance().getDocument(this)!!
protected fun VirtualFile.withOpenedEditor(task: () -> Unit) {
lstm.requestTrackerFor(document, this)
try {
task()
}
finally {
lstm.releaseTrackerFor(document, this)
}
}
protected open fun runCommand(task: () -> Unit) {
CommandProcessor.getInstance().executeCommand(getProject(), {
ApplicationManager.getApplication().runWriteAction(task)
}, "", null)
}
protected fun String.asListNameToList(): LocalChangeList = clm.changeLists.find { it.name == this }!!
protected fun String.asListNameToId(): String = asListNameToList().id
protected fun Array<out String>.asListNamesToIds() = this.map { it.asListNameToId() }
private fun changeListsNames() = clm.changeLists.map { it.name }
protected fun PartialLocalLineStatusTracker.assertAffectedChangeLists(vararg expectedNames: String) {
assertSameElements(this.affectedChangeListsIds, expectedNames.asListNamesToIds())
}
protected fun Range.assertChangeList(listName: String) {
val localRange = this as PartialLocalLineStatusTracker.LocalRange
assertEquals(localRange.changelistId, listName.asListNameToId())
}
protected fun createChangelist(listName: String) {
assertDoesntContain(changeListsNames(), listName)
clm.addChangeList(listName, null)
}
protected fun removeChangeList(listName: String) {
assertContainsElements(changeListsNames(), listName)
clm.removeChangeList(listName)
}
protected fun setDefaultChangeList(listName: String) {
clm.setDefaultChangeList(listName)
}
protected fun VirtualFile.moveChanges(fromListName: String, toListName: String) {
assertContainsElements(changeListsNames(), fromListName)
assertContainsElements(changeListsNames(), toListName)
val listChange = fromListName.asListNameToList().changes.find { it == this.change!! }!!
clm.moveChangesTo(toListName.asListNameToList(), listChange)
}
protected fun VirtualFile.moveAllChangesTo(toListName: String) {
assertContainsElements(changeListsNames(), toListName)
clm.moveChangesTo(toListName.asListNameToList(), this.change!!)
}
protected class MyMockChangeProvider : ChangeProvider {
val changes = mutableMapOf<FilePath, ContentRevision?>()
val files = mutableSetOf<VirtualFile>()
override fun getChanges(dirtyScope: VcsDirtyScope,
builder: ChangelistBuilder,
progress: ProgressIndicator,
addGate: ChangeListManagerGate) {
for ((filePath, beforeRevision) in changes) {
val file = files.find { VcsUtil.getFilePath(it) == filePath }
val afterContent: ContentRevision? = when (file) {
null -> null
else -> CurrentContentRevision(filePath)
}
val change = Change(beforeRevision, afterContent)
builder.processChange(change, MockAbstractVcs.getKey())
}
}
override fun isModifiedDocumentTrackingRequired(): Boolean {
return false
}
override fun doCleanup(files: List<VirtualFile>) {
}
}
protected inner class MyMockVcs(project: Project) : MockAbstractVcs(project) {
override fun arePartialChangelistsSupported(): Boolean = arePartialChangelistsSupported
}
}
@@ -20,9 +20,7 @@ import com.intellij.diff.comparison.iterables.DiffIterableUtil.fair
import com.intellij.diff.tools.util.text.LineOffsetsUtil
import com.intellij.diff.util.DiffUtil
import com.intellij.diff.util.Side
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.impl.DocumentImpl
import com.intellij.openapi.fileEditor.FileDocumentManager
@@ -30,29 +28,25 @@ import com.intellij.openapi.fileTypes.PlainTextFileType
import com.intellij.openapi.util.Comparing
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl
import com.intellij.openapi.vcs.changes.LocalChangeList
import com.intellij.openapi.vcs.ex.*
import com.intellij.openapi.vcs.ex.LineStatusTracker.Mode
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.testFramework.LightPlatformTestCase.assertOrderedEquals
import com.intellij.testFramework.LightVirtualFile
import com.intellij.util.containers.ContainerUtil
import java.util.*
private typealias DiffRange = com.intellij.diff.util.Range
abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() {
abstract class BaseLineStatusTrackerTestCase : BaseLineStatusTrackerManagerTest() {
protected fun test(text: String, task: Test.() -> Unit) {
test(text, text, false, task)
}
protected fun test(text: String, vcsText: String, smart: Boolean = false, task: Test.() -> Unit) {
val mode = if (smart) Mode.SMART else Mode.DEFAULT
doTest(text, vcsText,
{ document, file -> SimpleLocalLineStatusTracker.createTracker(getProject(), document, file, mode) },
{ tracker -> Test(tracker) },
task)
resetTestState()
VcsApplicationSettings.getInstance().SHOW_WHITESPACES_IN_LST = smart
arePartialChangelistsSupported = false
doTest(text, vcsText, { tracker -> Test(tracker as SimpleLocalLineStatusTracker) }, task)
}
protected fun testPartial(text: String, task: PartialTest.() -> Unit) {
@@ -60,32 +54,43 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() {
}
protected fun testPartial(text: String, vcsText: String, task: PartialTest.() -> Unit) {
doTest(text, vcsText,
{ document, file -> PartialLocalLineStatusTracker.createTracker(getProject(), document, file, Mode.SMART) },
{ tracker -> PartialTest(tracker) },
task)
resetTestState()
doTest(text, vcsText, { tracker -> PartialTest(tracker as PartialLocalLineStatusTracker) }, task)
}
protected fun <Tracker : LineStatusTracker<*>, TestHelper : Test> doTest(text: String, vcsText: String,
createTracker: (Document, VirtualFile) -> Tracker,
createTestHelper: (Tracker) -> TestHelper,
task: TestHelper.() -> Unit) {
private fun <TestHelper : Test> doTest(text: String, vcsText: String,
createTestHelper: (LineStatusTracker<*>) -> TestHelper,
task: TestHelper.() -> Unit) {
val fileName = "file.txt"
val file = addLocalFile(fileName, parseInput(text))
setBaseVersion(fileName, parseInput(vcsText))
refreshCLM()
file.withOpenedEditor {
lstm.waitUntilBaseContentsLoaded()
val testHelper = createTestHelper(file.tracker!!)
testHelper.verify()
task(testHelper)
testHelper.verify()
}
}
protected fun lightTest(text: String, vcsText: String, smart: Boolean = false, task: Test.() -> Unit) {
val file = LightVirtualFile("LSTTestFile", PlainTextFileType.INSTANCE, parseInput(text))
val document = FileDocumentManager.getInstance().getDocument(file)!!
val tracker = runWriteAction {
val tracker = createTracker(document, file)
val tracker = SimpleLocalLineStatusTracker.createTracker(getProject(), document, file, if (smart) Mode.SMART else Mode.DEFAULT)
tracker.setBaseRevision(parseInput(vcsText))
tracker
}
try {
val testHelper = createTestHelper(tracker)
val testHelper = Test(tracker)
testHelper.verify()
task(testHelper)
testHelper.verify()
testHelper.destroy()
}
finally {
tracker.release()
@@ -93,15 +98,12 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() {
}
protected open class Test(val tracker: LineStatusTracker<*>) {
protected open inner class Test(val tracker: LineStatusTracker<*>) {
val file: VirtualFile = tracker.virtualFile
val document: Document = tracker.document
val vcsDocument: Document = tracker.vcsDocument
private val documentTracker = tracker.getDocumentTrackerInTestMode()
open fun destroy() {
}
fun assertHelperContentIs(expected: String, helper: PartialLocalLineStatusTracker.PartialCommitHelper) {
assertEquals(parseInput(expected), helper.content)
}
@@ -129,36 +131,33 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() {
}
fun runCommand(task: () -> Unit) {
CommandProcessor.getInstance().executeCommand(getProject(), {
ApplicationManager.getApplication().runWriteAction(task)
}, "", null)
fun runCommandVerify(task: () -> Unit) {
this@BaseLineStatusTrackerTestCase.runCommand(task)
verify()
}
fun insertAtStart(text: String) {
runCommand { document.insertString(0, parseInput(text)) }
runCommandVerify { document.insertString(0, parseInput(text)) }
}
fun TestRange.insertBefore(text: String) {
runCommand { document.insertString(this.start, parseInput(text)) }
runCommandVerify { document.insertString(this.start, parseInput(text)) }
}
fun TestRange.insertAfter(text: String) {
runCommand { document.insertString(this.end, parseInput(text)) }
runCommandVerify { document.insertString(this.end, parseInput(text)) }
}
fun TestRange.delete() {
runCommand { document.deleteString(this.start, this.end) }
runCommandVerify { document.deleteString(this.start, this.end) }
}
fun TestRange.replace(text: String) {
runCommand { document.replaceString(this.start, this.end, parseInput(text)) }
runCommandVerify { document.replaceString(this.start, this.end, parseInput(text)) }
}
fun replaceWholeText(text: String) {
runCommand { document.replaceString(0, document.textLength, parseInput(text)) }
runCommandVerify { document.replaceString(0, document.textLength, parseInput(text)) }
}
fun stripTrailingSpaces() {
@@ -171,7 +170,7 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() {
}
fun rollbackLines(lines: BitSet) {
runCommand { tracker.rollbackChanges(lines) }
runCommandVerify { tracker.rollbackChanges(lines) }
}
@@ -198,7 +197,7 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() {
operator fun Int.not(): Helper = Helper(this)
operator fun Helper.minus(end: Int): TestRange = TestRange(this.start, end)
class Helper(val start: Int)
inner class Helper(val start: Int)
infix fun String.at(range: TestRange): TestRange {
assertEquals(parseInput(this), range.text)
@@ -273,7 +272,7 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() {
}
fun Range.rollback() {
runCommand {
runCommandVerify {
tracker.rollbackChanges(this)
}
}
@@ -373,68 +372,22 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() {
private fun getCurrentLines(range: Range): List<String> = DiffUtil.getLines(document, range.line1, range.line2)
}
protected class PartialTest(val partialTracker: PartialLocalLineStatusTracker) : Test(partialTracker) {
protected inner class PartialTest(val partialTracker: PartialLocalLineStatusTracker) : Test(partialTracker) {
private val clm = ChangeListManagerImpl.getInstanceImpl(getProject())
init {
resetChangelists()
partialTracker.initChangeTracking(defaultChangeListIds(), changeListIds(), null)
fun assertAffectedChangeLists(vararg expected: String) {
partialTracker.assertAffectedChangeLists(*expected)
}
override fun destroy() {
resetChangelists()
}
private fun resetChangelists() {
clm.addChangeList(LocalChangeList.DEFAULT_NAME, null)
clm.setDefaultChangeList(LocalChangeList.DEFAULT_NAME)
for (changeListName in changeListNames()) {
if (changeListName != LocalChangeList.DEFAULT_NAME) clm.removeChangeList(changeListName)
}
}
fun assertAffectedChangelists(vararg expected: String) {
assertSameElements(partialTracker.affectedChangeListsIds, expected.toListId())
}
fun Range.assertChangelist(list: String) {
val localRange = this as PartialLocalLineStatusTracker.LocalRange
assertEquals(localRange.changelistId, list.toListId())
}
fun createChangelist(list: String) {
assertDoesntContain(changeListNames(), list)
fun createChangeList_SetDefault(list: String) {
clm.addChangeList(list, null)
}
fun removeChangelist(list: String) {
assertContainsElements(changeListNames(), list)
partialTracker.changeListRemoved(list.toListId())
clm.removeChangeList(list)
}
fun setDefaultChangelist(list: String) {
clm.addChangeList(list, null)
partialTracker.defaultListChanged(defaultChangeListIds(), list.toListId())
clm.setDefaultChangeList(list)
}
fun handlePartialCommit(side: Side, list: String): PartialLocalLineStatusTracker.PartialCommitHelper {
return partialTracker.handlePartialCommit(side, listOf(list.toListId()))
}
fun moveChanges(fromList: String, toList: String) {
assertContainsElements(changeListNames(), fromList)
assertContainsElements(changeListNames(), toList)
partialTracker.moveChanges(fromList.toListId(), toList.toListId())
}
fun moveAllChangesTo(toList: String) {
assertContainsElements(changeListNames(), toList)
partialTracker.moveChangesTo(toList.toListId())
return partialTracker.handlePartialCommit(side, listOf(list.asListNameToId()))
}
@@ -447,13 +400,6 @@ abstract class BaseLineStatusTrackerTestCase : LightPlatformTestCase() {
val changeList = clm.addChangeList(list, null)
partialTracker.moveToChangelist(lines, changeList)
}
fun String.toListId(): String = clm.changeLists.find { it.name == this }!!.id
private fun Array<out String>.toListId() = this.map { it.toListId() }
private fun changeListIds() = clm.changeLists.map { it.id }
private fun changeListNames() = clm.changeLists.map { it.name }
private fun defaultChangeListIds() = clm.defaultChangeList.id
}
companion object {
@@ -0,0 +1,285 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vcs
import com.intellij.openapi.vcs.changes.Change
import com.intellij.openapi.vcs.ex.PartialLocalLineStatusTracker
import com.intellij.openapi.vcs.ex.SimpleLocalLineStatusTracker
class LineStatusTrackerManagerTest : BaseLineStatusTrackerManagerTest() {
private val FILE_1 = "file1.txt"
private val FILE_2 = "file2.txt"
fun `test mock changes`() {
setBaseVersion(FILE_1, "oldText")
refreshCLM()
assertEquals(1, clm.allChanges.size)
assertEquals(Change.Type.DELETED, clm.allChanges.first().type)
addLocalFile(FILE_1, "text")
setBaseVersion(FILE_1, null)
refreshCLM()
assertEquals(1, clm.allChanges.size)
assertEquals(Change.Type.NEW, clm.allChanges.first().type)
setBaseVersion(FILE_1, "oldText")
refreshCLM()
assertEquals(1, clm.allChanges.size)
assertEquals(Change.Type.MODIFICATION, clm.allChanges.first().type)
removeLocalFile(FILE_1)
refreshCLM()
assertEquals(1, clm.allChanges.size)
assertEquals(Change.Type.DELETED, clm.allChanges.first().type)
removeBaseVersion(FILE_1)
refreshCLM()
assertEquals(0, clm.allChanges.size)
setBaseVersion(FILE_1, "oldText")
setBaseVersion(FILE_2, "oldText")
refreshCLM()
assertEquals(2, clm.allChanges.size)
}
fun `test partial tracker lifecycle - editor for unchanged file`() {
createChangelist("Test")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
assertNull(file.tracker)
file.withOpenedEditor {
val tracker = file.tracker
assertNotNull(tracker)
assertTrue(tracker is SimpleLocalLineStatusTracker)
}
assertNull(file.tracker)
}
fun `test partial tracker lifecycle - editor for modified file`() {
createChangelist("Test")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
setBaseVersion(FILE_1, "a_b1_c_d1_e")
refreshCLM()
assertNull(file.tracker)
file.withOpenedEditor {
val tracker = file.tracker
assertNotNull(tracker)
assertTrue(tracker is PartialLocalLineStatusTracker)
}
assertNotNull(file.tracker)
lstm.waitUntilBaseContentsLoaded()
assertNull(file.tracker)
file.withOpenedEditor {
val tracker = file.tracker
assertNotNull(tracker)
assertTrue(tracker is PartialLocalLineStatusTracker)
lstm.waitUntilBaseContentsLoaded()
assertNotNull(file.tracker)
}
assertNull(file.tracker)
}
fun `test partial tracker lifecycle - multiple editors`() {
createChangelist("Test")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
setBaseVersion(FILE_1, "a_b1_c_d1_e")
refreshCLM()
assertNull(file.tracker)
val requester1 = Any()
val requester2 = Any()
lstm.requestTrackerFor(file.document, requester1)
assertNotNull(file.tracker)
lstm.waitUntilBaseContentsLoaded()
lstm.requestTrackerFor(file.document, requester2)
assertNotNull(file.tracker)
lstm.releaseTrackerFor(file.document, requester1)
assertNotNull(file.tracker)
lstm.releaseTrackerFor(file.document, requester2)
assertNull(file.tracker)
}
fun `test partial tracker lifecycle - with partial changes without editor`() {
createChangelist("Test")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
setBaseVersion(FILE_1, "a_b1_c_d1_e")
refreshCLM()
assertNull(file.tracker)
file.withOpenedEditor {
val tracker = file.tracker as PartialLocalLineStatusTracker
lstm.waitUntilBaseContentsLoaded()
val ranges = tracker.getRanges()!!
assertEquals(2, ranges.size)
tracker.moveToChangelist(ranges[0], "Test".asListNameToList())
tracker.assertAffectedChangeLists("Default", "Test")
}
assertNotNull(file.tracker)
clm.waitUntilRefreshed()
releaseUnneededTrackers()
assertNotNull(file.tracker)
file.moveAllChangesTo("Test")
clm.waitUntilRefreshed()
releaseUnneededTrackers() // partial tracker is not released immediately after becoming redundant
assertNull(file.tracker)
}
fun `test tracker from non-default changelist`() {
createChangelist("Test")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
setBaseVersion(FILE_1, "a_b1_c_d1_e")
refreshCLM()
file.moveAllChangesTo("Test")
clm.waitUntilRefreshed()
file.withOpenedEditor {
val tracker = file.tracker as PartialLocalLineStatusTracker
lstm.waitUntilBaseContentsLoaded()
tracker.assertAffectedChangeLists("Test")
}
}
fun `test tracker from non-default changelist - modified during initialisation`() {
createChangelist("Test")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
setBaseVersion(FILE_1, "a_b_c_d1_e")
refreshCLM()
file.moveAllChangesTo("Test")
clm.waitUntilRefreshed()
file.withOpenedEditor {
val tracker = file.tracker as PartialLocalLineStatusTracker
runCommand { tracker.document.replaceString(0, 1, "a2") }
lstm.waitUntilBaseContentsLoaded()
tracker.assertAffectedChangeLists("Test", "Default")
}
}
fun `test tracker changes moves`() {
createChangelist("Test #1")
createChangelist("Test #2")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
setBaseVersion(FILE_1, "a_b1_c_d1_e")
refreshCLM()
file.moveAllChangesTo("Test #2")
assertNull(file.tracker)
file.withOpenedEditor {
val tracker = file.tracker as PartialLocalLineStatusTracker
lstm.waitUntilBaseContentsLoaded()
assertEquals(2, tracker.getRanges()!!.size)
tracker.assertAffectedChangeLists("Test #2")
file.moveAllChangesTo("Test #1")
tracker.assertAffectedChangeLists("Test #1")
tracker.moveToChangelist(tracker.getRanges()!![0], "Test #2".asListNameToList())
tracker.assertAffectedChangeLists("Test #1", "Test #2")
file.moveChanges("Test #2", "Default")
tracker.assertAffectedChangeLists("Test #1", "Default")
file.moveAllChangesTo("Test #2")
tracker.assertAffectedChangeLists("Test #2")
}
}
fun `test tracker changes moves - empty tracker`() {
createChangelist("Test #1")
createChangelist("Test #2")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
setBaseVersion(FILE_1, "a_b_c_d_e")
refreshCLM()
file.moveAllChangesTo("Test #2")
file.withOpenedEditor {
val tracker = file.tracker as PartialLocalLineStatusTracker
lstm.waitUntilBaseContentsLoaded()
assertEquals(0, tracker.getRanges()!!.size)
tracker.assertAffectedChangeLists("Test #2")
file.moveAllChangesTo("Test #1")
tracker.assertAffectedChangeLists("Test #1")
file.moveAllChangesTo("Test #2")
tracker.assertAffectedChangeLists("Test #2")
runCommand { tracker.document.replaceString(0, 1, "a2") }
tracker.assertAffectedChangeLists("Default")
}
}
fun `test tracker changes moves - before initialisation`() {
createChangelist("Test")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
setBaseVersion(FILE_1, "a_b_c_d_e")
refreshCLM()
file.moveAllChangesTo("Test")
file.withOpenedEditor {
val tracker = file.tracker as PartialLocalLineStatusTracker
tracker.assertAffectedChangeLists("Test")
runCommand { tracker.document.replaceString(0, 1, "a2") }
tracker.assertAffectedChangeLists("Default", "Test")
runCommand { tracker.document.replaceString(0, 2, "a") }
tracker.assertAffectedChangeLists("Test")
assertFalse(tracker.isOperational())
assertNull(tracker.getRanges())
lstm.waitUntilBaseContentsLoaded()
assertEquals(0, tracker.getRanges()!!.size)
tracker.assertAffectedChangeLists("Test")
}
}
fun `test tracker changes moves - before initialisation 2`() {
createChangelist("Test")
val file = addLocalFile(FILE_1, "a_b_c_d_e")
setBaseVersion(FILE_1, "a_b_c_d_e2")
refreshCLM()
file.moveAllChangesTo("Test")
file.withOpenedEditor {
val tracker = file.tracker as PartialLocalLineStatusTracker
tracker.assertAffectedChangeLists("Test")
runCommand { tracker.document.replaceString(0, 1, "a2") }
tracker.assertAffectedChangeLists("Default", "Test")
assertFalse(tracker.isOperational())
assertNull(tracker.getRanges())
lstm.waitUntilBaseContentsLoaded()
assertEquals(2, tracker.getRanges()!!.size)
tracker.assertAffectedChangeLists("Default", "Test")
}
}
}
@@ -664,12 +664,12 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() {
tracker.doFrozen(Runnable {
assertNull(tracker.getRanges())
runCommand {
runCommandVerify {
document.setText("")
document.setText("Y")
}
runCommand {
runCommandVerify {
document.setText("X\nX\nX\nX")
}
@@ -687,12 +687,12 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() {
tracker.doFrozen(Runnable {
assertNull(tracker.getRanges())
runCommand {
runCommandVerify {
document.setText("")
document.setText("Y")
}
runCommand {
runCommandVerify {
document.setText(parseInput("Y_X_X_X_X"))
}
@@ -711,7 +711,7 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() {
assertNull(tracker.getRanges())
tracker.doFrozen(Runnable {
runCommand {
runCommandVerify {
document.setText("")
document.setText("Y")
}
@@ -720,7 +720,7 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() {
})
assertNull(tracker.getRanges())
runCommand {
runCommandVerify {
document.setText("X\nX\nX\nX")
}
@@ -740,7 +740,7 @@ class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() {
tracker.setBaseRevision(parseInput("X_X_X_Z_Z"))
runCommand {
runCommandVerify {
document.setText(parseInput("Y_X_X_X_X_Z_Z"))
}
@@ -63,13 +63,13 @@ class LineStatusTrackerRevertAutoTest : BaseLineStatusTrackerTestCase() {
if (i % 1000 == 0) LOG.debug(i.toString())
try {
val initial = generateText(textLength)
test(initial, initial, smart) {
lightTest(initial, initial, smart) {
// println("Initial: " + initial.replace("\n", "\\n"));
val count = myRng.nextInt(modifications)
for (j in 0 until count) {
val writeChanges = myRng.nextInt(4) + 1
runCommand {
runCommandVerify {
for (k in 0 until writeChanges) {
applyRandomChange(changeLength)
}
@@ -110,7 +110,7 @@ class LineStatusTrackerRevertAutoTest : BaseLineStatusTrackerTestCase() {
try {
val initial = generateText(textLength)
val initialVcs = generateText(textLength)
test(initial, initialVcs, smart) {
lightTest(initial, initialVcs, smart) {
checkRevert(tracker.getRanges()!!.size * 2)
}
@@ -11,8 +11,8 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
testPartial("1234_2345_3456") {
"12".insertAfter("a")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
}
}
@@ -20,19 +20,19 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
testPartial("1234_2345_3456") {
"12".insertAfter("a")
range().assertChangelist("Default")
range().assertChangeList("Default")
setDefaultChangelist("Test")
createChangeList_SetDefault("Test")
"12".insertBefore("X_Y_Z")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
"3456".replace("X_Y_Z")
range(0).assertChangelist("Default")
range(1).assertChangelist("Test")
assertAffectedChangelists("Default", "Test")
range(0).assertChangeList("Default")
range(1).assertChangeList("Test")
assertAffectedChangeLists("Default", "Test")
}
}
@@ -40,24 +40,24 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
testPartial("1234_2345_3456") {
"12".insertAfter("a")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
setDefaultChangelist("Test")
createChangeList_SetDefault("Test")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
"56".insertAfter("b")
range(0).assertChangelist("Default")
range(1).assertChangelist("Test")
assertAffectedChangelists("Default", "Test")
range(0).assertChangeList("Default")
range(1).assertChangeList("Test")
assertAffectedChangeLists("Default", "Test")
"2345".insertAfter("c")
range().assertChangelist("Test")
assertAffectedChangelists("Test")
range().assertChangeList("Test")
assertAffectedChangeLists("Test")
}
}
@@ -65,24 +65,24 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
testPartial("1234_2345_3456") {
"12".insertAfter("a")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
setDefaultChangelist("Test")
createChangeList_SetDefault("Test")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
"56".insertAfter("b")
range(0).assertChangelist("Default")
range(1).assertChangelist("Test")
assertAffectedChangelists("Default", "Test")
range(0).assertChangeList("Default")
range(1).assertChangeList("Test")
assertAffectedChangeLists("Default", "Test")
"2345_".delete()
range().assertChangelist("Test")
assertAffectedChangelists("Test")
range().assertChangeList("Test")
assertAffectedChangeLists("Test")
}
}
@@ -90,14 +90,14 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
testPartial("1234_2345_3456") {
"12".insertAfter("a")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
createChangelist("Test")
range().moveTo("Test")
range().assertChangelist("Test")
assertAffectedChangelists("Test")
range().assertChangeList("Test")
assertAffectedChangeLists("Test")
}
}
@@ -105,31 +105,31 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
testPartial("1234_2345_3456") {
"12".insertAfter("a")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
setDefaultChangelist("Test")
createChangeList_SetDefault("Test")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
"56".insertAfter("b")
range(0).assertChangelist("Default")
range(1).assertChangelist("Test")
assertAffectedChangelists("Default", "Test")
range(0).assertChangeList("Default")
range(1).assertChangeList("Test")
assertAffectedChangeLists("Default", "Test")
range(0).moveTo("Test")
range(0).assertChangelist("Test")
range(1).assertChangelist("Test")
assertAffectedChangelists("Test")
range(0).assertChangeList("Test")
range(1).assertChangeList("Test")
assertAffectedChangeLists("Test")
range(1).moveTo("Default")
range(0).assertChangelist("Test")
range(1).assertChangelist("Default")
assertAffectedChangelists("Default", "Test")
range(0).assertChangeList("Test")
range(1).assertChangeList("Default")
assertAffectedChangeLists("Default", "Test")
}
}
@@ -137,25 +137,25 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
testPartial("1234_2345_3456") {
"12".insertAfter("a")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
setDefaultChangelist("Test")
createChangeList_SetDefault("Test")
range().assertChangelist("Default")
assertAffectedChangelists("Default")
range().assertChangeList("Default")
assertAffectedChangeLists("Default")
"56".insertAfter("b")
range(0).assertChangelist("Default")
range(1).assertChangelist("Test")
assertAffectedChangelists("Default", "Test")
range(0).assertChangeList("Default")
range(1).assertChangeList("Test")
assertAffectedChangeLists("Default", "Test")
removeChangelist("Default")
removeChangeList("Default")
range(0).assertChangelist("Test")
range(1).assertChangelist("Test")
assertAffectedChangelists("Test")
range(0).assertChangeList("Test")
range(1).assertChangeList("Test")
assertAffectedChangeLists("Test")
}
}
@@ -184,7 +184,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
testPartial("A_ _C_D_E_") {
"A".replace("C_D_E")
setDefaultChangelist("Test")
createChangeList_SetDefault("Test")
(2 th "C_D_E_").delete()
assertTextContentIs("C_D_E_ _")
@@ -203,7 +203,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertTextContentIs("A_B1_C_E_F_M_G_N_H_")
assertBaseTextContentIs("A_B_C_D_E_F_G_H_")
assertAffectedChangelists("Default", "Test")
assertAffectedChangeLists("Default", "Test")
val helper = handlePartialCommit(Side.LEFT, "Test")
helper.applyChanges()
@@ -211,7 +211,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertHelperContentIs("A_B_C_E_F_G_N_H_", helper)
assertTextContentIs("A_B1_C_E_F_M_G_N_H_")
assertBaseTextContentIs("A_B_C_E_F_G_N_H_")
assertAffectedChangelists("Default")
assertAffectedChangeLists("Default")
}
}
@@ -226,7 +226,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertTextContentIs("A_B1_C_E_F_M_G_N_H_")
assertBaseTextContentIs("A_B_C_D_E_F_G_H_")
assertAffectedChangelists("Default", "Test")
assertAffectedChangeLists("Default", "Test")
val helper = handlePartialCommit(Side.LEFT, "Default")
helper.applyChanges()
@@ -234,7 +234,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertHelperContentIs("A_B1_C_D_E_F_M_G_H_", helper)
assertTextContentIs("A_B1_C_E_F_M_G_N_H_")
assertBaseTextContentIs("A_B1_C_D_E_F_M_G_H_")
assertAffectedChangelists("Test")
assertAffectedChangeLists("Test")
}
}
@@ -249,7 +249,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertTextContentIs("A_B1_C_E_F_M_G_N_H_")
assertBaseTextContentIs("A_B_C_D_E_F_G_H_")
assertAffectedChangelists("Default", "Test")
assertAffectedChangeLists("Default", "Test")
val helper = handlePartialCommit(Side.RIGHT, "Test")
helper.applyChanges()
@@ -257,7 +257,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertHelperContentIs("A_B1_C_D_E_F_M_G_H_", helper)
assertTextContentIs("A_B1_C_D_E_F_M_G_H_")
assertBaseTextContentIs("A_B_C_D_E_F_G_H_")
assertAffectedChangelists("Default")
assertAffectedChangeLists("Default")
}
}
@@ -272,10 +272,10 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertTextContentIs("A_B1_C_E_F_M_G_N_H_")
assertBaseTextContentIs("A_B_C_D_E_F_G_H_")
assertAffectedChangelists("Default", "Test")
assertAffectedChangeLists("Default", "Test")
tracker.doFrozen(Runnable {
runCommand {
runCommandVerify {
"B1_".replace("X_Y_Z_")
val helper = handlePartialCommit(Side.LEFT, "Default")
@@ -284,7 +284,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertHelperContentIs("A_X_Y_Z_C_D_E_F_M_G_H_", helper)
assertTextContentIs("A_X_Y_Z_C_E_F_M_G_N_H_")
assertBaseTextContentIs("A_X_Y_Z_C_D_E_F_M_G_H_")
assertAffectedChangelists("Test")
assertAffectedChangeLists("Test")
}
})
}
@@ -301,10 +301,10 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertTextContentIs("A_B1_C_E_F_M_G_N_H_")
assertBaseTextContentIs("A_B_C_D_E_F_G_H_")
assertAffectedChangelists("Default", "Test")
assertAffectedChangeLists("Default", "Test")
tracker.doFrozen(Runnable {
runCommand {
runCommandVerify {
"B1_".replace("X_Y_Z_")
val helper = handlePartialCommit(Side.LEFT, "Default")
@@ -321,7 +321,7 @@ class PartialLineStatusTrackerTest : BaseLineStatusTrackerTestCase() {
assertHelperContentIs("A_X_Y_Z_C_D_E_F_M_G_H_", helper)
assertTextContentIs("A_X_Y_Z_C_E_F_M2_G_N2_H_")
assertBaseTextContentIs("A_X_Y_Z_C_D_E_F_M_G_H_")
assertAffectedChangelists("Test")
assertAffectedChangeLists("Test")
}
})
}