Add test to ambient mode

This commit is contained in:
Lucas Lima 2020-03-08 13:41:18 -03:00
parent fb4a439f43
commit 149c4f6146
32 changed files with 233 additions and 49 deletions

View file

@ -9,6 +9,7 @@ import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.data.Area
import dev.lucasnlm.antimine.common.level.data.LevelSetup
import dev.lucasnlm.antimine.common.level.data.Mark
import dev.lucasnlm.antimine.common.level.model.AreaPalette
import dev.lucasnlm.antimine.common.level.repository.DrawableRepository
import dev.lucasnlm.antimine.common.level.view.AreaPaintSettings
import dev.lucasnlm.antimine.common.level.view.paintOnCanvas
@ -40,6 +41,7 @@ class ShareBuilder(
val padding = 1f
val radius = 2f
val areaPalette = AreaPalette.fromLightTheme()
val drawableRepository = DrawableRepository()
val paintSettings = AreaPaintSettings(
@ -79,7 +81,8 @@ class ShareBuilder(
drawableRepository = drawableRepository,
paintSettings = paintSettings,
markPadding = 6,
minePadding = 1
minePadding = 1,
areaPalette = areaPalette
)
canvas.restore()
}

View file

@ -8,6 +8,7 @@ import android.graphics.Paint
import androidx.test.platform.app.InstrumentationRegistry
import dev.lucasnlm.antimine.common.level.data.Area
import dev.lucasnlm.antimine.common.level.data.Mark
import dev.lucasnlm.antimine.common.level.model.AreaPalette
import dev.lucasnlm.antimine.common.level.repository.DrawableRepository
import dev.lucasnlm.antimine.common.level.view.AreaAdapter
import dev.lucasnlm.antimine.common.level.view.paintOnCanvas
@ -20,11 +21,11 @@ import java.io.FileOutputStream
class AreaScreenshot {
private lateinit var instrumentationContext: Context
private lateinit var context: Context
private fun saveImage(area: Area, fileName: String): File {
private fun saveImage(area: Area, fileName: String, ambientMode: Boolean): File {
val drawableRepository = DrawableRepository()
val paintSettings = AreaAdapter.createAreaPaintSettings(instrumentationContext, false)
val paintSettings = AreaAdapter.createAreaPaintSettings(context, false)
val size = paintSettings.rectF.width().toInt()
val testPadding = 4
val bitmap = Bitmap.createBitmap(size + testPadding, size + testPadding, Bitmap.Config.ARGB_8888)
@ -37,25 +38,26 @@ class AreaScreenshot {
size.toFloat() + testPadding,
size.toFloat() + testPadding,
Paint().apply {
color = Color.WHITE
color = if (ambientMode) Color.BLACK else Color.WHITE
style = Paint.Style.FILL
})
canvas.save()
canvas.translate(testPadding * 0.5f, testPadding.toFloat() * 0.5f)
area.paintOnCanvas(
instrumentationContext,
context,
canvas,
isAmbientMode = false,
isAmbientMode = ambientMode,
isLowBitAmbient = false,
isFocused = false,
drawableRepository = drawableRepository,
paintSettings = paintSettings
paintSettings = paintSettings,
areaPalette = if (ambientMode) AreaPalette.fromContrast(context) else AreaPalette.fromLightTheme()
)
canvas.restore()
val file = File(instrumentationContext.filesDir, fileName)
bitmap.compress(Bitmap.CompressFormat.PNG, 95, FileOutputStream(file))
val file = File(context.filesDir, fileName)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, FileOutputStream(file))
return file
}
@ -75,14 +77,14 @@ class AreaScreenshot {
return result
}
private fun screenshotTest(area: Area, fileName: String) {
val current = saveImage(area, fileName)
private fun screenshotTest(area: Area, fileName: String, ambientMode: Boolean = false) {
val current = saveImage(area, fileName, ambientMode)
assertTrue("$fileName doesn't match the reference", compareScreenshot(current, fileName))
}
@Before
fun setup() {
instrumentationContext = InstrumentationRegistry.getInstrumentation().context
context = InstrumentationRegistry.getInstrumentation().context
}
@Test
@ -91,12 +93,25 @@ class AreaScreenshot {
screenshotTest(area, "covered.png")
}
@Test
fun testCoveredAreaAmbientMode() {
val area = Area(0, 0, 0, isCovered = true)
screenshotTest(area, "covered_ambient.png", true)
}
@Test
fun testUncoveredArea() {
val area = Area(0, 0, 0, isCovered = false)
screenshotTest(area, "uncovered.png")
}
@Test
fun testUncoveredAreaAmbientMode() {
val area = Area(0, 0, 0, isCovered = false)
screenshotTest(area, "uncovered_ambient.png", ambientMode = true)
}
@Test
fun testUncoveredAreaWithTips() {
repeat(8) {
@ -108,48 +123,103 @@ class AreaScreenshot {
}
}
@Test
fun testUncoveredAreaWithTipsAmbientMode() {
repeat(8) {
val id = it + 1
screenshotTest(
Area(0, 0, 0, isCovered = false, minesAround = id),
"mines_around_${id}_ambient.png",
true
)
}
}
@Test
fun testCoveredAreaWithFlag() {
val area = Area(0, 0, 0, isCovered = true, mark = Mark.Flag)
screenshotTest(area, "covered_flag.png")
}
@Test
fun testCoveredAreaWithFlagAmbient() {
val area = Area(0, 0, 0, isCovered = true, mark = Mark.Flag)
screenshotTest(area, "covered_flag_ambient.png", true)
}
@Test
fun testCoveredAreaWithQuestion() {
val area = Area(0, 0, 0, isCovered = true, mark = Mark.Question)
screenshotTest(area, "covered_question.png")
}
@Test
fun testCoveredAreaWithQuestionAmbient() {
val area = Area(0, 0, 0, isCovered = true, mark = Mark.Question)
screenshotTest(area, "covered_question_ambient.png", true)
}
@Test
fun testCoveredAreaHighlighted() {
val area = Area(0, 0, 0, isCovered = true, highlighted = true)
screenshotTest(area, "covered_highlighted.png")
}
@Test
fun testCoveredAreaHighlightedAmbient() {
val area = Area(0, 0, 0, isCovered = true, highlighted = true)
screenshotTest(area, "covered_highlighted_ambient.png", true)
}
@Test
fun testCoveredAreaWithMine() {
val area = Area(0, 0, 0, isCovered = true, hasMine = true)
screenshotTest(area, "covered_mine.png")
}
@Test
fun testCoveredAreaWithMineAmbient() {
val area = Area(0, 0, 0, isCovered = true, hasMine = true)
screenshotTest(area, "covered_mine_ambient.png", true)
}
@Test
fun testUncoveredAreaWithMine() {
val area = Area(0, 0, 0, isCovered = false, hasMine = true)
screenshotTest(area, "uncovered_mine.png")
}
@Test
fun testUncoveredAreaWithMineAmbient() {
val area = Area(0, 0, 0, isCovered = false, hasMine = true)
screenshotTest(area, "uncovered_mine_ambient.png", true)
}
@Test
fun testUncoveredAreaHighlighted() {
val area = Area(0, 0, 0, isCovered = false, hasMine = false, highlighted = true)
screenshotTest(area, "uncovered_highlighted.png")
}
@Test
fun testUncoveredAreaHighlightedAmbient() {
val area = Area(0, 0, 0, isCovered = false, hasMine = false, highlighted = true)
screenshotTest(area, "uncovered_highlighted_ambient.png", true)
}
@Test
fun testUncoveredAreaWithMineExploded() {
val area = Area(0, 0, 0, isCovered = false, hasMine = true, mistake = true)
screenshotTest(area, "uncovered_mine_exploded.png")
}
@Test
fun testUncoveredAreaWithMineExplodedAmbient() {
val area = Area(0, 0, 0, isCovered = false, hasMine = true, mistake = true)
screenshotTest(area, "uncovered_mine_exploded_ambient.png", true)
}
@Test
fun testUncoveredAreaWithTipsHighlighted() {
repeat(8) {
@ -160,4 +230,16 @@ class AreaScreenshot {
)
}
}
@Test
fun testUncoveredAreaWithTipsHighlightedAmbient() {
repeat(8) {
val id = it + 1
screenshotTest(
Area(0, 0, 0, isCovered = false, minesAround = id, highlighted = true),
"mines_around_highlighted_${id}_ambient.png",
true
)
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -0,0 +1,85 @@
package dev.lucasnlm.antimine.common.level.model
import android.content.Context
import android.graphics.Color
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import dev.lucasnlm.antimine.common.R
data class AreaPalette(
@ColorInt val border: Int,
@ColorInt val covered: Int,
@ColorInt val uncovered: Int,
@ColorInt val minesAround1: Int,
@ColorInt val minesAround2: Int,
@ColorInt val minesAround3: Int,
@ColorInt val minesAround4: Int,
@ColorInt val minesAround5: Int,
@ColorInt val minesAround6: Int,
@ColorInt val minesAround7: Int,
@ColorInt val minesAround8: Int,
@ColorInt val highlight: Int,
@ColorInt val focus: Int
) {
companion object {
private fun toArgb(color: Int): Int {
return Color.argb(
0xFF,
Color.red(color),
Color.green(color),
Color.blue(color)
)
}
fun fromLightTheme() =
AreaPalette(
border = toArgb(0x424242),
covered = toArgb(0x424242),
uncovered = toArgb(0xd5d2cc),
minesAround1 = toArgb(0x527F8D),
minesAround2 = toArgb(0x2B8D43),
minesAround3 = toArgb(0xE65100),
minesAround4 = toArgb(0x20A5f7),
minesAround5 = toArgb(0xED1C24),
minesAround6 = toArgb(0xFFC107),
minesAround7 = toArgb(0x66126B),
minesAround8 = toArgb(0x000000),
highlight = toArgb(0x212121),
focus = toArgb(0xD32F2F)
)
fun fromDefault(context: Context) =
AreaPalette(
border = ContextCompat.getColor(context, R.color.view_cover),
covered = ContextCompat.getColor(context, R.color.view_cover),
uncovered = ContextCompat.getColor(context, R.color.view_clean),
minesAround1 = ContextCompat.getColor(context, R.color.mines_around_1),
minesAround2 = ContextCompat.getColor(context, R.color.mines_around_2),
minesAround3 = ContextCompat.getColor(context, R.color.mines_around_3),
minesAround4 = ContextCompat.getColor(context, R.color.mines_around_4),
minesAround5 = ContextCompat.getColor(context, R.color.mines_around_5),
minesAround6 = ContextCompat.getColor(context, R.color.mines_around_6),
minesAround7 = ContextCompat.getColor(context, R.color.mines_around_7),
minesAround8 = ContextCompat.getColor(context, R.color.mines_around_8),
highlight = ContextCompat.getColor(context, R.color.highlight),
focus = ContextCompat.getColor(context, R.color.accent)
)
fun fromContrast(context: Context) =
AreaPalette(
border = ContextCompat.getColor(context, android.R.color.white),
covered = ContextCompat.getColor(context, android.R.color.black),
uncovered = ContextCompat.getColor(context, android.R.color.black),
minesAround1 = ContextCompat.getColor(context, R.color.white),
minesAround2 = ContextCompat.getColor(context, R.color.white),
minesAround3 = ContextCompat.getColor(context, R.color.white),
minesAround4 = ContextCompat.getColor(context, R.color.white),
minesAround5 = ContextCompat.getColor(context, R.color.white),
minesAround6 = ContextCompat.getColor(context, R.color.white),
minesAround7 = ContextCompat.getColor(context, R.color.white),
minesAround8 = ContextCompat.getColor(context, R.color.white),
highlight = ContextCompat.getColor(context, R.color.white),
focus = ContextCompat.getColor(context, R.color.white)
)
}
}

View file

@ -4,10 +4,10 @@ import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import androidx.core.content.ContextCompat
import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.common.level.data.Area
import dev.lucasnlm.antimine.common.level.data.Mark
import dev.lucasnlm.antimine.common.level.model.AreaPalette
import dev.lucasnlm.antimine.common.level.repository.DrawableRepository
fun Area.paintOnCanvas(context: Context,
@ -17,6 +17,7 @@ fun Area.paintOnCanvas(context: Context,
isFocused: Boolean,
drawableRepository: DrawableRepository,
paintSettings: AreaPaintSettings,
areaPalette: AreaPalette,
markPadding: Int? = null,
minePadding: Int? = null
) {
@ -27,13 +28,13 @@ fun Area.paintOnCanvas(context: Context,
style = Paint.Style.STROKE
strokeWidth = 2.0f
isAntiAlias = !isLowBitAmbient
color = ContextCompat.getColor(context, android.R.color.white)
color = areaPalette.border
}
} else {
painter.apply {
style = Paint.Style.FILL
isAntiAlias = !isLowBitAmbient
color = ContextCompat.getColor(context, R.color.view_cover)
color = areaPalette.covered
alpha = if(highlighted) 155 else 255
}
}
@ -79,13 +80,13 @@ fun Area.paintOnCanvas(context: Context,
style = Paint.Style.STROKE
strokeWidth = 0.5f
isAntiAlias = !isLowBitAmbient
color = ContextCompat.getColor(context, android.R.color.white)
color = areaPalette.border
}
} else {
painter.apply {
style = Paint.Style.FILL
isAntiAlias = !isLowBitAmbient
color = ContextCompat.getColor(context, R.color.view_clean)
color = areaPalette.uncovered
}
}
@ -110,22 +111,16 @@ fun Area.paintOnCanvas(context: Context,
)
mine?.draw(canvas)
} else if (minesAround > 0) {
val color = if (isAmbientMode) {
R.color.ambient_color_white
} else {
when (minesAround) {
1 -> R.color.mines_around_1
2 -> R.color.mines_around_2
3 -> R.color.mines_around_3
4 -> R.color.mines_around_4
5 -> R.color.mines_around_5
6 -> R.color.mines_around_6
7 -> R.color.mines_around_7
else -> R.color.mines_around_8
}
painter.color = when (minesAround) {
1 -> areaPalette.minesAround1
2 -> areaPalette.minesAround2
3 -> areaPalette.minesAround3
4 -> areaPalette.minesAround4
5 -> areaPalette.minesAround5
6 -> areaPalette.minesAround6
7 -> areaPalette.minesAround7
else -> areaPalette.minesAround8
}
painter.color = ContextCompat.getColor(context, color)
drawText(canvas, painter, minesAround.toString(), paintSettings)
}
@ -137,11 +132,7 @@ fun Area.paintOnCanvas(context: Context,
style = Paint.Style.STROKE
strokeWidth = highlightWidth
isAntiAlias = !isLowBitAmbient
color = if (isAmbientMode) {
ContextCompat.getColor(context, R.color.white)
} else {
ContextCompat.getColor(context, R.color.highlight)
}
color = areaPalette.highlight
val rect = RectF(
rectF.left + halfWidth,
@ -163,7 +154,7 @@ fun Area.paintOnCanvas(context: Context,
style = Paint.Style.STROKE
strokeWidth = highlightWidth
isAntiAlias = !isLowBitAmbient
color = ContextCompat.getColor(context, R.color.accent)
color = areaPalette.focus
}
val rect = RectF(

View file

@ -14,6 +14,7 @@ import android.os.Build
import androidx.core.view.ViewCompat
import dev.lucasnlm.antimine.common.R
import dev.lucasnlm.antimine.common.level.data.Mark
import dev.lucasnlm.antimine.common.level.model.AreaPalette
class AreaView : View {
// Used on Wear OS
@ -22,6 +23,7 @@ class AreaView : View {
private var area: Area? = null
private lateinit var paintSettings: AreaPaintSettings
private lateinit var palette: AreaPalette
private val drawableRepository = DrawableRepository()
constructor(context: Context)
@ -45,6 +47,12 @@ class AreaView : View {
).firstOrNull { it } ?: false
if (changed) {
this.palette = if (isAmbientMode) {
AreaPalette.fromContrast(context)
} else {
AreaPalette.fromDefault(context)
}
this.isAmbientMode = isAmbientMode
this.isLowBitAmbient = isLowBitAmbient
@ -97,7 +105,16 @@ class AreaView : View {
setBackgroundResource(android.R.color.transparent)
}
area?.paintOnCanvas(context, canvas, isAmbientMode, isLowBitAmbient, isFocused, drawableRepository, paintSettings)
area?.paintOnCanvas(
context,
canvas,
isAmbientMode,
isLowBitAmbient,
isFocused,
drawableRepository,
paintSettings,
palette
)
}
private fun getRippleEffect(context: Context): Drawable? {

View file

@ -151,8 +151,6 @@ class WatchGameActivity : DaggerAppCompatActivity(), AmbientModeSupport.AmbientC
private fun onGameEvent(event: GameEvent) {
when (event) {
GameEvent.ResumeGame -> {
}
GameEvent.StartNewGame -> {
gameStatus = GameStatus.PreGame
}
@ -160,13 +158,13 @@ class WatchGameActivity : DaggerAppCompatActivity(), AmbientModeSupport.AmbientC
gameStatus = GameStatus.Running
}
GameEvent.Victory -> {
gameStatus = GameStatus.Over
gameStatus = GameStatus.Over()
messageText.text = getString(R.string.victory)
waitAndShowNewGameButton()
}
GameEvent.GameOver -> {
gameStatus = GameStatus.Over
gameStatus = GameStatus.Over()
viewModel.stopClock()
viewModel.gameOver()
@ -174,21 +172,23 @@ class WatchGameActivity : DaggerAppCompatActivity(), AmbientModeSupport.AmbientC
waitAndShowNewGameButton()
}
GameEvent.ResumeVictory -> {
gameStatus = GameStatus.Over
gameStatus = GameStatus.Over()
messageText.text = getString(R.string.victory)
waitAndShowNewGameButton(0L)
}
GameEvent.ResumeGameOver -> {
gameStatus = GameStatus.Over
gameStatus = GameStatus.Over()
messageText.text = getString(R.string.game_over)
waitAndShowNewGameButton(0L)
}
else -> {
}
}
}
private fun waitAndShowNewGameButton() {
private fun waitAndShowNewGameButton(wait: Long = DateUtils.SECOND_IN_MILLIS) {
HandlerCompat.postDelayed(Handler(), {
if (this.gameStatus == GameStatus.Over && !isFinishing) {
if (this.gameStatus is GameStatus.Over && !isFinishing) {
newGame.visibility = View.VISIBLE
newGame.setOnClickListener {
it.visibility = View.GONE
@ -197,7 +197,7 @@ class WatchGameActivity : DaggerAppCompatActivity(), AmbientModeSupport.AmbientC
}
}
}
}, null, DateUtils.SECOND_IN_MILLIS)
}, null, wait)
}
override fun getAmbientCallback(): AmbientCallback = ambientMode

View file

@ -101,6 +101,12 @@ class WatchLevelFragment: DaggerFragment() {
if (it == GameEvent.StartNewGame) {
recyclerGrid.scrollToPosition(areaAdapter.itemCount / 2)
}
when (it) {
GameEvent.ResumeGameOver, GameEvent.GameOver,
GameEvent.Victory, GameEvent.ResumeVictory -> areaAdapter.setClickEnabled(false)
else -> areaAdapter.setClickEnabled(true)
}
})
}
}