diff --git a/.editorconfig b/.editorconfig index 90abd91b3a53..76804a3471ae 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,4 +2,15 @@ end_of_line = lf [*.bat] -end_of_line = crlf \ No newline at end of file +end_of_line = crlf + +# These can be removed once we upgrade to ktlint 1.5.0 +# These are added in preparation for the move to gradle.ktlint 12.1.1 + +# Rule 'standard:no-unused-imports' throws exception in file 'CardBrowser.kt' at position (1228:9) +[*CardBrowser.kt] +ktlint_standard_no-unused-imports = disabled + +# Rule 'standard:parameter-list-wrapping' throws exception in file 'DeckConfig.kt' at position (0:0) +[*DeckConfig.kt] +ktlint_standard_parameter-list-wrapping = disabled \ No newline at end of file diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/NoteEditorTest.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/NoteEditorTest.kt index 27c623bbca62..f5c9dd9770a5 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/NoteEditorTest.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/NoteEditorTest.kt @@ -59,12 +59,10 @@ abstract class NoteEditorTest protected constructor() { private val invalidSdksImpl: List get() { - // TODO: Look into these assumptions and see if they can be diagnosed - both work on my emulators. - // If we fix them, we might be able to use instrumentation.sendKeyDownUpSync /* java.lang.AssertionError: Activity never becomes requested state "[DESTROYED]" (last lifecycle transition = "PAUSED") at androidx.test.core.app.ActivityScenario.waitForActivityToBecomeAnyOf(ActivityScenario.java:301) - */ + */ val invalid = Build.VERSION_CODES.N_MR1 val integers = ArrayList(listOf(invalid)) integers.addAll(invalidSdks!!) diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ACRATest.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ACRATest.kt index 1719e7e7839f..2f68a02f26cd 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ACRATest.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ACRATest.kt @@ -244,7 +244,11 @@ class ACRATest : InstrumentedTest() { assertThat("Second handler is AnalyticsLoggingExceptionHandler", secondExceptionHandler is UsageAnalytics.AnalyticsLoggingExceptionHandler) UsageAnalytics.unInstallDefaultExceptionHandler() var thirdExceptionHandler = Thread.getDefaultUncaughtExceptionHandler() - assertThat("Third handler is neither Analytics nor ThrowableFilter", thirdExceptionHandler !is UsageAnalytics.AnalyticsLoggingExceptionHandler && thirdExceptionHandler !is ThrowableFilterService.FilteringExceptionHandler) + assertThat( + "Third handler is neither Analytics nor ThrowableFilter", + thirdExceptionHandler !is UsageAnalytics.AnalyticsLoggingExceptionHandler && + thirdExceptionHandler !is ThrowableFilterService.FilteringExceptionHandler + ) // chain them again UsageAnalytics.installDefaultExceptionHandler() @@ -260,7 +264,11 @@ class ACRATest : InstrumentedTest() { assertThat("Second handler is AnalyticsLoggingExceptionHandler", secondExceptionHandler is UsageAnalytics.AnalyticsLoggingExceptionHandler) UsageAnalytics.unInstallDefaultExceptionHandler() thirdExceptionHandler = Thread.getDefaultUncaughtExceptionHandler() - assertThat("Third handler is neither Analytics nor ThrowableFilter", thirdExceptionHandler !is UsageAnalytics.AnalyticsLoggingExceptionHandler && thirdExceptionHandler !is ThrowableFilterService.FilteringExceptionHandler) + assertThat( + "Third handler is neither Analytics nor ThrowableFilter", + thirdExceptionHandler !is UsageAnalytics.AnalyticsLoggingExceptionHandler && + thirdExceptionHandler !is ThrowableFilterService.FilteringExceptionHandler + ) } private fun setAcraReportingMode(feedbackReportAlways: String) { diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ContentProviderTest.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ContentProviderTest.kt index 5abac67fefc9..0b7a45f3f622 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ContentProviderTest.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ContentProviderTest.kt @@ -789,15 +789,17 @@ class ContentProviderTest : InstrumentedTest() { fun testUnsupportedOperations() { val cr = contentResolver val dummyValues = ContentValues() - val updateUris = arrayOf( // Can't update most tables in bulk -- only via ID - FlashCardsContract.Note.CONTENT_URI, - FlashCardsContract.Model.CONTENT_URI, - FlashCardsContract.Deck.CONTENT_ALL_URI, - FlashCardsContract.Note.CONTENT_URI.buildUpon() - .appendPath("1234") - .appendPath("cards") - .build() - ) + // Can't update most tables in bulk -- only via ID + val updateUris = + arrayOf( + FlashCardsContract.Note.CONTENT_URI, + FlashCardsContract.Model.CONTENT_URI, + FlashCardsContract.Deck.CONTENT_ALL_URI, + FlashCardsContract.Note.CONTENT_URI.buildUpon() + .appendPath("1234") + .appendPath("cards") + .build() + ) for (uri in updateUris) { try { cr.update(uri, dummyValues, null, null) @@ -808,22 +810,24 @@ class ContentProviderTest : InstrumentedTest() { // ... or this. } } - val deleteUris = arrayOf( - FlashCardsContract.Note.CONTENT_URI, // Only note/ is supported - FlashCardsContract.Note.CONTENT_URI.buildUpon() - .appendPath("1234") - .appendPath("cards") - .build(), - FlashCardsContract.Note.CONTENT_URI.buildUpon() - .appendPath("1234") - .appendPath("cards") - .appendPath("2345") - .build(), - FlashCardsContract.Model.CONTENT_URI, - FlashCardsContract.Model.CONTENT_URI.buildUpon() - .appendPath("1234") - .build() - ) + // Only note/ is supported + val deleteUris = + arrayOf( + FlashCardsContract.Note.CONTENT_URI, + FlashCardsContract.Note.CONTENT_URI.buildUpon() + .appendPath("1234") + .appendPath("cards") + .build(), + FlashCardsContract.Note.CONTENT_URI.buildUpon() + .appendPath("1234") + .appendPath("cards") + .appendPath("2345") + .build(), + FlashCardsContract.Model.CONTENT_URI, + FlashCardsContract.Model.CONTENT_URI.buildUpon() + .appendPath("1234") + .build() + ) for (uri in deleteUris) { try { cr.delete(uri, null, null) @@ -832,23 +836,25 @@ class ContentProviderTest : InstrumentedTest() { // This was expected } } - val insertUris = arrayOf( // Can't do an insert with specific ID on the following tables - FlashCardsContract.Note.CONTENT_URI.buildUpon() - .appendPath("1234") - .build(), - FlashCardsContract.Note.CONTENT_URI.buildUpon() - .appendPath("1234") - .appendPath("cards") - .build(), - FlashCardsContract.Note.CONTENT_URI.buildUpon() - .appendPath("1234") - .appendPath("cards") - .appendPath("2345") - .build(), - FlashCardsContract.Model.CONTENT_URI.buildUpon() - .appendPath("1234") - .build() - ) + // Can't do an insert with specific ID on the following tables + val insertUris = + arrayOf( + FlashCardsContract.Note.CONTENT_URI.buildUpon() + .appendPath("1234") + .build(), + FlashCardsContract.Note.CONTENT_URI.buildUpon() + .appendPath("1234") + .appendPath("cards") + .build(), + FlashCardsContract.Note.CONTENT_URI.buildUpon() + .appendPath("1234") + .appendPath("cards") + .appendPath("2345") + .build(), + FlashCardsContract.Model.CONTENT_URI.buildUpon() + .appendPath("1234") + .build() + ) for (uri in insertUris) { try { cr.insert(uri, dummyValues) @@ -1273,10 +1279,14 @@ class ContentProviderTest : InstrumentedTest() { contentResolver.query( specificCardUri, - arrayOf(FlashCardsContract.Card.QUESTION, FlashCardsContract.Card.ANSWER), // projection - null, // selection is ignored for this URI - null, // selectionArgs is ignored for this URI - null // sortOrder is ignored for this URI + // projection + arrayOf(FlashCardsContract.Card.QUESTION, FlashCardsContract.Card.ANSWER), + // selection is ignored for this URI + null, + // selectionArgs is ignored for this URI + null, + // sortOrder is ignored for this URI + null )?.let { cursor -> if (!cursor.moveToFirst()) { fail("no rows in cursor") diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.kt b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.kt index 3b1356402f2e..841ba7736aad 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.kt @@ -1,4 +1,4 @@ -/**************************************************************************************** +/* ************************************************************************************** * Copyright (c) 2011 Kostas Spyropoulos * * Copyright (c) 2014 Bruno Romero de Azevedo * * Copyright (c) 2014–15 Roland Sieker * @@ -17,6 +17,7 @@ * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ + // TODO: implement own menu? http://www.codeproject.com/Articles/173121/Android-Menus-My-Way package com.ichi2.anki @@ -277,8 +278,9 @@ abstract class AbstractFlashcardViewer : */ protected val gestureProcessor = GestureProcessor(this) - /** Handle joysticks/pedals */ // needs to be lateinit due to a reliance on Context + + /** Handle joysticks/pedals */ protected lateinit var motionEventHandler: MotionEventHandler val server = AnkiServer(this).also { it.start() } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt index f1a250f8a87b..91ec54705ce3 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt @@ -422,9 +422,9 @@ open class AnkiDroidApp : Application(), Configuration.Provider, ChangeManager.S val parsed = Uri.parse(uri) return Intent(Intent.ACTION_VIEW, parsed) } // TODO actually this can be done by translating "link_help" string for each language when the App is - // properly translated + /** - * Get the url for the feedback page + * Get the url for the properly translated feedback page * @return */ val feedbackUrl: String @@ -436,9 +436,9 @@ open class AnkiDroidApp : Application(), Configuration.Provider, ChangeManager.S "ar" -> appResources.getString(R.string.link_help_ar) else -> appResources.getString(R.string.link_help) } // TODO actually this can be done by translating "link_manual" string for each language when the App is - // properly translated + /** - * Get the url for the manual + * Get the url for the properly translated manual * @return */ val manualUrl: String diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt index 96bdb411e065..d575b38fba35 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt @@ -218,7 +218,10 @@ open class CardBrowser : } val data = result.data if (data != null && - (data.getBooleanExtra(NoteEditor.RELOAD_REQUIRED_EXTRA_KEY, false) || data.getBooleanExtra(NoteEditor.NOTE_CHANGED_EXTRA_KEY, false)) + ( + data.getBooleanExtra(NoteEditor.RELOAD_REQUIRED_EXTRA_KEY, false) || + data.getBooleanExtra(NoteEditor.NOTE_CHANGED_EXTRA_KEY, false) + ) ) { Timber.d("Reloading Card Browser due to activity result") // if reloadRequired or noteChanged flag was sent from note editor then reload card list @@ -249,7 +252,10 @@ open class CardBrowser : // Previewing can now perform an "edit", so it can pass on a reloadRequired val data = result.data if (data != null && - (data.getBooleanExtra(NoteEditor.RELOAD_REQUIRED_EXTRA_KEY, false) || data.getBooleanExtra(NoteEditor.NOTE_CHANGED_EXTRA_KEY, false)) + ( + data.getBooleanExtra(NoteEditor.RELOAD_REQUIRED_EXTRA_KEY, false) || + data.getBooleanExtra(NoteEditor.NOTE_CHANGED_EXTRA_KEY, false) + ) ) { forceRefreshSearch() if (reviewerCardId == currentCardId) { @@ -1886,8 +1892,11 @@ open class CardBrowser : // can delete some elements from the cache for example, since nothing is displayed. // It would be interesting to know how often it occurs, but it is not a bug. - // CrashReportService.sendExceptionReport("CardBrowser Scroll Issue 8821", "In a search result of $size cards, with totalItemCount = $totalItemCount, somehow we got $visibleItemCount elements to display.") - Timber.w("CardBrowser Scroll Issue 15441/8821: In a search result of $size cards, with totalItemCount = $totalItemCount, somehow we got $visibleItemCount elements to display.") + Timber.w( + "CardBrowser Scroll Issue 15441/8821: In a search result of $size " + + "cards, with totalItemCount = $totalItemCount, " + + "somehow we got $visibleItemCount elements to display." + ) } // In all of those cases, there is nothing to do: if (size <= 0 || firstVisibleItem >= size || lastVisibleItem >= size || visibleItemCount <= 0) { @@ -2489,7 +2498,10 @@ open class CardBrowser : due.toLong() } else if (card.queue == Consts.QUEUE_TYPE_NEW || card.type == Consts.CARD_TYPE_NEW) { return due.toString() - } else if (card.queue == Consts.QUEUE_TYPE_REV || card.queue == Consts.QUEUE_TYPE_DAY_LEARN_RELEARN || card.type == Consts.CARD_TYPE_REV && card.queue < 0) { + } else if (card.queue == Consts.QUEUE_TYPE_REV || + card.queue == Consts.QUEUE_TYPE_DAY_LEARN_RELEARN || + card.type == Consts.CARD_TYPE_REV && card.queue < 0 + ) { val time = TimeManager.time.intTime() val nbDaySinceCreation = due - col.sched.today time + nbDaySinceCreation * SECONDS_PER_DAY diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt b/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt index 09725b2467fb..b25fb097cc1e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt @@ -1,4 +1,4 @@ -/**************************************************************************************** +/* ************************************************************************************** * Copyright (c) 2009 Andrew Dubya * * Copyright (c) 2009 Nicolas Raoul * * Copyright (c) 2009 Edu Zamora * diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/provider/CardContentProvider.kt b/AnkiDroid/src/main/java/com/ichi2/anki/provider/CardContentProvider.kt index 512cf11194b8..d69e46b15a7f 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/provider/CardContentProvider.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/provider/CardContentProvider.kt @@ -318,7 +318,11 @@ class CardContentProvider : ContentProvider() { val keyAndValue = arg.split("=").toTypedArray() // split arguments into key ("limit") and value ("?") try { // check if value is a placeholder ("?"), if so replace with the next value of selectionArgs - val value = if ("?" == keyAndValue[1].trim { it <= ' ' }) selectionArgs!![selectionArgIndex++] else keyAndValue[1] + val value = if ("?" == keyAndValue[1].trim { it <= ' ' }) { + selectionArgs!![selectionArgIndex++] + } else { + keyAndValue[1] + } if ("limit" == keyAndValue[0].trim { it <= ' ' }) { limit = value.toInt() } else if ("deckID" == keyAndValue[0].trim { it <= ' ' }) { @@ -980,8 +984,10 @@ class CardContentProvider : ContentProvider() { val tempFile: File try { tempFile = File.createTempFile( - preferredName + "_", // the beginning of the filename. - ".$fileMimeType", // this is the extension, if null, '.tmp' is used, need to get the extension from MIME type? + // the beginning of the filename. + preferredName + "_", + // this is the extension, if null, '.tmp' is used, need to get the extension from MIME type? + ".$fileMimeType", File(tempMediaDir) ) tempFile.deleteOnExit() diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/GestureMapper.kt b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/GestureMapper.kt index 2cb01084903e..0dcd1047c819 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/GestureMapper.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/GestureMapper.kt @@ -99,8 +99,13 @@ class GestureMapper { } companion object { + @Suppress("ktlint:standard:property-naming") private var VIEW_CONFIGURATION: ViewConfiguration? = null + + @Suppress("ktlint:standard:property-naming") private var DEFAULT_SWIPE_MIN_DISTANCE = 0 + + @Suppress("ktlint:standard:property-naming") private var DEFAULT_SWIPE_THRESHOLD_VELOCITY = 0 private fun fromTap(height: Int, width: Int, posX: Float, posY: Float): Gesture { val gestureIsRight = posY > height * (1 - posX / width) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/Scheduler.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/Scheduler.kt index 47cfac9b3925..ec491b6eac10 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/Scheduler.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/Scheduler.kt @@ -497,6 +497,7 @@ open class Scheduler(val col: Collection) { /** * @return Number of new card in current deck and its descendants. Capped at [REPORT_LIMIT] */ + @Suppress("ktlint:standard:max-line-length") fun totalNewForCurrentDeck(): Int { return col.db.queryScalar( "SELECT count() FROM cards WHERE id IN (SELECT id FROM cards WHERE did IN " + deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_NEW + " LIMIT ?)", @@ -506,6 +507,7 @@ open class Scheduler(val col: Collection) { /** @return Number of review cards in current deck. */ + @Suppress("ktlint:standard:max-line-length") fun totalRevForCurrentDeck(): Int { return col.db.queryScalar( "SELECT count() FROM cards WHERE id IN (SELECT id FROM cards WHERE did IN " + deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ? LIMIT ?)", @@ -535,6 +537,7 @@ open class Scheduler(val col: Collection) { } /** true if there are any rev cards due. */ + @Suppress("ktlint:standard:max-line-length") open fun revDue(): Boolean { return col.db .queryScalar( @@ -545,6 +548,7 @@ open class Scheduler(val col: Collection) { } /** true if there are any new cards due. */ + @Suppress("ktlint:standard:max-line-length") open fun newDue(): Boolean { return col.db.queryScalar("SELECT 1 FROM cards WHERE did IN " + deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_NEW + " LIMIT 1") != 0 } @@ -568,6 +572,7 @@ open class Scheduler(val col: Collection) { * @param counts An array of [new, lrn, rev] counts from the scheduler's counts() method. * @param reload Force rebuild of estimator rates using the revlog. */ + @Suppress("ktlint:standard:max-line-length") fun eta(counts: Counts, reload: Boolean = true): Int { var newRate: Double var newTime: Double diff --git a/AnkiDroid/src/main/java/com/ichi2/ui/FixedTextView.kt b/AnkiDroid/src/main/java/com/ichi2/ui/FixedTextView.kt index 37d1e985b18e..2de792b8ad01 100644 --- a/AnkiDroid/src/main/java/com/ichi2/ui/FixedTextView.kt +++ b/AnkiDroid/src/main/java/com/ichi2/ui/FixedTextView.kt @@ -174,8 +174,7 @@ open class FixedTextView : AppCompatTextView { at android.widget.TextView.performLongClick(TextView.java:13544) at android.view.View.performLongClick(View.java:7928) at android.view.View$CheckForLongPress.run(View.java:29321) - */ - /* + java.lang.NullPointerException: Attempt to invoke virtual method 'int android.widget.Editor$SelectionModifierCursorController.getMinTouchOffset()' on a null object reference at android.widget.Editor.touchPositionIsInSelection(Unknown:36) at android.widget.Editor.performLongClick(Unknown:72) diff --git a/AnkiDroid/src/main/java/com/ichi2/utils/LanguageUtil.kt b/AnkiDroid/src/main/java/com/ichi2/utils/LanguageUtil.kt index 21c6c4c76da9..6e887caac427 100644 --- a/AnkiDroid/src/main/java/com/ichi2/utils/LanguageUtil.kt +++ b/AnkiDroid/src/main/java/com/ichi2/utils/LanguageUtil.kt @@ -39,159 +39,306 @@ object LanguageUtil { * Please modify LanguageUtilsTest if changing * Please note 'yue' is special, it is 'yu' on CrowdIn, and mapped in import specially to 'yue' */ val APP_LANGUAGES = mapOf( - "Afrikaans" to "af", // Afrikaans - "አማርኛ" to "am", // Amharic - "العربية" to "ar", // Arabic - "Azərbaycan" to "az", // Azerbaijani - "Беларуская" to "be", // Belarusian - "Български" to "bg", // Bulgarian - "বাংলা" to "bn", // Bangla - "Català" to "ca", // Catalan - "کوردیی ناوەندی" to "ckb", // Central Kurdish - "Čeština" to "cs", // Czech - "Dansk" to "da", // Danish - "Deutsch" to "de", // German - "Ελληνικά" to "el", // Greek - "English" to "en", // English - "Esperanto" to "eo", // Esperanto - "Español (Argentina)" to "es-AR", // Spanish (Argentina) - "Español (España)" to "es-ES", // Spanish (Spain) - "Eesti" to "et", // Estonian - "Euskara" to "eu", // Basque - "فارسی" to "fa", // Persian - "Suomi" to "fi", // Finnish - "Filipino" to "fil", // Filipino - "Français" to "fr", // French - "Frysk (Nederlân)" to "fy-NL", // Western Frisian (Netherlands) - "Gaeilge (Éire)" to "ga-IE", // Irish (Ireland) - "Galego" to "gl", // Galician - "Gothic" to "got", // Gothic - "ગુજરાતી (ભારત)" to "gu-IN", // Gujarati (India) - "עברית" to "heb", // Hebrew - "हिन्दी" to "hi", // Hindi - "Hrvatski" to "hr", // Croatian - "Magyar" to "hu", // Hungarian - "Hայերեն (Հայաստան)" to "hy-AM", // Armenian (Armenia) - "Indonesia" to "ind", // Indonesian - "íslenska" to "is", // Icelandic - "Italiano" to "it", // Italian - "日本語" to "ja", // Japanese - "Jawa" to "jv", // Javanese - "ქართული" to "ka", // Georgian - "Қазақ тілі" to "kk", // Kazakh - "ខ្មែរ" to "km", // Khmer - "ಕನ್ನಡ" to "kn", // Kannada - "한국어" to "ko", // Korean - "Kurdî" to "ku", // Kurdish - "Кыргызча" to "ky", // Kyrgyz - "Lietuvių" to "lt", // Lithuanian - "Latviešu" to "lv", // Latvian - "Македонски" to "mk", // Macedonian - "മലയാളം (ഇന്ത്യ)" to "ml-IN", // Malayalam (India) - "Монгол" to "mn", // Mongolian - "मराठी" to "mr", // Marathi - "Melayu" to "ms", // Malay - "မြန်မာ" to "my", // Burmese - "Nederlands" to "nl", // Dutch - "Nynorsk (Noreg)" to "nn-NO", // Norwegian Nynorsk (Norway) - "Norsk" to "no", // Norwegian - "ଓଡ଼ିଆ" to "or", // Odia - "ਪੰਜਾਬੀ (ਭਾਰਤ)" to "pa-IN", // Punjabi (India) - "Polski" to "pl", // Polish - "Português (Brasil)" to "pt-BR", // Portuguese (Brazil) - "Português (Portugal)" to "pt-PT", // Portuguese (Portugal) - "Română" to "ro", // Romanian - "Русский" to "ru", // Russian - "ᱥᱟᱱᱛᱟᱲᱤ" to "sat", // Santali - "Sardu" to "sc", // Sardinian - "Slovenčina" to "sk", // Slovak - "Slovenščina" to "sl", // Slovenian - "Shqip" to "sq", // Albanian - "Српски" to "sr", // Serbian - "Swati" to "ss", // Swati - "Svenska (Sverige)" to "sv-SE", // Swedish (Sweden) - "Kiswahili" to "sw", // Swahili - "தமிழ்" to "ta", // Tamil - "తెలుగు" to "te", // Telugu - "Тоҷикӣ" to "tg", // Tajik - "Tagalog" to "tgl", // Tagalog - "ไทย" to "th", // Thai - "ትግርኛ" to "ti", // Tigrinya - "Tswana" to "tn", // Tswana - "Türkçe" to "tr", // Turkish - "Tsonga" to "ts", // Tsonga - "Татар (Россия)" to "tt-RU", // Tatar (Russia) - "Українська" to "uk", // Ukrainian - "اردو (پاکستان)" to "ur-PK", // Urdu (Pakistan) - "O‘zbek" to "uz", // Uzbek - "Venda" to "ve", // Venda - "Tiếng Việt" to "vi", // Vietnamese - "Wolof" to "wo", // Wolof - "isiXhosa" to "xh", // Xhosa - "粵語" to "yue", // Cantonese - "中文 (中国)" to "zh-CN", // Chinese (China) - "中文 (台灣)" to "zh-TW", // Chinese (Taiwan) - "isiZulu" to "zu" // Zulu + // Afrikaans + "Afrikaans" to "af", + // Amharic + "አማርኛ" to "am", + // Arabic + "العربية" to "ar", + // Azerbaijani + "Azərbaycan" to "az", + // Belarusian + "Беларуская" to "be", + // Bulgarian + "Български" to "bg", + // Bangla + "বাংলা" to "bn", + // Catalan + "Català" to "ca", + // Central Kurdish + "کوردیی ناوەندی" to "ckb", + // Czech + "Čeština" to "cs", + // Danish + "Dansk" to "da", + // German + "Deutsch" to "de", + // Greek + "Ελληνικά" to "el", + // English + "English" to "en", + // Esperanto + "Esperanto" to "eo", + // Spanish (Argentina) + "Español (Argentina)" to "es-AR", + // Spanish (Spain) + "Español (España)" to "es-ES", + // Estonian + "Eesti" to "et", + // Basque + "Euskara" to "eu", + // Persian + "فارسی" to "fa", + // Finnish + "Suomi" to "fi", + // Filipino + "Filipino" to "fil", + // French + "Français" to "fr", + // Western Frisian (Netherlands) + "Frysk (Nederlân)" to "fy-NL", + // Irish (Ireland) + "Gaeilge (Éire)" to "ga-IE", + // Galician + "Galego" to "gl", + // Gothic + "Gothic" to "got", + // Gujarati (India) + "ગુજરાતી (ભારત)" to "gu-IN", + // Hebrew + "עברית" to "heb", + // Hindi + "हिन्दी" to "hi", + // Croatian + "Hrvatski" to "hr", + // Hungarian + "Magyar" to "hu", + // Armenian (Armenia) + "Hայերեն (Հայաստան)" to "hy-AM", + // Indonesian + "Indonesia" to "ind", + // Icelandic + "íslenska" to "is", + // Italian + "Italiano" to "it", + // Japanese + "日本語" to "ja", + // Javanese + "Jawa" to "jv", + // Georgian + "ქართული" to "ka", + // Kazakh + "Қазақ тілі" to "kk", + // Khmer + "ខ្មែរ" to "km", + // Kannada + "ಕನ್ನಡ" to "kn", + // Korean + "한국어" to "ko", + // Kurdish + "Kurdî" to "ku", + // Kyrgyz + "Кыргызча" to "ky", + // Lithuanian + "Lietuvių" to "lt", + // Latvian + "Latviešu" to "lv", + // Macedonian + "Македонски" to "mk", + // Malayalam (India) + "മലയാളം (ഇന്ത്യ)" to "ml-IN", + // Mongolian + "Монгол" to "mn", + // Marathi + "मराठी" to "mr", + // Malay + "Melayu" to "ms", + // Burmese + "မြန်မာ" to "my", + // Dutch + "Nederlands" to "nl", + // Norwegian Nynorsk (Norway) + "Nynorsk (Noreg)" to "nn-NO", + // Norwegian + "Norsk" to "no", + // Odia + "ଓଡ଼ିଆ" to "or", + // Punjabi (India) + "ਪੰਜਾਬੀ (ਭਾਰਤ)" to "pa-IN", + // Polish + "Polski" to "pl", + // Portuguese (Brazil) + "Português (Brasil)" to "pt-BR", + // Portuguese (Portugal) + "Português (Portugal)" to "pt-PT", + // Romanian + "Română" to "ro", + // Russian + "Русский" to "ru", + // Santali + "ᱥᱟᱱᱛᱟᱲᱤ" to "sat", + // Sardinian + "Sardu" to "sc", + // Slovak + "Slovenčina" to "sk", + // Slovenian + "Slovenščina" to "sl", + // Albanian + "Shqip" to "sq", + // Serbian + "Српски" to "sr", + // Swati + "Swati" to "ss", + // Swedish (Sweden) + "Svenska (Sverige)" to "sv-SE", + // Swahili + "Kiswahili" to "sw", + // Tamil + "தமிழ்" to "ta", + // Telugu + "తెలుగు" to "te", + // Tajik + "Тоҷикӣ" to "tg", + // Tagalog + "Tagalog" to "tgl", + // Thai + "ไทย" to "th", + // Tigrinya + "ትግርኛ" to "ti", + // Tswana + "Tswana" to "tn", + // Turkish + "Türkçe" to "tr", + // Tsonga + "Tsonga" to "ts", + // Tatar (Russia) + "Татар (Россия)" to "tt-RU", + // Ukrainian + "Українська" to "uk", + // Urdu (Pakistan) + "اردو (پاکستان)" to "ur-PK", + // Uzbek + "O‘zbek" to "uz", + // Venda + "Venda" to "ve", + // Vietnamese + "Tiếng Việt" to "vi", + // Wolof + "Wolof" to "wo", + // Xhosa + "isiXhosa" to "xh", + // Cantonese + "粵語" to "yue", + // Chinese (China) + "中文 (中国)" to "zh-CN", + // Chinese (Taiwan) + "中文 (台灣)" to "zh-TW", + // Zulu + "isiZulu" to "zu" ) /** Backend languages; may not include recently added ones. * Found at https://i18n.ankiweb.net/teams/ */ @Suppress("unused") val BACKEND_LANGS = listOf( - "af", // Afrikaans - "ar", // العربية - "be", // Беларуская мова - "bg", // Български - "ca", // Català - "cs", // Čeština - "da", // Dansk - "de", // Deutsch - "el", // Ελληνικά - "en", // English (United States) - "en-GB", // English (United Kingdom) - "eo", // Esperanto - "es", // Español - "et", // Eesti - "eu", // Euskara - "fa", // فارسی - "fi", // Suomi - "fr", // Français - "ga-IE", // Gaeilge - "gl", // Galego - "he", // עִבְרִית - "hi-IN", // Hindi - "hr", // Hrvatski - "hu", // Magyar - "hy-AM", // Հայերեն - "id", // Indonesia - "it", // Italiano - "ja", // 日本語 - "jbo", // lo jbobau - "ko", // 한국어 - "la", // Latin - "mn", // Монгол хэл - "ms", // Bahasa Melayu - "nb", // Norsk - "nb-NO", // norwegian - "nl", // Nederlands - "nn-NO", // norwegian - "oc", // Lenga d'òc - "or", // ଓଡ଼ିଆ - "pl", // Polski - "pt-BR", // Português Brasileiro - "pt-PT", // Português - "ro", // Română - "ru", // Pусский язык - "sk", // Slovenčina - "sl", // Slovenščina - "sr", // Српски - "sv-SE", // Svenska - "th", // ภาษาไทย - "tr", // Türkçe - "uk", // Yкраїнська мова - "vi", // Tiếng Việt - "zh-CN", // 简体中文 - "zh-TW" // 繁體中文 + // Afrikaans + "af", + // العربية + "ar", + // Беларуская мова + "be", + // Български + "bg", + // Català + "ca", + // Čeština + "cs", + // Dansk + "da", + // Deutsch + "de", + // Ελληνικά + "el", + // English (United States) + "en", + // English (United Kingdom) + "en-GB", + // Esperanto + "eo", + // Español + "es", + // Eesti + "et", + // Euskara + "eu", + // فارسی + "fa", + // Suomi + "fi", + // Français + "fr", + // Gaeilge + "ga-IE", + // Galego + "gl", + // עִבְרִית + "he", + // Hindi + "hi-IN", + // Hrvatski + "hr", + // Magyar + "hu", + // Հայերեն + "hy-AM", + // Indonesia + "id", + // Italiano + "it", + // 日本語 + "ja", + // lo jbobau + "jbo", + // 한국어 + "ko", + // Latin + "la", + // Монгол хэл + "mn", + // Bahasa Melayu + "ms", + // Norsk + "nb", + // norwegian + "nb-NO", + // Nederlands + "nl", + // norwegian + "nn-NO", + // Lenga d'òc + "oc", + // ଓଡ଼ିଆ + "or", + // Polski + "pl", + // Português Brasileiro + "pt-BR", + // Português + "pt-PT", + // Română + "ro", + // Pусский язык + "ru", + // Slovenčina + "sk", + // Slovenščina + "sl", + // Српски + "sr", + // Svenska + "sv-SE", + // ภาษาไทย + "th", + // Türkçe + "tr", + // Yкраїнська мова + "uk", + // Tiếng Việt + "vi", + // 简体中文 + "zh-CN", + // 繁體中文 + "zh-TW" ) fun getShortDateFormatFromMs(ms: Long): String { diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/ActivityStartupMetaTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/ActivityStartupMetaTest.kt index e71c64543b13..affa41257e19 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/ActivityStartupMetaTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/ActivityStartupMetaTest.kt @@ -32,7 +32,9 @@ class ActivityStartupMetaTest : RobolectricTest() { // if this fails, you may need to add the missing activity to ActivityList.allActivitiesAndIntents() // we can't access this in a static context - val packageInfo = targetContext.getPackageInfoCompat(targetContext.packageName, PackageInfoFlagsCompat.of(PackageManager.GET_ACTIVITIES.toLong())) ?: throw IllegalStateException("getPackageInfo failed") + val flags = PackageInfoFlagsCompat.of(PackageManager.GET_ACTIVITIES.toLong()) + val packageInfo = targetContext.getPackageInfoCompat(targetContext.packageName, flags) + ?: throw IllegalStateException("getPackageInfo failed") val manifestActivities = packageInfo.activities ?: throw IllegalStateException("activity list") val testedActivityClassNames = ActivityList.allActivitiesAndIntents().map { it.className }.toSet() val manifestActivityNames = manifestActivities diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplateEditorTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplateEditorTest.kt index 2b2a94af0a45..438aca67ebdf 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplateEditorTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplateEditorTest.kt @@ -271,7 +271,13 @@ class CardTemplateEditorTest : RobolectricTest() { ) clickAlertDialogButton(DialogInterface.BUTTON_POSITIVE, true) advanceRobolectricLooperWithSleep() - assertNull("Can delete used template?", col.notetypes.getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), intArrayOf(0))) + assertNull( + "Can delete used template?", + col.notetypes.getCardIdsForModel( + collectionBasicModelOriginal.getLong("id"), + intArrayOf(0) + ) + ) assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim { it <= ' ' }, getCurrentDatabaseModelCopy(modelName).toString().trim { it <= ' ' }) assertFalse("Ordinal pending add?", CardTemplateNotetype.isOrdinalPendingAdd(testEditor.tempModel!!, 0)) assertEquals("Change incorrectly added to list?", 0, testEditor.tempModel?.templateChanges?.size) @@ -358,7 +364,8 @@ class CardTemplateEditorTest : RobolectricTest() { advanceRobolectricLooperWithSleep() assertFalse("Model should now be unchanged", testEditor.modelHasChanged()) assertEquals("card generation should result in three cards", 3, getModelCardCount(collectionBasicModelOriginal)) - collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName) // reload the model for future comparison after saving the edit + // reload the model for future comparison after saving the edit + collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName) // Start the CardTemplateEditor back up after saving (which closes the thing...) intent = Intent(Intent.ACTION_VIEW) diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt index 3ec72b49e70d..1a18133be8d8 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt @@ -117,7 +117,8 @@ open class RobolectricTest : AndroidTest { ShadowLog.stream = System.out // Filters for non-Timber sources. Prefer filtering in RobolectricDebugTree if possible // LifecycleMonitor: not needed as we already use registerActivityLifecycleCallbacks for logs - .filter("^(?!(W/ShadowLegacyPath|D/LifecycleMonitor)).*$") // W/ShadowLegacyPath: android.graphics.Path#op() not supported yet. + // W/ShadowLegacyPath: android.graphics.Path#op() not supported yet. + .filter("^(?!(W/ShadowLegacyPath|D/LifecycleMonitor)).*$") ChangeManager.clearSubscribers() diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/analytics/AnalyticsConstantsTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/analytics/AnalyticsConstantsTest.kt index e7f69253a0da..1eb3f6587847 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/analytics/AnalyticsConstantsTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/analytics/AnalyticsConstantsTest.kt @@ -89,7 +89,12 @@ object AnalyticsConstantsTest { @Throws(IllegalAccessException::class) fun checkAnalyticsString() { Assert.assertEquals( - "Re-check if you renamed any string in the analytics string constants of Actions class or AnalyticsConstantsTest.listOfConstantFields. If so, revert them as those string constants must not change as they are compared in analytics.", + """Re-check if you renamed any string in the analytics string constants of + |Actions class or AnalyticsConstantsTest.listOfConstantFields. + |If so, revert them as those string constants must not change as they are + |compared in analytics. + |""" + .trimMargin(), analyticsString, getStringFromReflection(analyticsString) ) @@ -120,13 +125,25 @@ object AnalyticsConstantsTest { fun fieldSizeEqualsListOfConstantFields() { if (fieldSize > listOfConstantFields.size) { Assert.assertEquals( - "Add the newly added analytics constant to AnalyticsConstantsTest.listOfConstantFields. NOTE: Constants should not be renamed as we cannot compare these in analytics.", + """Add the newly added analytics constant to + |AnalyticsConstantsTest.listOfConstantFields. + |NOTE: Constants + |should not be renamed as we cannot compare these + |in analytics. + |""" + .trimMargin(), listOfConstantFields.size, fieldSize ) } else if (fieldSize < listOfConstantFields.size) { Assert.assertEquals( - "If a constant is removed, it should be removed from AnalyticsConstantsTest.listOfConstantFields. NOTE: Constants should not be renamed as we cannot compare these in analytics.", + """If a constant is removed, it should be removed from + |AnalyticsConstantsT + |est.listOfConstantFields. + |NOTE: Constants should not be renamed as we cannot compare + |these in analytics. + |""" + .trimMargin(), listOfConstantFields.size, fieldSize ) @@ -136,14 +153,18 @@ object AnalyticsConstantsTest { } /** - * This test is used to check whether all the string constants of Actions are annotated with @AnalyticsConstant. - * If not, then a runtime exception is thrown. + * This test is used to check whether all the string constants of Actions are + * annotated with [`@AnalyticsConstant`][AnalyticsConstant]. + * If not, then a [RuntimeException] is thrown. */ @Test fun fieldAnnotatedOrNot() { for (value in getProperties()) { if (value.getAnnotation(AnalyticsConstant::class.java) == null && !value.isSynthetic) { - throw RuntimeException("All the fields in Actions class must be annotated with @AnalyticsConstant. It seems " + value.name + " is not annotated.") + throw RuntimeException( + "All the fields in Actions class must be annotated " + + "with @AnalyticsConstant. It seems " + value.name + " is not annotated." + ) } } } diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/analytics/PreferencesAnalyticsTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/analytics/PreferencesAnalyticsTest.kt index 8ec8767daa5d..9b07e6e9e4c7 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/analytics/PreferencesAnalyticsTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/analytics/PreferencesAnalyticsTest.kt @@ -38,7 +38,8 @@ class PreferencesAnalyticsTest : RobolectricTest() { /** Keys of preferences that shouldn't be reported */ private val excludedPrefs = setOf( - "analytics_opt_in", // Share feature usage: analytics are only reported if this is enabled :) + // Share feature usage: analytics are only reported if this is enabled :) + "analytics_opt_in", // Screens: don't have a value "generalScreen", "reviewingScreen", @@ -59,13 +60,18 @@ class PreferencesAnalyticsTest : RobolectricTest() { // Preferences that only click: don't have a value "tts", "resetLanguages", - "custom_buttons_link", // Opens App Bar buttons fragment - "custom_sync_server_link", // Opens Custom sync server fragment + // Opens App Bar buttons fragment + "custom_buttons_link", + // Opens Custom sync server fragment + "custom_sync_server_link", "thirdpartyapps_link", // will be reworked in the future - "minimumCardsDueForNotification", // Notify when - "widgetVibrate", // Vibrate - "widgetBlink", // Blink light + // Notify when + "minimumCardsDueForNotification", + // Vibrate + "widgetVibrate", + // Blink light + "widgetBlink", // potential personal data "syncAccount", "syncBaseUrl", diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/dialogs/tags/TagsListTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/dialogs/tags/TagsListTest.kt index 6e654a024f8c..98af20c74f04 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/dialogs/tags/TagsListTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/dialogs/tags/TagsListTest.kt @@ -392,7 +392,8 @@ class TagsListTest { @Test fun test_uncheck_indeterminate_tags_list() { assertTrue( - "Attempting to uncheck tag 'programming' should return true, as 'programming' is found in all tags and it have indeterminate state", + "Attempting to uncheck tag 'programming' should return true, as 'programming' " + + "is found in all tags and it have indeterminate state", tagsListWithIndeterminate.uncheck("programming") ) assertEquals( diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/servicemodel/UpgradeGesturesToControlsTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/servicemodel/UpgradeGesturesToControlsTest.kt index 3d9b16584944..e8b36badcb87 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/servicemodel/UpgradeGesturesToControlsTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/servicemodel/UpgradeGesturesToControlsTest.kt @@ -193,6 +193,11 @@ class UpgradeGesturesToControlsTest(private val testData: TestData) : Robolectri arrayOf(TestData(PREF_KEY_VOLUME_DOWN, KEYCODE_VOLUME_DOWN, PREF_KEY_VOLUME_UP, volume_down_binding)) ).toList() } - data class TestData(val affectedPreferenceKey: String, val keyCode: Int, val unaffectedPreferenceKey: String, val binding: MappableBinding) + data class TestData( + val affectedPreferenceKey: String, + val keyCode: Int, + val unaffectedPreferenceKey: String, + val binding: MappableBinding + ) } } diff --git a/AnkiDroid/src/test/java/com/ichi2/libanki/CollectionTest.kt b/AnkiDroid/src/test/java/com/ichi2/libanki/CollectionTest.kt index a862d8f1c285..6879a4ae8614 100644 --- a/AnkiDroid/src/test/java/com/ichi2/libanki/CollectionTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/libanki/CollectionTest.kt @@ -64,10 +64,10 @@ class CollectionTest : JvmTest() { } } - /******************* + /* ***************** ** autogenerated from https://github.com/ankitects/anki/blob/2c73dcb2e547c44d9e02c20a00f3c52419dc277b/pylib/tests/test_cards.py * - *******************/ - /*TODO + ******************* + @Test public void test_create_open(){ (fd, path) = tempfile.mkstemp(suffix=".anki2", prefix="test_attachNew"); diff --git a/AnkiDroid/src/test/java/com/ichi2/libanki/DecksTest.kt b/AnkiDroid/src/test/java/com/ichi2/libanki/DecksTest.kt index 6ec8f1ebb133..8e19728c9950 100644 --- a/AnkiDroid/src/test/java/com/ichi2/libanki/DecksTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/libanki/DecksTest.kt @@ -62,13 +62,14 @@ class DecksTest : JvmTest() { assertTrue(names.contains("foo::bar")) assertFalse(names.contains("hello::world")) // create another col - /* TODO: do we want to follow upstream here ? + + /* TODO: do we want to follow upstream here ? // automatically adjusted if a duplicate name decks.rename(decks.get(id), "FOO"); names = decks.allSortedNames(); assertThat(names, containsString("FOO+")); - */ + // when renaming, the children should be renamed too addDeck("one::two::three") id = addDeck("one") @@ -211,16 +212,4 @@ class DecksTest : JvmTest() { assertThat("filtered and home deck", decks.cardCount(deckWithNoChildren, filteredDeck, includeSubdecks = false), equalTo(3)) } - - companion object { - // Used in other class to populate decks. - @Suppress("SpellCheckingInspection") - val TEST_DECKS = arrayOf( - "scxipjiyozczaaczoawo", - "cmxieunwoogyxsctnjmv::abcdefgh::ZYXW", - "cmxieunwoogyxsctnjmv::INSBGDS", - "::foobar", // Addition test for issue #11026 - "A::" - ) - } } diff --git a/AnkiDroid/src/test/java/com/ichi2/libanki/FinderTest.kt b/AnkiDroid/src/test/java/com/ichi2/libanki/FinderTest.kt index 591d5e30be85..44717bb7c7c4 100644 --- a/AnkiDroid/src/test/java/com/ichi2/libanki/FinderTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/libanki/FinderTest.kt @@ -261,6 +261,7 @@ class FinderTest : JvmTest() { assertNotEquals(firstCardId, col.findCards("", BuiltinSortKind.CARD_DUE, reverse=true).get(0)); */ + // model assertEquals(3, col.findCards("note:basic").size) assertEquals(2, col.findCards("-note:basic").size) diff --git a/AnkiDroid/src/test/java/com/ichi2/libanki/LaTeXTest.kt b/AnkiDroid/src/test/java/com/ichi2/libanki/LaTeXTest.kt index 3280893e4447..2e9113001925 100644 --- a/AnkiDroid/src/test/java/com/ichi2/libanki/LaTeXTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/libanki/LaTeXTest.kt @@ -35,6 +35,7 @@ class LaTeXTest : JvmTest() { } @Test + @Suppress("ktlint:standard:max-line-length") fun imgLinkTest() { val m: Media = MockMedia(col) // The hashing function should never change, as it would broke link. So hard coding the expected hash value is valid @@ -69,6 +70,7 @@ class LaTeXTest : JvmTest() { } @Test + @Suppress("ktlint:standard:max-line-length") fun mathMatchTest() { val media: Media = MockMedia(col) // The hashing function should never change, as it would broke link. So hard coding the expected hash value is valid @@ -86,6 +88,7 @@ class LaTeXTest : JvmTest() { } @Test + @Suppress("ktlint:standard:max-line-length") fun mungeQATest() { val m: Media = MockMedia(col) diff --git a/AnkiDroid/src/test/java/com/ichi2/libanki/SchedulerTest.kt b/AnkiDroid/src/test/java/com/ichi2/libanki/SchedulerTest.kt index 59eeeda852e2..084afa9eb57e 100644 --- a/AnkiDroid/src/test/java/com/ichi2/libanki/SchedulerTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/libanki/SchedulerTest.kt @@ -523,6 +523,7 @@ open class SchedulerTest : JvmTest() { @Ignore("Disabled upstream") fun test_overdue_lapseV2() { // disabled in commit 3069729776990980f34c25be66410e947e9d51a2 + /* Upstream does not execute it Collection col = getColV2() // pylint: disable=unreachable // add a note @@ -739,9 +740,10 @@ open class SchedulerTest : JvmTest() { val did = addDynamicDeck("Cram") col.sched.rebuildDyn(did) // should appear as normal in the deck list - /* todo sort - assertEquals(1, sorted(col.getSched().deckDueTree().getChildren())[0].review_count); - */ + + // TODO: sort + // Assert.assertEquals(1, sorted(col.sched.deckDueTree().getChildren())[0].review_count); + // and should appear in the counts Assert.assertEquals(Counts(0, 0, 1), col.sched.counts()) // grab it and check estimates diff --git a/AnkiDroid/src/test/java/com/ichi2/testutils/AnkiAssert.kt b/AnkiDroid/src/test/java/com/ichi2/testutils/AnkiAssert.kt index 2d56f4b0379a..550b2caf5da6 100644 --- a/AnkiDroid/src/test/java/com/ichi2/testutils/AnkiAssert.kt +++ b/AnkiDroid/src/test/java/com/ichi2/testutils/AnkiAssert.kt @@ -39,8 +39,9 @@ object AnkiAssert { } } - /** Helper to sort out "JUnit tests should include assert() or fail()" quality check */ // suspend variant of [assertDoesNotThrow] + + /** Helper to sort out "JUnit tests should include assert() or fail()" quality check */ suspend fun assertDoesNotThrowSuspend(block: suspend () -> Unit) { try { block() diff --git a/AnkiDroid/src/test/java/com/ichi2/testutils/AnkiFragmentScenario.kt b/AnkiDroid/src/test/java/com/ichi2/testutils/AnkiFragmentScenario.kt index 4d4fff0b3ea4..4bbb86853ef1 100644 --- a/AnkiDroid/src/test/java/com/ichi2/testutils/AnkiFragmentScenario.kt +++ b/AnkiDroid/src/test/java/com/ichi2/testutils/AnkiFragmentScenario.kt @@ -207,7 +207,8 @@ inline fun AnkiFragmentScenario.withFragment( * @see ActivityScenario a scenario API for Activity */ class AnkiFragmentScenario private constructor( - @Suppress("MemberVisibilityCanBePrivate") /* synthetic access */ + // MemberVisibilityCanBePrivate: synthetic access + @Suppress("MemberVisibilityCanBePrivate") val fragmentClass: Class, private val activityScenario: ActivityScenario ) : Closeable by activityScenario { @@ -335,7 +336,7 @@ class AnkiFragmentScenario private constructor( fragmentArgs, initialState, factory, - 0 /*containerViewId=*/ + 0 ) /** diff --git a/AnkiDroid/src/test/java/com/ichi2/utils/ClipboardUtilTest.kt b/AnkiDroid/src/test/java/com/ichi2/utils/ClipboardUtilTest.kt index 80522927a48b..bdd0a3e99c0a 100644 --- a/AnkiDroid/src/test/java/com/ichi2/utils/ClipboardUtilTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/utils/ClipboardUtilTest.kt @@ -26,7 +26,8 @@ class ClipboardUtilTest { @Before fun setUp() { - clipboardManager = ApplicationProvider.getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + clipboardManager = ApplicationProvider.getApplicationContext() + .getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager } @Test diff --git a/AnkiDroid/src/test/java/com/ichi2/utils/JSONObjectTest.kt b/AnkiDroid/src/test/java/com/ichi2/utils/JSONObjectTest.kt index 13b737e1507b..66617a12a4de 100644 --- a/AnkiDroid/src/test/java/com/ichi2/utils/JSONObjectTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/utils/JSONObjectTest.kt @@ -18,6 +18,7 @@ package com.ichi2.utils import android.annotation.SuppressLint import androidx.test.ext.junit.runners.AndroidJUnit4 import com.ichi2.testutils.EmptyApplication +import org.intellij.lang.annotations.Language import org.json.JSONObject import org.junit.Assert import org.junit.Before @@ -32,10 +33,22 @@ import org.robolectric.annotation.Config @Config(application = EmptyApplication::class) @SuppressLint("CheckResult") // many usages: checking exceptions class JSONObjectTest { - private val correctJsonBasic = "{\"key1\":\"value1\"}" - private val correctJsonNested = "{\"key1\":{\"key1a\":\"value1a\",\"key1b\":\"value1b\"},\"key2\":\"value2\"}" - private val correctJsonWithArray = "{\"key1\":\"value1\",\"key2\":[{\"key2a\":\"value2a\"},{\"key2b\":\"value2b\"}],\"key3\":\"value3\"}" - private val correctJsonNestedWithArray = "{\"key1\":{\"key1a\":\"value1a\",\"key1b\":\"value1b\"},\"key2\":[{\"key2a\":\"value2a\"},{\"key2b\":\"value2b\"}],\"key3\":\"value3\"}" + @Language("JSON") + private val correctJsonBasic = """{"key1":"value1"}""" + + @Language("JSON") + private val correctJsonNested = + """{"key1":{"key1a":"value1a","key1b":"value1b"},"key2":"value2"}""" + + @Language("JSON") + private val correctJsonWithArray = + """{"key1":"value1","key2":[{"key2a":"value2a"},{"key2b":"value2b"}],"key3":"value3"}""" + + @Language("JSON") + private val correctJsonNestedWithArray = + """{"key1":{"key1a":"value1a","key1b":"value1b"}, + |"key2":[{"key2a":"value2a"},{"key2b":"value2b"}],"key3":"value3"} + """.trimMargin() private lateinit var correctJsonObjectBasic: JSONObject private lateinit var correctJsonObjectNested: JSONObject diff --git a/AnkiDroid/src/test/java/com/ichi2/utils/LanguageUtilsTest.kt b/AnkiDroid/src/test/java/com/ichi2/utils/LanguageUtilsTest.kt index ce991ec77b3d..32cb727ba9c3 100644 --- a/AnkiDroid/src/test/java/com/ichi2/utils/LanguageUtilsTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/utils/LanguageUtilsTest.kt @@ -74,11 +74,16 @@ class LanguageUtilsTest { /** Languages which were removed for good reason */ private val previousLanguageExclusions = Sets.newHashSet( - "pt_PT", // pt-PT - "pt_BR", // pt-BR - "sv", // sv-SE - "zh_CN", // zh-CN - "zh_TW" // zh-TW + // pt-PT + "pt_PT", + // pt-BR + "pt_BR", + // sv-SE + "sv", + // zh-CN + "zh_CN", + // zh-TW + "zh_TW" ) } } diff --git a/AnkiDroid/src/test/java/com/ichi2/utils/UniqueArrayListTest.kt b/AnkiDroid/src/test/java/com/ichi2/utils/UniqueArrayListTest.kt index 957e0643ade6..5e6415f6ec18 100644 --- a/AnkiDroid/src/test/java/com/ichi2/utils/UniqueArrayListTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/utils/UniqueArrayListTest.kt @@ -385,7 +385,7 @@ class UniqueArrayListTest { val uniqueList = UniqueArrayList.from(longs) assertNotEquals(-1, uniqueList.indexOf(1L).toLong()) - uniqueList.removeAt(0 /*index of 1L*/) + uniqueList.removeAt(0) // 0 is the index of 1L assertEquals(-1, uniqueList.indexOf(1L).toLong()) uniqueList[10] = 1L assertEquals(10, uniqueList.indexOf(1L).toLong()) diff --git a/AnkiDroid/src/test/java/com/ichi2/utils/WebViewUtilsTest.kt b/AnkiDroid/src/test/java/com/ichi2/utils/WebViewUtilsTest.kt index 129f6ac62ce0..f14e25e8c48b 100644 --- a/AnkiDroid/src/test/java/com/ichi2/utils/WebViewUtilsTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/utils/WebViewUtilsTest.kt @@ -22,6 +22,7 @@ import org.junit.Test class WebViewUtilsTest { @Test + @Suppress("ktlint:standard:max-line-length") fun testWebviewVersionCodes() { assertThat( "Known old webview determined correctly", diff --git a/api/src/main/java/com/ichi2/anki/FlashCardsContract.kt b/api/src/main/java/com/ichi2/anki/FlashCardsContract.kt index 362a63f7a15b..b6c293280bbb 100644 --- a/api/src/main/java/com/ichi2/anki/FlashCardsContract.kt +++ b/api/src/main/java/com/ichi2/anki/FlashCardsContract.kt @@ -226,7 +226,7 @@ public object FlashCardsContract { * used for accessing the data of a note using the URI * "content://com.ichi2.anki.flashcards/notes//data */ - @Suppress("ConstPropertyName") + @Suppress("ConstPropertyName", "ktlint:standard:property-naming") public const val _ID: String = "_id" // field is part of the default projection available to the clients @@ -361,7 +361,7 @@ public object FlashCardsContract { * used for accessing the data of the model using the URI * `content://com.ichi2.anki.flashcards/models/` */ - @Suppress("ConstPropertyName") + @Suppress("ConstPropertyName", "ktlint:standard:property-naming") public const val _ID: String = "_id" public const val NAME: String = "name" public const val FIELD_NAME: String = "field_name" @@ -426,7 +426,7 @@ public object FlashCardsContract { * reliably over subsequent queries. Especially if the number of cards or fields changes, * the _ID will change too. */ - @Suppress("ConstPropertyName") + @Suppress("ConstPropertyName", "ktlint:standard:property-naming") public const val _ID: String = "_id" /** diff --git a/api/src/main/java/com/ichi2/anki/api/BasicModel.kt b/api/src/main/java/com/ichi2/anki/api/BasicModel.kt index a29d4c469370..3e92cee1633a 100644 --- a/api/src/main/java/com/ichi2/anki/api/BasicModel.kt +++ b/api/src/main/java/com/ichi2/anki/api/BasicModel.kt @@ -7,6 +7,7 @@ package com.ichi2.anki.api internal class BasicModel { companion object { @JvmField // required for API + @Suppress("ktlint:standard:property-naming") var FIELDS = arrayOf("Front", "Back") // List of card names that will be used in AnkiDroid (one for each direction of learning) diff --git a/lint-rules/src/main/java/com/ichi2/anki/lint/rules/DuplicateCrowdInStrings.kt b/lint-rules/src/main/java/com/ichi2/anki/lint/rules/DuplicateCrowdInStrings.kt index 75c15fd81140..4aa8cb748d57 100644 --- a/lint-rules/src/main/java/com/ichi2/anki/lint/rules/DuplicateCrowdInStrings.kt +++ b/lint-rules/src/main/java/com/ichi2/anki/lint/rules/DuplicateCrowdInStrings.kt @@ -144,7 +144,9 @@ class DuplicateCrowdInStrings : ResourceXmlDetector() { firstLocation = location } else { prevLocation.secondary = location - location.message = "Duplicates value in `${names[0]}`. Add a `comment` attribute on both strings to explain this duplication" + location.message = + "Duplicates value in `${names[0]}`. " + + "Add a `comment` attribute on both strings to explain this duplication" location.setSelfExplanatory(false) if (string != prevString) { caseVaries = true @@ -179,6 +181,7 @@ class DuplicateCrowdInStrings : ResourceXmlDetector() { /** * Whether there are any duplicate strings, including capitalization adjustments. */ + @Suppress("ktlint:standard:property-naming") var ISSUE: Issue = Issue.create( ID, "Duplicate Strings (CrowdIn)", diff --git a/lint-rules/src/main/java/com/ichi2/anki/lint/rules/FixedPreferencesTitleLength.kt b/lint-rules/src/main/java/com/ichi2/anki/lint/rules/FixedPreferencesTitleLength.kt index 0cb131e26028..80d3018b11cc 100644 --- a/lint-rules/src/main/java/com/ichi2/anki/lint/rules/FixedPreferencesTitleLength.kt +++ b/lint-rules/src/main/java/com/ichi2/anki/lint/rules/FixedPreferencesTitleLength.kt @@ -50,19 +50,31 @@ class FixedPreferencesTitleLength : ResourceXmlDetector(), XmlScanner { private const val PREFERENCES_TITLE_MAX_LENGTH = 41 private const val MENU_TITLE_MAX_LENGTH = 28 - private const val PREFERENCES_DESCRIPTION_TITLE_LENGTH = "Preference titles should be less than $PREFERENCES_TITLE_MAX_LENGTH characters" - private const val MENU_DESCRIPTION_TITLE_LENGTH = "Preference titles should be less than $MENU_TITLE_MAX_LENGTH characters" + private const val PREFERENCES_DESCRIPTION_TITLE_LENGTH = + "Preference titles should be less than $PREFERENCES_TITLE_MAX_LENGTH characters" + private const val MENU_DESCRIPTION_TITLE_LENGTH = + "Preference titles should be less than $MENU_TITLE_MAX_LENGTH characters" - private const val PREFERENCES_DESCRIPTION_MAX_LENGTH = """Preference titles should contain maxLength="$PREFERENCES_TITLE_MAX_LENGTH" attribute""" - private const val MENU_DESCRIPTION_MAX_LENGTH = """Preference titles should contain maxLength="$MENU_TITLE_MAX_LENGTH" attribute""" + private const val PREFERENCES_DESCRIPTION_MAX_LENGTH = + "Preference titles should contain maxLength=\"$PREFERENCES_TITLE_MAX_LENGTH\" attribute" + private const val MENU_DESCRIPTION_MAX_LENGTH = + """Preference titles should contain maxLength="$MENU_TITLE_MAX_LENGTH" attribute""" // Around 42 (resp. 29) characters is a hard max on emulators in preferences (resp. menu), likely smaller in reality, so use a buffer - private const val PREFERENCES_EXPLANATION_TITLE_LENGTH = "A preference title with more than $PREFERENCES_TITLE_MAX_LENGTH characters may fail to display on smaller screens" - private const val MENU_EXPLANATION_TITLE_LENGTH = "A menu title with more than $MENU_TITLE_MAX_LENGTH characters may fail to display on smaller screens" + private const val PREFERENCES_EXPLANATION_TITLE_LENGTH = + "A preference title with more than $PREFERENCES_TITLE_MAX_LENGTH characters " + + "may fail to display on smaller screens" + private const val MENU_EXPLANATION_TITLE_LENGTH = + "A menu title with more than $MENU_TITLE_MAX_LENGTH characters " + + "may fail to display on smaller screens" // Read More: https://support.crowdin.com/file-formats/android-xml/ - private const val PREFERENCES_EXPLANATION_MAX_LENGTH = "Preference Title should contain maxLength attribute because it fixes translated string length" - private const val MENU_EXPLANATION_MAX_LENGTH = "Preference Title should contain maxLength attribute because it fixes translated string length" + private const val PREFERENCES_EXPLANATION_MAX_LENGTH = + "Preference Title should contain maxLength attribute because " + + "it fixes translated string length" + private const val MENU_EXPLANATION_MAX_LENGTH = + "Preference Title should contain maxLength attribute because " + + "it fixes translated string length" private val implementation = Implementation(FixedPreferencesTitleLength::class.java, Scope.RESOURCE_FILE_SCOPE) val PREFERENCES_ISSUE_TITLE_LENGTH: Issue = Issue.create( @@ -142,8 +154,9 @@ class FixedPreferencesTitleLength : ResourceXmlDetector(), XmlScanner { "menu" -> titlesOfMenuScreens else -> return } - /* Add the `android:title`'s resource name (without "@string/") to [stringResources] if the element has this attribute and the file belongs to src/main/res/xml. - */ + // Add the `android:title`'s resource name (without "@string/") to `stringResources` + // if the element has this attribute and the file belongs to src/main/res/xml. + // Removing the "@string/" part. val titleAttribute = element.getAttribute(ATTR_TITLE) val stringName = titleAttribute.substringAfter("@string/", "").ifEmpty { return } diff --git a/lint-rules/src/main/java/com/ichi2/anki/lint/rules/PrintStackTraceUsage.kt b/lint-rules/src/main/java/com/ichi2/anki/lint/rules/PrintStackTraceUsage.kt index 31c4225b1ba1..13916614c9cb 100644 --- a/lint-rules/src/main/java/com/ichi2/anki/lint/rules/PrintStackTraceUsage.kt +++ b/lint-rules/src/main/java/com/ichi2/anki/lint/rules/PrintStackTraceUsage.kt @@ -37,7 +37,9 @@ class PrintStackTraceUsage : Detector(), SourceCodeScanner { @VisibleForTesting val DESCRIPTION = "Use Timber to log exceptions (typically Timber.w if non-fatal)" - private const val EXPLANATION = "AnkiDroid exclusively uses Timber for logging exceptions. See: https://github.com/ankidroid/Anki-Android/wiki/Code-style#logging" + private const val EXPLANATION = + "AnkiDroid exclusively uses Timber for logging exceptions. " + + "See: https://github.com/ankidroid/Anki-Android/wiki/Code-style#logging" private val implementation = Implementation(PrintStackTraceUsage::class.java, Scope.JAVA_FILE_SCOPE) val ISSUE: Issue = Issue.create( ID, diff --git a/lint-rules/src/main/java/com/ichi2/anki/lint/utils/Crowdin.kt b/lint-rules/src/main/java/com/ichi2/anki/lint/utils/Crowdin.kt index 4b12d4b90924..6686e6e9b0b4 100644 --- a/lint-rules/src/main/java/com/ichi2/anki/lint/utils/Crowdin.kt +++ b/lint-rules/src/main/java/com/ichi2/anki/lint/utils/Crowdin.kt @@ -62,29 +62,27 @@ value class CrowdinLanguageTag(private val tag: String) { companion object { private val customMappings = mapOf( - /* from tools/localization/src/update.ts */ + // ** from tools/localization/src/update.ts ** "yue" to "yu", "heb" to "he", "iw" to "he", "ind" to "id", "tgl" to "tl", - /* Other weirdness */ + // ** Other weirdness ** - /* Malayalam */ + // Malayalam "ml" to "mlin", - /* Punjabi */ + // Punjabi "pa" to "pain", // Norwegian Nynorsk "nn" to "nnno", - - /* Tatar (Russia) */ + // Tatar (Russia) "tt" to "ttru", - - /* Urdu (Pakistan) */ + // Urdu (Pakistan) "ur" to "urpk", - // Crowdin does not handle 'Spanish (Spain)' as 'eses', it needs 'es' + // ** Crowdin does not handle 'Spanish (Spain)' as 'eses', it needs 'es' ** "eses" to "es", "ptpt" to "pt" ) diff --git a/lint-rules/src/test/java/com/ichi2/anki/lint/rules/VariableNamingDetectorTest.kt b/lint-rules/src/test/java/com/ichi2/anki/lint/rules/VariableNamingDetectorTest.kt index d8af33928461..0a01c4fa86c9 100644 --- a/lint-rules/src/test/java/com/ichi2/anki/lint/rules/VariableNamingDetectorTest.kt +++ b/lint-rules/src/test/java/com/ichi2/anki/lint/rules/VariableNamingDetectorTest.kt @@ -22,6 +22,7 @@ import org.junit.Test internal class VariableNamingDetectorTest { @Test + @Suppress("ktlint:standard:max-line-length") fun reportsErrorTest() { lint() .allowMissingSdk()