mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-09-20 00:35:47 +01:00
Keep the account ID visual transformation length-preserving.
This commit is contained in:
committed by
Alex Hart
parent
4408ab3386
commit
e3ff228684
+5
-2
@@ -16,14 +16,17 @@ internal object AccountIdFormat {
|
||||
/** Offsets in a raw account ID that a dash is inserted in front of. */
|
||||
private val DASH_OFFSETS = intArrayOf(8, 12, 16, 20)
|
||||
|
||||
/** Rewrites a raw account ID with the dashes a UUID is normally written with. */
|
||||
/**
|
||||
* Rewrites a raw account ID with the dashes and uppercasing a UUID is normally written with.
|
||||
*/
|
||||
fun dashed(accountId: String): String {
|
||||
return buildString {
|
||||
for ((index, character) in accountId.withIndex()) {
|
||||
if (index in DASH_OFFSETS) {
|
||||
append('-')
|
||||
}
|
||||
append(character)
|
||||
// Uppercase on a per-character basis so as to not screw up offsets
|
||||
append(character.uppercaseChar())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -470,7 +470,7 @@ internal object AccountIdVisualTransformation : VisualTransformation {
|
||||
|
||||
override fun filter(text: AnnotatedString): TransformedText {
|
||||
return TransformedText(
|
||||
text = AnnotatedString(AccountIdFormat.dashed(text.text).uppercase()),
|
||||
text = AnnotatedString(AccountIdFormat.dashed(text.text)),
|
||||
offsetMapping = AccountIdOffsetMapping(text.length)
|
||||
)
|
||||
}
|
||||
|
||||
+31
@@ -15,6 +15,9 @@ class AccountIdVisualTransformationTest {
|
||||
companion object {
|
||||
private const val FULL_KEY = "a6b284822e3283d07f2391360a4c2b91"
|
||||
private const val FULL_KEY_FORMATTED = "A6B28482-2E32-83D0-7F23-91360A4C2B91"
|
||||
|
||||
/** Characters whose whole-string uppercase mapping is longer than the character itself. */
|
||||
private val LENGTH_CHANGING_CHARACTERS = listOf('ß', 'ʼn', 'ff', 'fi', 'ǰ')
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -54,5 +57,33 @@ class AccountIdVisualTransformationTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `characters that uppercase into multiple characters stay one character long`() {
|
||||
for (character in LENGTH_CHANGING_CHARACTERS) {
|
||||
assertThat(transform(character.toString()).length).isEqualTo(1)
|
||||
assertThat(transform("a6b2848$character")).isEqualTo("A6B2848${character.uppercaseChar()}")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `every cursor position round trips even when the key holds characters that normally expand`() {
|
||||
for (character in LENGTH_CHANGING_CHARACTERS) {
|
||||
val key = character + FULL_KEY.drop(1)
|
||||
val mapping = AccountIdVisualTransformation.filter(AnnotatedString(key)).offsetMapping
|
||||
val transformedLength = transform(key).length
|
||||
|
||||
for (offset in 0..key.length) {
|
||||
val transformed = mapping.originalToTransformed(offset)
|
||||
|
||||
assertThat(transformed in 0..transformedLength).isEqualTo(true)
|
||||
assertThat(mapping.transformedToOriginal(transformed)).isEqualTo(offset)
|
||||
}
|
||||
|
||||
for (offset in 0..transformedLength) {
|
||||
assertThat(mapping.transformedToOriginal(offset) in 0..key.length).isEqualTo(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun transform(text: String): String = AccountIdVisualTransformation.filter(AnnotatedString(text)).text.text
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user