Ignore "@instance..." part of username when computing status length (#3392)
* Move compose.* tests to own namespace * Ignore "@instance..." part of username when computing status length In a status with a mention ("@foo@example.org") only the "@foo" part should be included in the calculated status length. It wasn't, so the app was prevening people from posting statuses that should have been allowed. Fix this. - Lift the length calculation code in to a separate static function (easier and faster to test) - Add a `MentionSpan` type, to reuse existing code for detecting mentions - Fix a bug in `FakeSpannable.getSpans()` (it was returning the outer type, not the wrapped inner span) - Add additional fast tests The tests made sense under the `components.compose.ComposeActivity` package, so I also created that and moved the existing ComposeActivity tests there. Fixes https://github.com/tuskyapp/Tusky/issues/3339 * Static import assertEquals
This commit is contained in:
parent
f309c7750f
commit
6dfdaec425
8 changed files with 158 additions and 23 deletions
|
@ -136,7 +136,7 @@ class SpanUtilsTest {
|
|||
}
|
||||
|
||||
override fun <T : Any> getSpans(start: Int, end: Int, type: Class<T>): Array<T> {
|
||||
return spans.filter { it.start >= start && it.end <= end && type.isInstance(it) }
|
||||
return spans.filter { it.start >= start && it.end <= end && type.isInstance(it.span) }
|
||||
.map { it.span }
|
||||
.toTypedArray() as Array<T>
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* Copyright 2018 charlag
|
||||
/*
|
||||
* Copyright 2018 Tusky Contributors
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
|
@ -11,15 +12,17 @@
|
|||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
* see <http://www.gnu.org/licenses>.
|
||||
*/
|
||||
|
||||
package com.keylesspalace.tusky
|
||||
package com.keylesspalace.tusky.components.compose.ComposeActivity
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Looper.getMainLooper
|
||||
import android.widget.EditText
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import at.connyduck.calladapter.networkresult.NetworkResult
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.components.compose.ComposeActivity
|
||||
import com.keylesspalace.tusky.components.compose.ComposeViewModel
|
||||
import com.keylesspalace.tusky.components.instanceinfo.InstanceInfoRepository
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2023 Tusky Contributors
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>.
|
||||
*/
|
||||
|
||||
package com.keylesspalace.tusky.components.compose.ComposeActivity
|
||||
|
||||
import com.keylesspalace.tusky.SpanUtilsTest
|
||||
import com.keylesspalace.tusky.components.compose.ComposeActivity
|
||||
import com.keylesspalace.tusky.util.highlightSpans
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class StatusLengthTest(
|
||||
private val text: String,
|
||||
private val expectedLength: Int
|
||||
) {
|
||||
companion object {
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
@JvmStatic
|
||||
fun data(): Iterable<Any> {
|
||||
return listOf(
|
||||
arrayOf("", 0),
|
||||
arrayOf(" ", 1),
|
||||
arrayOf("123", 3),
|
||||
// "@user@server" should be treated as "@user"
|
||||
arrayOf("123 @example@example.org", 12),
|
||||
// URLs under 23 chars are treated as 23 chars
|
||||
arrayOf("123 http://example.url", 27),
|
||||
// URLs over 23 chars are treated as 23 chars
|
||||
arrayOf("123 http://urlthatislongerthan23characters.example.org", 27),
|
||||
// Short hashtags are treated as is
|
||||
arrayOf("123 #basictag", 13),
|
||||
// Long hashtags are *also* treated as is (not treated as 23, like URLs)
|
||||
arrayOf("123 #atagthatislongerthan23characters", 37)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun statusLength_matchesExpectations() {
|
||||
val spannedText = SpanUtilsTest.FakeSpannable(text)
|
||||
highlightSpans(spannedText, 0)
|
||||
|
||||
assertEquals(
|
||||
expectedLength,
|
||||
ComposeActivity.statusLength(spannedText, null, 23)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun statusLength_withCwText_matchesExpectations() {
|
||||
val spannedText = SpanUtilsTest.FakeSpannable(text)
|
||||
highlightSpans(spannedText, 0)
|
||||
|
||||
val cwText = SpanUtilsTest.FakeSpannable(
|
||||
"a @example@example.org #hashtagmention and http://example.org URL"
|
||||
)
|
||||
assertEquals(
|
||||
expectedLength + cwText.length,
|
||||
ComposeActivity.statusLength(spannedText, cwText, 23)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky
|
||||
package com.keylesspalace.tusky.components.compose.ComposeTokenizer
|
||||
|
||||
import com.keylesspalace.tusky.components.compose.ComposeTokenizer
|
||||
import org.junit.Assert
|
Loading…
Add table
Add a link
Reference in a new issue