diff --git a/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/BaseEspressoTest.kt b/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/BaseEspressoTest.kt new file mode 100644 index 000000000..a6413a26b --- /dev/null +++ b/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/BaseEspressoTest.kt @@ -0,0 +1,91 @@ +package universe.constellation.orion.viewer.test.espresso + +import android.view.View +import android.widget.SeekBar +import androidx.test.espresso.Espresso +import androidx.test.espresso.UiController +import androidx.test.espresso.ViewAction +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.filters.SdkSuppress +import androidx.test.platform.app.InstrumentationRegistry +import org.hamcrest.Matcher +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.runners.Parameterized +import universe.constellation.orion.viewer.Controller +import universe.constellation.orion.viewer.R +import universe.constellation.orion.viewer.test.framework.BookDescription +import universe.constellation.orion.viewer.test.framework.InstrumentationTestCase + +@SdkSuppress(minSdkVersion = 21) +/*Default zoom is "Fit Width"*/ +open class BaseEspressoTest(val bookDescription: BookDescription) : InstrumentationTestCase(bookDescription.toOpenIntent()) { + + companion object { + @JvmStatic + @Parameterized.Parameters(name = "Zoom test for {0} book") + fun testData(): Iterable> { + return BookDescription.executionEntries().map { arrayOf(it) } + } + } + + private lateinit var controller: Controller + + @Before + fun checkStartInvariant() { + println("BaseInv") + activityScenarioRule.scenario.onActivity { + controller = it.controller!! + Assert.assertEquals(it.controller!!.pageCount, bookDescription.pageCount) + Assert.assertFalse(controller.pageLayoutManager.sceneRect.isEmpty) + } + } + + @After + fun checkEndInvariant() { + activityScenarioRule.scenario.onActivity { + Assert.assertEquals(it.controller!!, controller) + } + } + + + protected fun applyZoom() { + Espresso.onView(ViewMatchers.withId(R.id.zoom_preview)).perform(ViewActions.click()) + Espresso.onView(ViewMatchers.withId(R.id.zoom_picker_close)).perform(ViewActions.click()) + } + + protected fun applyGoTo() { + Espresso.onView(ViewMatchers.withId(R.id.page_preview)).perform(ViewActions.click()) + Espresso.onView(ViewMatchers.withId(R.id.page_picker_close)).perform(ViewActions.click()) + } + + protected fun openZoom() { + Espresso.openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getInstrumentation().targetContext) + Espresso.onView(ViewMatchers.withText("Zoom")).perform(ViewActions.click()) + } + + protected fun openGoTo() { + Espresso.openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getInstrumentation().targetContext) + Espresso.onView(ViewMatchers.withText("Go To")).perform(ViewActions.click()) + } +} + +internal fun setSeekBarProgress(transform: (Int) -> Int): ViewAction { + return object : ViewAction { + override fun perform(uiController: UiController?, view: View) { + val seekBar = view as SeekBar + val transform1 = transform(seekBar.progress) + seekBar.progress = transform1 + } + + override fun getDescription(): String { + return "Set a progress on a SeekBar" + } + + override fun getConstraints(): Matcher { + return ViewMatchers.isAssignableFrom(SeekBar::class.java) + } + } +} \ No newline at end of file diff --git a/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/ScrollTest.kt b/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/ScrollTest.kt index 6aa92e8dc..fc8eeafab 100644 --- a/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/ScrollTest.kt +++ b/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/ScrollTest.kt @@ -4,9 +4,13 @@ import androidx.test.espresso.Espresso.* import androidx.test.espresso.action.ViewActions.* import androidx.test.espresso.matcher.ViewMatchers.withId import org.hamcrest.Matchers.* +import org.junit.After +import org.junit.Assert +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized +import universe.constellation.orion.viewer.Controller import universe.constellation.orion.viewer.R import universe.constellation.orion.viewer.test.framework.BookDescription @@ -14,19 +18,56 @@ import universe.constellation.orion.viewer.test.framework.BookDescription class ScrollTest(bookDescription: BookDescription): BaseEspressoTest(bookDescription) { @Test - fun testSwipeUpAndDown3() { + fun testSwipeUpAndDownWithZoomIn3() { + testSwipeUpAndDown(0.5f) + } + + @Test + fun testSwipeUpAndDownWithZoomOut3() { testSwipeUpAndDown(3) } @Test - fun testSwipeUpAndDown10() { + fun testSwipeUpAndDownWithZoomOut10() { testSwipeUpAndDown(10) } + @Test + fun testFirstPageSwipeDown() { + openGoTo() + onView(withId(R.id.page_picker_seeker)).perform(setSeekBarProgress { 0 }) + applyGoTo() + onView(withId(R.id.view)).perform(swipeDown()) + activityScenarioRule.scenario.onActivity { + Assert.assertEquals(it.controller!!.pageCount, bookDescription.pageCount) + val first = it.controller!!.pageLayoutManager.visiblePages.first() + Assert.assertEquals(0, first.pageNum) + Assert.assertEquals(0f, first.layoutData.position.y, 0.0f) + } + } + + @Test + fun testLastPageSwipeUp() { + openGoTo() + onView(withId(R.id.page_picker_seeker)).perform(setSeekBarProgress { bookDescription.pageCount - 1 }) + applyGoTo() + onView(withId(R.id.view)).perform(swipeUp()) + + activityScenarioRule.scenario.onActivity { activity -> + val pageLayoutManager = activity.controller!!.pageLayoutManager + val last = pageLayoutManager.visiblePages.last() + Assert.assertEquals(pageLayoutManager.visiblePages.joinToString(" ") {it.pageNum.toString()}, activity.controller!!.pageCount - 1, last.pageNum) + Assert.assertTrue(last.layoutData.globalBottom <= pageLayoutManager.sceneRect.bottom) + } + } private fun testSwipeUpAndDown(downScale: Int) { + testSwipeUpAndDown(downScale.toFloat()) + } + + private fun testSwipeUpAndDown(downScale: Float) { openZoom() - onView(withId(R.id.zoom_picker_seeker)).perform(setSeekBarProgress { it / downScale }) + onView(withId(R.id.zoom_picker_seeker)).perform(setSeekBarProgress { (it / downScale).toInt() }) applyZoom() Thread.sleep(500) onView(withId(R.id.view)).perform(swipeUp()) @@ -37,4 +78,4 @@ class ScrollTest(bookDescription: BookDescription): BaseEspressoTest(bookDescrip Thread.sleep(500) onView(withId(R.id.view)).perform(swipeDown()) } -} \ No newline at end of file +} diff --git a/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/ZoomTest.kt b/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/ZoomTest.kt index 6665c8d3f..d55082f37 100644 --- a/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/ZoomTest.kt +++ b/orion-viewer/src/androidTest/kotlin/universe/constellation/orion/viewer/test/espresso/ZoomTest.kt @@ -8,9 +8,6 @@ import androidx.test.espresso.ViewAction import androidx.test.espresso.action.ViewActions.* import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.matcher.ViewMatchers.withText -import androidx.test.filters.SdkSuppress -import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import org.hamcrest.Matcher import org.hamcrest.Matchers.* import org.junit.Test @@ -18,30 +15,6 @@ import org.junit.runner.RunWith import org.junit.runners.Parameterized import universe.constellation.orion.viewer.R import universe.constellation.orion.viewer.test.framework.BookDescription -import universe.constellation.orion.viewer.test.framework.InstrumentationTestCase - -@SdkSuppress(minSdkVersion = 21) -/*Default zoom is "Fit Width"*/ -open class BaseEspressoTest(bookDescription: BookDescription) : InstrumentationTestCase(bookDescription.toOpenIntent()) { - - companion object { - @JvmStatic - @Parameterized.Parameters(name = "Zoom test for {0} book") - fun testData(): Iterable> { - return BookDescription.executionEntries().map { arrayOf(it) } - } - } - - protected fun applyZoom() { - onView(withId(R.id.zoom_preview)).perform(click()) - onView(withId(R.id.zoom_picker_close)).perform(click()) - } - - protected fun openZoom() { - openActionBarOverflowOrOptionsMenu(getInstrumentation().targetContext) - onView(withText("Zoom")).perform(click()) - } -} @RunWith(Parameterized::class) class ZoomTest(bookDescription: BookDescription): BaseEspressoTest(bookDescription) { @@ -62,22 +35,4 @@ class ZoomTest(bookDescription: BookDescription): BaseEspressoTest(bookDescripti Thread.sleep(1000) onView(withId(R.id.view)).perform(swipeUp()) } -} - -internal fun setSeekBarProgress(transform: (Int) -> Int): ViewAction { - return object : ViewAction { - override fun perform(uiController: UiController?, view: View) { - val seekBar = view as SeekBar - val transform1 = transform(seekBar.progress) - seekBar.progress = transform1 - } - - override fun getDescription(): String { - return "Set a progress on a SeekBar" - } - - override fun getConstraints(): Matcher { - return ViewMatchers.isAssignableFrom(SeekBar::class.java) - } - } } \ No newline at end of file diff --git a/orion-viewer/src/main/java/universe/constellation/orion/viewer/view/PageLayoutManager.kt b/orion-viewer/src/main/java/universe/constellation/orion/viewer/view/PageLayoutManager.kt index 217924b65..ef681a97e 100644 --- a/orion-viewer/src/main/java/universe/constellation/orion/viewer/view/PageLayoutManager.kt +++ b/orion-viewer/src/main/java/universe/constellation/orion/viewer/view/PageLayoutManager.kt @@ -31,20 +31,24 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): var isSinglePageMode = false val sceneRect = Rect(0, 0, scene.width, scene.height) - val tmpRect = Rect(0, 0, scene.width, scene.height) - var sceneWidth: Int - get() = scene.width + + private val tmpRect = Rect(sceneRect) + + private var sceneWidth: Int + get() = sceneRect.width() set(value) { sceneRect.right = value } - var sceneHeight: Int - get() = scene.height + + private var sceneHeight: Int + get() = sceneRect.height() set(value) { sceneRect.bottom = value } override fun onDimensionChanged(newWidth: Int, newHeight: Int) { if (sceneWidth != newWidth && newHeight != sceneHeight) { + log("New scene size: $sceneRect") sceneWidth = newWidth sceneHeight = newHeight updateRenderingParameters() @@ -60,7 +64,7 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): fun forcePageUpdate() { visiblePages.forEach { it.invalidateAndUpdate() - println("Page force update " + it.pageNum) + log("Page force update " + it.pageNum) } } @@ -93,7 +97,7 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): } fun doScroll(xPos: Float, yPos: Float, distanceX: Float, distanceY: Float) { - println("onScroll: $distanceX, $distanceY") + log("onScroll: $distanceX, $distanceY") isSinglePageMode = false doScrollOnly(xPos, yPos, distanceX, distanceY) uploadNewPages() @@ -128,7 +132,7 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): } if (!updateStateAndRender(it)) { iterator.remove() - println("Remove ${it.pageNum}") + log("Remove ${it.pageNum}") } } dump() @@ -163,7 +167,7 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): return } } - println("Before uploadNewPages") + log("Before uploadNewPages") dump() if (visiblePages.isEmpty()) { val nextPageNum = 0 @@ -181,13 +185,13 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): val firstView = visiblePages.first() val pageStart = firstView.layoutData.position.y - println("Check new $pageStart ${firstView.pageNum} ${visiblePages.size}") + log("Check new $pageStart ${firstView.pageNum} ${visiblePages.size}") if (pageStart > 5 && firstView.pageNum > 0) { val newView = controller.createCachePageView(firstView.pageNum - 1) addPageInPosition(newView, 0f, firstView.layoutData.position.y - newView.layoutData.wholePageRect.height() - 2, false) } } - println("After uploadNewPages") + log("After uploadNewPages") dump() } @@ -213,7 +217,7 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): view.renderVisibleAsync() true } else { - println("toInvisible ${view.pageNum}: ${view.layoutData.globalRectInTmp()}") + log("toInvisible ${view.pageNum}: ${view.layoutData.globalRectInTmp()} $sceneRect") view.toInvisibleState() false } @@ -222,7 +226,7 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): fun findPageAndPageRect(screenRect: Rect): List { return visiblePages.mapNotNull { val visibleOnScreenPart = it.layoutData.occupiedScreenPartInTmp(screenRect) ?: return@mapNotNull null - println("selection: " + it.pageNum + visibleOnScreenPart) + log("selection: " + it.pageNum + visibleOnScreenPart) val pageSelection = Rect(visibleOnScreenPart) //TODO zoom and crop pageSelection.minusOffset(it.layoutData.position) @@ -233,7 +237,7 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): (pageSelection.top/zoom).toInt(), (pageSelection.right/zoom).toInt(), (pageSelection.bottom/zoom).toInt() ) - println("selection: " + it.pageNum + pageSelection) + log("selection: " + it.pageNum + pageSelection) PageAndSelection(it.pageNum, pageSelection) } } @@ -268,7 +272,7 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): private fun dump() { visiblePages.forEach{ - println("Dump ${it.pageNum}: ${it.layoutData.position} ${it.layoutData.wholePageRect}") + log("Dump ${it.pageNum}: ${it.layoutData.position} ${it.layoutData.wholePageRect}") } visiblePages.zipWithNext().forEach { @@ -302,7 +306,7 @@ class PageLayoutManager(val controller: Controller, val scene: OrionDrawScene): updatedView.layoutData.wholePageRect.set(updatedView.wholePageRect) dump() } else { - println("invisible $oldArea") + log("invisible $oldArea") visiblePages.remove(updatedView) } }