Clean up kotlin code

* static imports
* less nullable types
* format
This commit is contained in:
Quentin Hibon
2021-01-18 16:11:52 +01:00
parent 9d0fbb9ea9
commit dedeb13f46
106 changed files with 982 additions and 1287 deletions

View File

@@ -125,6 +125,7 @@ dependencies {
testImplementation "junit:junit:4.12"
testImplementation "org.mockito:mockito-core:2.28.2"
testImplementation "org.mockito:mockito-inline:2.8.9"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
}
kapt {

View File

@@ -38,19 +38,13 @@ import org.mockito.Mockito.mock
@Module
class TestModule {
@Provides fun ListHabitsBehavior() = mock(ListHabitsBehavior::class.java)
@Provides fun listHabitsBehavior(): ListHabitsBehavior = mock(ListHabitsBehavior::class.java)
}
@ActivityScope
@Component(
modules = arrayOf(
ActivityContextModule::class,
HabitsActivityModule::class,
ListHabitsModule::class,
HabitModule::class,
TestModule::class
),
dependencies = arrayOf(HabitsApplicationComponent::class)
modules = [ActivityContextModule::class, HabitsActivityModule::class, ListHabitsModule::class, HabitModule::class, TestModule::class],
dependencies = [HabitsApplicationComponent::class]
)
interface HabitsActivityTestComponent {
fun getCheckmarkPanelViewFactory(): CheckmarkPanelViewFactory

View File

@@ -25,7 +25,8 @@ import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.matcher.ViewMatchers
import org.hamcrest.CoreMatchers
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.endsWith
import org.hamcrest.Matcher
import org.isoron.uhabits.BaseUserInterfaceTest
import org.isoron.uhabits.R
@@ -56,12 +57,12 @@ object ListHabitsSteps {
private fun clickTextInsideOverflowMenu(id: Int) {
Espresso.onView(
CoreMatchers.allOf(
allOf(
ViewMatchers.withContentDescription("More options"),
ViewMatchers.withParent(
ViewMatchers.withParent(
ViewMatchers.withClassName(
CoreMatchers.endsWith("Toolbar")
endsWith("Toolbar")
)
)
)
@@ -107,9 +108,9 @@ object ListHabitsSteps {
fun longPressCheckmarks(habit: String?, count: Int) {
CommonSteps.scrollToText(habit)
Espresso.onView(
CoreMatchers.allOf(
allOf(
ViewMatchers.hasDescendant(ViewMatchers.withText(habit)),
ViewMatchers.withClassName(CoreMatchers.endsWith("HabitCardView"))
ViewMatchers.withClassName(endsWith("HabitCardView"))
)
).perform(
longClickDescendantWithClass(CheckmarkButtonView::class.java, count)

View File

@@ -28,8 +28,8 @@ import org.isoron.uhabits.BaseUserInterfaceTest
object WidgetSteps {
@Throws(Exception::class)
fun clickCheckmarkWidget() {
val view_id = "org.isoron.uhabits:id/imageView"
BaseUserInterfaceTest.device.findObject(UiSelector().resourceId(view_id)).click()
val viewId = "org.isoron.uhabits:id/imageView"
BaseUserInterfaceTest.device.findObject(UiSelector().resourceId(viewId)).click()
}
@Throws(Exception::class)
@@ -66,7 +66,7 @@ object WidgetSteps {
BaseUserInterfaceTest.device.findObject(UiSelector().description("Apps")).click()
BaseUserInterfaceTest.device.findObject(UiSelector().description("Widgets")).click()
} else {
val list_id = "com.android.launcher3:id/widgets_list_view"
val listId = "com.android.launcher3:id/widgets_list_view"
BaseUserInterfaceTest.device.pressHome()
BaseUserInterfaceTest.device.waitForIdle()
BaseUserInterfaceTest.device.drag(w / 2, h / 2, w / 2, h / 2, 8)
@@ -76,10 +76,10 @@ object WidgetSteps {
}
button.click()
if (VERSION.SDK_INT >= 28) {
UiScrollable(UiSelector().resourceId(list_id))
UiScrollable(UiSelector().resourceId(listId))
.scrollForward()
}
UiScrollable(UiSelector().resourceId(list_id))
UiScrollable(UiSelector().resourceId(listId))
.scrollIntoView(UiSelector().text("Checkmark"))
}
}

View File

@@ -34,11 +34,12 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
private const val PATH = "habits/list/CheckmarkPanelView"
@RunWith(AndroidJUnit4::class)
@MediumTest
class EntryPanelViewTest : BaseViewTest() {
private val PATH = "habits/list/CheckmarkPanelView"
private lateinit var view: CheckmarkPanelView
@Before
@@ -75,27 +76,6 @@ class EntryPanelViewTest : BaseViewTest() {
assertRenders(view, "$PATH/render.png")
}
// // Flaky test
// @Test
// fun testRender_withDifferentColor() {
// view.color = PaletteUtils.getAndroidTestColor(1)
// assertRenders(view, "$PATH/render_different_color.png")
// }
// // Flaky test
// @Test
// fun testRender_Reversed() {
// prefs.isCheckmarkSequenceReversed = true
// assertRenders(view, "$PATH/render_reversed.png")
// }
// // Flaky test
// @Test
// fun testRender_withOffset() {
// view.dataOffset = 3
// assertRenders(view, "$PATH/render_offset.png")
// }
@Test
fun testToggle() {
val timestamps = mutableListOf<Timestamp>()

View File

@@ -56,7 +56,7 @@ class HabitCardViewTest : BaseViewTest() {
view = component.getHabitCardViewFactory().create().apply {
habit = habit1
values = entries
score = habit1.scores.get(today).value
score = habit1.scores[today].value
isSelected = false
buttonCount = 5
}

View File

@@ -73,27 +73,6 @@ class NumberPanelViewTest : BaseViewTest() {
assertRenders(view, "$PATH/render.png")
}
// // Flaky test
// @Test
// fun testRender_withDifferentColor() {
// view.color = PaletteUtils.getAndroidTestColor(1)
// assertRenders(view, "$PATH/render_different_color.png")
// }
// // Flaky test
// @Test
// fun testRender_Reversed() {
// prefs.isCheckmarkSequenceReversed = true
// assertRenders(view, "$PATH/render_reversed.png")
// }
// // Flaky test
// @Test
// fun testRender_withOffset() {
// view.dataOffset = 3
// assertRenders(view, "$PATH/render_offset.png")
// }
@Test
fun testEdit() {
val timestamps = mutableListOf<Timestamp>()

View File

@@ -103,9 +103,8 @@ class IntentSchedulerTest : BaseAndroidTest() {
assertNull(ReminderReceiver.lastReceivedIntent)
setSystemTime("America/Chicago", 2020, JUNE, 2, 22, 46)
val intent = ReminderReceiver.lastReceivedIntent
assertNotNull(intent)
assertThat(parseId(intent?.data!!), equalTo(habit.id))
val intent = ReminderReceiver.lastReceivedIntent!!
assertThat(parseId(intent.data!!), equalTo(habit.id))
}
@Test
@@ -123,7 +122,6 @@ class IntentSchedulerTest : BaseAndroidTest() {
assertNull(WidgetReceiver.lastReceivedIntent)
setSystemTime("America/Chicago", 2020, JUNE, 2, 22, 46)
val intent = WidgetReceiver.lastReceivedIntent
assertNotNull(intent)
WidgetReceiver.lastReceivedIntent!!
}
}

View File

@@ -68,13 +68,6 @@ public class CheckmarkWidgetViewTest extends BaseViewTest
assertRenders(view, PATH + "checked.png");
}
// @Test
// public void testRender_implicitlyChecked() throws IOException
// {
// view.setCheckmarkValue(Checkmark.YES_AUTO);
// view.refresh();
// assertRenders(view, PATH + "implicitly_checked.png");
// }
@Test
public void testRender_largeSize() throws IOException
@@ -83,11 +76,4 @@ public class CheckmarkWidgetViewTest extends BaseViewTest
assertRenders(view, PATH + "large_size.png");
}
// @Test
// public void testRender_unchecked() throws IOException
// {
// view.setCheckmarkValue(Checkmark.NO);
// view.refresh();
// assertRenders(view, PATH + "unchecked.png");
// }
}

View File

@@ -25,6 +25,8 @@ import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.widget.Scroller
import kotlin.math.abs
import kotlin.math.max
/**
* An AndroidView that implements scrolling.
@@ -71,7 +73,7 @@ class AndroidDataView(
dx: Float,
dy: Float,
): Boolean {
if (Math.abs(dx) > Math.abs(dy)) {
if (abs(dx) > abs(dy)) {
val parent = parent
parent?.requestDisallowInterceptTouchEvent(true)
}
@@ -128,7 +130,7 @@ class AndroidDataView(
view?.let { v ->
var newDataOffset: Int =
scroller.currX / (v.dataColumnWidth * canvas.innerDensity).toInt()
newDataOffset = Math.max(0, newDataOffset)
newDataOffset = max(0, newDataOffset)
if (newDataOffset != v.dataOffset) {
v.dataOffset = newDataOffset
postInvalidate()

View File

@@ -42,7 +42,7 @@ class AndroidImage(private val bmp: Bitmap) : Image {
}
}
public fun Color.toInt(): Int {
fun Color.toInt(): Int {
return android.graphics.Color.argb(
(255 * this.alpha).roundToInt(),
(255 * this.red).roundToInt(),

View File

@@ -83,7 +83,7 @@ class HabitsApplication : Application() {
notificationTray.startListening()
val prefs = component.preferences
prefs.setLastAppVersion(BuildConfig.VERSION_CODE)
prefs.lastAppVersion = BuildConfig.VERSION_CODE
val taskRunner = component.taskRunner
taskRunner.execute {
@@ -106,11 +106,11 @@ class HabitsApplication : Application() {
lateinit var component: HabitsApplicationComponent
fun isTestMode(): Boolean {
try {
return try {
Class.forName("org.isoron.uhabits.BaseAndroidTest")
return true
true
} catch (e: ClassNotFoundException) {
return false
false
}
}
}

View File

@@ -34,6 +34,7 @@ import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.InterfaceUtils
import javax.inject.Inject
import kotlin.math.roundToLong
class NumberPickerFactory
@Inject constructor(
@@ -52,7 +53,7 @@ class NumberPickerFactory
val picker2 = view.findViewById<NumberPicker>(R.id.picker2)
val tvUnit = view.findViewById<TextView>(R.id.tvUnit)
val intValue = Math.round(value * 100).toInt()
val intValue = (value * 100).roundToLong().toInt()
picker.minValue = 0
picker.maxValue = Integer.MAX_VALUE / 100
@@ -86,13 +87,12 @@ class NumberPickerFactory
}
InterfaceUtils.setupEditorAction(
picker,
TextView.OnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE)
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick()
false
}
)
picker
) { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE)
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick()
false
}
return dialog
}

View File

@@ -56,8 +56,7 @@ class TaskProgressBar(
fun update() {
val callback = {
val activeTaskCount = runner.activeTaskCount
val newVisibility = when (activeTaskCount) {
val newVisibility = when (runner.activeTaskCount) {
0 -> GONE
else -> VISIBLE
}

View File

@@ -36,7 +36,7 @@ class HabitTypeDialog : AppCompatDialogFragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
): View {
val binding = SelectHabitTypeBinding.inflate(inflater, container, false)
binding.buttonYesNo.setOnClickListener {

View File

@@ -48,9 +48,9 @@ import org.isoron.uhabits.utils.dim
import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.setupToolbar
import org.isoron.uhabits.utils.sres
import java.lang.Math.max
import java.lang.Math.min
import javax.inject.Inject
import kotlin.math.max
import kotlin.math.min
const val MAX_CHECKMARK_COUNT = 60

View File

@@ -39,12 +39,10 @@ class HabitCardListController @Inject constructor(
private val selectionMenu: Lazy<ListHabitsSelectionMenu>
) : HabitCardListView.Controller, ModelObservable.Listener {
private val NORMAL_MODE = NormalMode()
private val SELECTION_MODE = SelectionMode()
private var activeMode: Mode
init {
this.activeMode = NORMAL_MODE
this.activeMode = NormalMode()
adapter.observable.addListener(this)
}
@@ -83,9 +81,9 @@ class HabitCardListController @Inject constructor(
activeMode.startDrag(position)
}
protected fun toggleSelection(position: Int) {
private fun toggleSelection(position: Int) {
adapter.toggleSelection(position)
activeMode = if (adapter.isSelectionEmpty) NORMAL_MODE else SELECTION_MODE
activeMode = if (adapter.isSelectionEmpty) NormalMode() else SelectionMode()
}
private fun cancelSelection() {
@@ -116,8 +114,7 @@ class HabitCardListController @Inject constructor(
*/
internal inner class NormalMode : Mode {
override fun onItemClick(position: Int) {
val habit = adapter.getItem(position)
if (habit == null) return
val habit = adapter.getItem(position) ?: return
behavior.onClickHabit(habit)
}
@@ -130,9 +127,9 @@ class HabitCardListController @Inject constructor(
startSelection(position)
}
protected fun startSelection(position: Int) {
private fun startSelection(position: Int) {
toggleSelection(position)
activeMode = SELECTION_MODE
activeMode = SelectionMode()
selectionMenu.get().onSelectionStart()
}
}
@@ -158,8 +155,8 @@ class HabitCardListController @Inject constructor(
notifyListener()
}
protected fun notifyListener() {
if (activeMode === SELECTION_MODE)
private fun notifyListener() {
if (activeMode === SelectionMode())
selectionMenu.get().onSelectionChange()
else
selectionMenu.get().onSelectionFinish()

View File

@@ -170,22 +170,22 @@ class HabitCardListView(
inner class TouchHelperCallback : ItemTouchHelper.Callback() {
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
viewHolder: ViewHolder
): Int {
return makeMovementFlags(UP or DOWN, START or END)
}
override fun onMove(
recyclerView: RecyclerView,
from: RecyclerView.ViewHolder,
to: RecyclerView.ViewHolder
from: ViewHolder,
to: ViewHolder
): Boolean {
controller.get().drop(from.adapterPosition, to.adapterPosition)
return true
}
override fun onSwiped(
viewHolder: RecyclerView.ViewHolder,
viewHolder: ViewHolder,
direction: Int
) {
}

View File

@@ -59,8 +59,8 @@ class HabitCardViewFactory
class HabitCardView(
@ActivityContext context: Context,
private val checkmarkPanelFactory: CheckmarkPanelViewFactory,
private val numberPanelFactory: NumberPanelViewFactory,
checkmarkPanelFactory: CheckmarkPanelViewFactory,
numberPanelFactory: NumberPanelViewFactory,
private val behavior: ListHabitsBehavior
) : FrameLayout(context),
ModelObservable.Listener {
@@ -174,7 +174,7 @@ class HabitCardView(
}
clipToPadding = false
layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
val margin = dp(3f).toInt()
setPadding(margin, 0, margin, margin)
addView(innerFrame)

View File

@@ -71,7 +71,7 @@ class NumberPanelView(
setupButtons()
}
override fun createButton() = buttonFactory.create()!!
override fun createButton() = buttonFactory.create()
@Synchronized
override fun setupButtons() {

View File

@@ -27,6 +27,7 @@ import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState
import org.isoron.uhabits.databinding.ShowHabitOverviewBinding
import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.toThemedAndroidColor
import kotlin.math.abs
class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@@ -36,7 +37,7 @@ class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
return String.format(
"%s%.0f%%",
if (percentageDiff >= 0) "+" else "\u2212",
Math.abs(percentageDiff) * 100
abs(percentageDiff) * 100
)
}

View File

@@ -68,7 +68,7 @@ class SyncActivity : AppCompatActivity(), SyncBehavior.Screen {
title = resources.getString(R.string.device_sync),
)
binding.syncLink.setOnClickListener { copyToClipboard() }
binding.instructions.setText(Html.fromHtml(resources.getString(R.string.sync_instructions)))
binding.instructions.text = Html.fromHtml(resources.getString(R.string.sync_instructions))
setContentView(binding.root)
}

View File

@@ -27,22 +27,22 @@ class AndroidCursor(private val cursor: android.database.Cursor) : Cursor {
override fun moveToNext() = cursor.moveToNext()
override fun getInt(index: Int): Int? {
if (cursor.isNull(index)) return null
else return cursor.getInt(index)
return if (cursor.isNull(index)) null
else cursor.getInt(index)
}
override fun getLong(index: Int): Long? {
if (cursor.isNull(index)) return null
else return cursor.getLong(index)
return if (cursor.isNull(index)) null
else cursor.getLong(index)
}
override fun getDouble(index: Int): Double? {
if (cursor.isNull(index)) return null
else return cursor.getDouble(index)
return if (cursor.isNull(index)) null
else cursor.getDouble(index)
}
override fun getString(index: Int): String? {
if (cursor.isNull(index)) return null
else return cursor.getString(index)
return if (cursor.isNull(index)) null
else cursor.getString(index)
}
}

View File

@@ -51,7 +51,7 @@ class AndroidDatabase(
return db.update(tableName, contValues, where, params)
}
override fun insert(tableName: String, values: Map<String, Any?>): Long? {
override fun insert(tableName: String, values: Map<String, Any?>): Long {
val contValues = mapToContentValues(values)
return db.insert(tableName, null, contValues)
}

View File

@@ -32,13 +32,8 @@ import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
@ActivityScope
@Component(
modules = arrayOf(
ActivityContextModule::class,
HabitsActivityModule::class,
ListHabitsModule::class,
HabitModule::class
),
dependencies = arrayOf(HabitsApplicationComponent::class)
modules = [ActivityContextModule::class, HabitsActivityModule::class, ListHabitsModule::class, HabitModule::class],
dependencies = [HabitsApplicationComponent::class]
)
interface HabitsActivityComponent {
val colorPickerDialogFactory: ColorPickerDialogFactory

View File

@@ -44,9 +44,8 @@ class IntentParser
}
private fun parseHabit(uri: Uri): Habit {
val habit = habits.getById(parseId(uri))
return habits.getById(parseId(uri))
?: throw IllegalArgumentException("habit not found")
return habit
}
private fun parseTimestamp(intent: Intent): Timestamp {

View File

@@ -36,6 +36,7 @@ import org.isoron.uhabits.core.utils.DateFormats
import org.isoron.uhabits.inject.AppContext
import java.util.Date
import javax.inject.Inject
import kotlin.math.min
@AppScope
class IntentScheduler
@@ -84,7 +85,7 @@ class IntentScheduler
}
private fun logReminderScheduled(habit: Habit, reminderTime: Long) {
val min = Math.min(5, habit.name.length)
val min = min(5, habit.name.length)
val name = habit.name.substring(0, min)
val df = DateFormats.getBackupDateFormat()
val time = df.format(Date(reminderTime))

View File

@@ -41,7 +41,7 @@ class PendingIntentFactory
) {
fun addCheckmark(habit: Habit, timestamp: Timestamp?): PendingIntent =
PendingIntent.getBroadcast(
getBroadcast(
context,
1,
Intent(context, WidgetReceiver::class.java).apply {
@@ -53,7 +53,7 @@ class PendingIntentFactory
)
fun dismissNotification(habit: Habit): PendingIntent =
PendingIntent.getBroadcast(
getBroadcast(
context,
0,
Intent(context, ReminderReceiver::class.java).apply {
@@ -64,7 +64,7 @@ class PendingIntentFactory
)
fun removeRepetition(habit: Habit): PendingIntent =
PendingIntent.getBroadcast(
getBroadcast(
context,
3,
Intent(context, WidgetReceiver::class.java).apply {
@@ -90,7 +90,7 @@ class PendingIntentFactory
reminderTime: Long?,
timestamp: Long
): PendingIntent =
PendingIntent.getBroadcast(
getBroadcast(
context,
(habit.id!! % Integer.MAX_VALUE).toInt() + 1,
Intent(context, ReminderReceiver::class.java).apply {
@@ -103,7 +103,7 @@ class PendingIntentFactory
)
fun snoozeNotification(habit: Habit): PendingIntent =
PendingIntent.getBroadcast(
getBroadcast(
context,
0,
Intent(context, ReminderReceiver::class.java).apply {
@@ -114,7 +114,7 @@ class PendingIntentFactory
)
fun toggleCheckmark(habit: Habit, timestamp: Long?): PendingIntent =
PendingIntent.getBroadcast(
getBroadcast(
context,
2,
Intent(context, WidgetReceiver::class.java).apply {
@@ -145,7 +145,7 @@ class PendingIntentFactory
)
fun updateWidgets(): PendingIntent =
PendingIntent.getBroadcast(
getBroadcast(
context,
0,
Intent(context, WidgetReceiver::class.java).apply {

View File

@@ -40,17 +40,17 @@ class RingtoneManager
PreferenceManager.getDefaultSharedPreferences(context)
fun getName(): String? {
try {
return try {
var ringtoneName = context.resources.getString(R.string.none)
val ringtoneUri = getURI()
if (ringtoneUri != null) {
val ringtone = getRingtone(context, ringtoneUri)
if (ringtone != null) ringtoneName = ringtone.getTitle(context)
}
return ringtoneName
ringtoneName
} catch (e: RuntimeException) {
e.printStackTrace()
return null
null
}
}

View File

@@ -80,8 +80,7 @@ class RemoteSyncServer(
try {
val url = "${preferences.syncBaseURL}/db/$key"
Log.i("RemoteSyncServer", "GET $url")
val data: SyncData = httpClient.get(url)
return@IO data
return@IO httpClient.get<SyncData>(url)
} catch (e: ServerResponseException) {
throw ServiceUnavailable()
} catch (e: ClientRequestException) {

View File

@@ -23,7 +23,7 @@ import android.content.Context
class CheckmarkWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return CheckmarkWidget(context, id, habits[0])
else return StackWidget(context, id, StackWidgetType.CHECKMARK, habits)
return if (habits.size == 1) CheckmarkWidget(context, id, habits[0])
else StackWidget(context, id, StackWidgetType.CHECKMARK, habits)
}
}

View File

@@ -36,7 +36,7 @@ class FrequencyWidget(
override val defaultHeight: Int = 200
override val defaultWidth: Int = 200
override fun getOnClickPendingIntent(context: Context): PendingIntent? =
override fun getOnClickPendingIntent(context: Context): PendingIntent =
pendingIntentFactory.showHabit(habit)
override fun refreshData(v: View) {

View File

@@ -24,12 +24,12 @@ import android.content.Context
class FrequencyWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return FrequencyWidget(
return if (habits.size == 1) FrequencyWidget(
context,
id,
habits[0],
preferences!!.firstWeekdayInt
preferences.firstWeekdayInt
)
else return StackWidget(context, id, StackWidgetType.FREQUENCY, habits)
else StackWidget(context, id, StackWidgetType.FREQUENCY, habits)
}
}

View File

@@ -41,7 +41,7 @@ class HistoryWidget(
override val defaultHeight: Int = 250
override val defaultWidth: Int = 250
override fun getOnClickPendingIntent(context: Context): PendingIntent? {
override fun getOnClickPendingIntent(context: Context): PendingIntent {
return pendingIntentFactory.showHabit(habit)
}

View File

@@ -23,11 +23,11 @@ import android.content.Context
class HistoryWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return HistoryWidget(
return if (habits.size == 1) HistoryWidget(
context,
id,
habits[0]
)
else return StackWidget(context, id, StackWidgetType.HISTORY, habits)
else StackWidget(context, id, StackWidgetType.HISTORY, habits)
}
}

View File

@@ -36,7 +36,7 @@ class ScoreWidget(
override val defaultHeight: Int = 300
override val defaultWidth: Int = 300
override fun getOnClickPendingIntent(context: Context): PendingIntent? =
override fun getOnClickPendingIntent(context: Context): PendingIntent =
pendingIntentFactory.showHabit(habit)
override fun refreshData(view: View) {

View File

@@ -23,7 +23,7 @@ import android.content.Context
class ScoreWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return ScoreWidget(context, id, habits[0])
else return StackWidget(context, id, StackWidgetType.SCORE, habits)
return if (habits.size == 1) ScoreWidget(context, id, habits[0])
else StackWidget(context, id, StackWidgetType.SCORE, habits)
}
}

View File

@@ -48,7 +48,10 @@ class StackWidgetService : RemoteViewsService() {
internal class StackRemoteViewsFactory(private val context: Context, intent: Intent) :
RemoteViewsFactory {
private val widgetId: Int
private val widgetId: Int = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID
)
private val habitIds: LongArray
private val widgetType: StackWidgetType?
private var remoteViews = ArrayList<RemoteViews>()
@@ -148,15 +151,11 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int
}
init {
widgetId = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID
)
val widgetTypeValue = intent.getIntExtra(StackWidgetService.WIDGET_TYPE, -1)
val habitIdsStr = intent.getStringExtra(StackWidgetService.HABIT_IDS)
if (widgetTypeValue < 0) throw RuntimeException("invalid widget type")
if (habitIdsStr == null) throw RuntimeException("habitIdsStr is null")
widgetType = StackWidgetType.Companion.getWidgetTypeFromValue(widgetTypeValue)
widgetType = StackWidgetType.getWidgetTypeFromValue(widgetTypeValue)
habitIds = splitLongs(habitIdsStr)
}
}

View File

@@ -37,7 +37,7 @@ class StreakWidget(
override val defaultHeight: Int = 200
override val defaultWidth: Int = 200
override fun getOnClickPendingIntent(context: Context): PendingIntent? =
override fun getOnClickPendingIntent(context: Context): PendingIntent =
pendingIntentFactory.showHabit(habit)
override fun refreshData(view: View) {

View File

@@ -23,7 +23,7 @@ import android.content.Context
class StreakWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return StreakWidget(context, id, habits[0])
else return StackWidget(context, id, StackWidgetType.STREAKS, habits)
return if (habits.size == 1) StreakWidget(context, id, habits[0])
else StackWidget(context, id, StackWidgetType.STREAKS, habits)
}
}

View File

@@ -40,7 +40,7 @@ class TargetWidget(
override val defaultHeight: Int = 200
override val defaultWidth: Int = 200
override fun getOnClickPendingIntent(context: Context): PendingIntent? =
override fun getOnClickPendingIntent(context: Context): PendingIntent =
pendingIntentFactory.showHabit(habit)
override fun refreshData(view: View) = runBlocking {

View File

@@ -23,7 +23,7 @@ import android.content.Context
class TargetWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return TargetWidget(context, id, habits[0])
else return StackWidget(context, id, StackWidgetType.TARGET, habits)
return if (habits.size == 1) TargetWidget(context, id, habits[0])
else StackWidget(context, id, StackWidgetType.TARGET, habits)
}
}

View File

@@ -37,14 +37,15 @@ import org.isoron.uhabits.inject.HabitsApplicationComponent
import org.isoron.uhabits.utils.InterfaceUtils.getDimension
import org.isoron.uhabits.utils.PaletteUtils.getAndroidTestColor
import org.isoron.uhabits.utils.StyledResources
import kotlin.math.min
class CheckmarkWidgetView : HabitWidgetView {
var activeColor: Int = 0
var percentage = 0f
var name: String? = null
protected lateinit var ring: RingView
protected lateinit var label: TextView
private lateinit var ring: RingView
private lateinit var label: TextView
var entryValue = 0
var entryState = 0
var isNumerical = false
@@ -92,7 +93,7 @@ class CheckmarkWidgetView : HabitWidgetView {
postInvalidate()
}
protected val text: String
private val text: String
get() = if (isNumerical) {
(entryValue / 1000.0).toShortString()
} else when (entryState) {
@@ -122,7 +123,7 @@ class CheckmarkWidgetView : HabitWidgetView {
val height = MeasureSpec.getSize(heightMeasureSpec)
var w = width.toFloat()
var h = width * 1.25f
val scale = Math.min(width / w, height / h)
val scale = min(width / w, height / h)
w *= scale
h *= scale
if (h < getDimension(context, R.dimen.checkmarkWidget_heightBreakpoint)) ring.visibility =
@@ -131,7 +132,7 @@ class CheckmarkWidgetView : HabitWidgetView {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(h.toInt(), MeasureSpec.EXACTLY)
var textSize = 0.15f * h
val maxTextSize = getDimension(context, R.dimen.smallerTextSize)
textSize = Math.min(textSize, maxTextSize)
textSize = min(textSize, maxTextSize)
label.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
ring.setTextSize(textSize)
ring.setThickness(0.15f * textSize)
@@ -139,8 +140,7 @@ class CheckmarkWidgetView : HabitWidgetView {
}
private fun init() {
val appComponent: HabitsApplicationComponent
appComponent = (context.applicationContext as HabitsApplication).component
val appComponent: HabitsApplicationComponent = (context.applicationContext as HabitsApplication).component
preferences = appComponent.preferences
ring = findViewById<View>(R.id.scoreRing) as RingView
label = findViewById<View>(R.id.label) as TextView

View File

@@ -32,6 +32,7 @@ import org.isoron.uhabits.R
import org.isoron.uhabits.utils.InterfaceUtils.dpToPixels
import org.isoron.uhabits.utils.StyledResources
import java.util.Arrays
import kotlin.math.max
abstract class HabitWidgetView : FrameLayout {
protected var background: InsetDrawable? = null
@@ -73,7 +74,7 @@ abstract class HabitWidgetView : FrameLayout {
Arrays.fill(radii, cornerRadius)
val shape = RoundRectShape(radii, null, null)
val innerDrawable = ShapeDrawable(shape)
val insetLeftTop = Math.max(shadowRadius - shadowOffset, 0)
val insetLeftTop = max(shadowRadius - shadowOffset, 0)
val insetRightBottom = shadowRadius + shadowOffset
background = InsetDrawable(
innerDrawable,

View File

@@ -18,6 +18,7 @@
*/
package org.isoron.uhabits
import com.nhaarman.mockitokotlin2.spy
import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.models.HabitList
import org.isoron.uhabits.core.models.memory.MemoryModelFactory
@@ -29,7 +30,6 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.junit.MockitoJUnitRunner
@RunWith(MockitoJUnitRunner::class)
@@ -46,7 +46,7 @@ open class BaseAndroidJVMTest {
setFixedLocalTime(fixedLocalTime)
setStartDayOffset(0, 0)
modelFactory = MemoryModelFactory()
habitList = Mockito.spy(modelFactory.buildHabitList())
habitList = spy(modelFactory.buildHabitList())
fixtures = HabitFixtures(modelFactory, habitList)
taskRunner = SingleThreadTaskRunner()
commandRunner = CommandRunner(taskRunner)

View File

@@ -18,6 +18,9 @@
*/
package org.isoron.uhabits.receivers
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
import org.isoron.uhabits.BaseAndroidJVMTest
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.Timestamp
@@ -25,7 +28,6 @@ import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.reminders.ReminderScheduler
import org.isoron.uhabits.core.ui.NotificationTray
import org.junit.Test
import org.mockito.Mockito
class ReminderControllerTest : BaseAndroidJVMTest() {
private lateinit var controller: ReminderController
@@ -34,9 +36,9 @@ class ReminderControllerTest : BaseAndroidJVMTest() {
private lateinit var preferences: Preferences
override fun setUp() {
super.setUp()
reminderScheduler = Mockito.mock(ReminderScheduler::class.java)
notificationTray = Mockito.mock(NotificationTray::class.java)
preferences = Mockito.mock(Preferences::class.java)
reminderScheduler = mock()
notificationTray = mock()
preferences = mock()
controller = ReminderController(
reminderScheduler,
notificationTray,
@@ -47,24 +49,24 @@ class ReminderControllerTest : BaseAndroidJVMTest() {
@Test
@Throws(Exception::class)
fun testOnDismiss() {
Mockito.verifyNoMoreInteractions(reminderScheduler)
Mockito.verifyNoMoreInteractions(notificationTray)
Mockito.verifyNoMoreInteractions(preferences)
verifyNoMoreInteractions(reminderScheduler)
verifyNoMoreInteractions(notificationTray)
verifyNoMoreInteractions(preferences)
}
@Test
@Throws(Exception::class)
fun testOnShowReminder() {
val habit = Mockito.mock(Habit::class.java)
val habit: Habit = mock()
controller.onShowReminder(habit, Timestamp.ZERO.plus(100), 456)
Mockito.verify(notificationTray).show(habit, Timestamp.ZERO.plus(100), 456)
Mockito.verify(reminderScheduler).scheduleAll()
verify(notificationTray).show(habit, Timestamp.ZERO.plus(100), 456)
verify(reminderScheduler).scheduleAll()
}
@Test
@Throws(Exception::class)
fun testOnBootCompleted() {
controller.onBootCompleted()
Mockito.verify(reminderScheduler).scheduleAll()
verify(reminderScheduler).scheduleAll()
}
}