Fix #4347: Remove leading and trailing spaces in title (#5141)

* Update method to remove leading whitespace

* Update test cases testing remove whitespace method

* Remove unused whitespace check method

* Add comment about use of strip and trim in dealing with whitespace
This commit is contained in:
Chan Jun Da 2023-02-10 15:31:45 +08:00 committed by GitHub
parent 654a0fce33
commit f85efeba97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 42 deletions

View file

@ -1,7 +1,6 @@
package fr.free.nrw.commons.upload;
import android.app.Dialog;
import android.content.Intent;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
@ -23,7 +22,6 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import com.google.android.material.textfield.TextInputLayout;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.contributions.MainActivity;
import fr.free.nrw.commons.recentlanguages.Language;
import fr.free.nrw.commons.recentlanguages.RecentLanguagesAdapter;
import fr.free.nrw.commons.recentlanguages.RecentLanguagesDao;
@ -32,10 +30,8 @@ import fr.free.nrw.commons.utils.AbstractTextWatcher;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.regex.Pattern;
import javax.inject.Inject;
import timber.log.Timber;
public class UploadMediaDetailAdapter extends RecyclerView.Adapter<UploadMediaDetailAdapter.ViewHolder> {
@ -198,7 +194,8 @@ public class UploadMediaDetailAdapter extends RecyclerView.Adapter<UploadMediaDe
removeButton.setOnClickListener(v -> removeDescription(uploadMediaDetail, position));
captionListener = new AbstractTextWatcher(
captionText -> uploadMediaDetails.get(position).setCaptionText(convertIdeographicSpaceToLatinSpace(removeTrailingWhitespace(captionText))));
captionText -> uploadMediaDetails.get(position).setCaptionText(convertIdeographicSpaceToLatinSpace(
removeLeadingAndTrailingWhitespace(captionText))));
descriptionListener = new AbstractTextWatcher(
descriptionText -> uploadMediaDetails.get(position).setDescriptionText(descriptionText));
captionItemEditText.addTextChangedListener(captionListener);
@ -421,28 +418,35 @@ public class UploadMediaDetailAdapter extends RecyclerView.Adapter<UploadMediaDe
}
/**
* Checks if the source string contains trailing whitespace
* Removes any leading and trailing whitespace from the source text.
* @param source input string
* @return true if contains trailing whitespace and false otherwise
* @return a string without leading and trailing whitespace
*/
public Boolean checkTrailingWhitespace(String source) {
int len = source.length();
if (len == 0) {
return false;
public String removeLeadingAndTrailingWhitespace(String source) {
// This method can be replaced with the inbuilt String::strip when updated to JDK 11.
// Note that String::trim does not adequately remove all whitespace chars.
int firstNonWhitespaceIndex = 0;
while (firstNonWhitespaceIndex < source.length()) {
if (Character.isWhitespace(source.charAt(firstNonWhitespaceIndex))) {
firstNonWhitespaceIndex++;
} else {
break;
}
}
if (firstNonWhitespaceIndex == source.length()) {
return "";
}
return Character.isWhitespace(source.charAt(len - 1));
}
/**
* Removes any trailing whitespace from the source text.
* @param source input string
* @return a string without trailing whitespace
*/
public String removeTrailingWhitespace(String source) {
while (checkTrailingWhitespace(source)) {
source = source.substring(0, source.length() - 1);
int lastNonWhitespaceIndex = source.length() - 1;
while (lastNonWhitespaceIndex > firstNonWhitespaceIndex) {
if (Character.isWhitespace(source.charAt(lastNonWhitespaceIndex))) {
lastNonWhitespaceIndex--;
} else {
break;
}
}
return source;
return source.substring(firstNonWhitespaceIndex, lastNonWhitespaceIndex + 1);
}
/**

View file

@ -248,39 +248,39 @@ class UploadMediaDetailAdapterUnitTest {
}
@Test
fun testRemoveTrailingWhitespace() {
fun testRemoveLeadingAndTrailingWhitespace() {
// empty space
val test1 = "test "
val test1 = " test "
val expected1 = "test"
Assert.assertTrue(viewHolder.checkTrailingWhitespace(test1));
Assert.assertEquals(expected1, viewHolder.removeTrailingWhitespace(test1))
Assert.assertEquals(expected1, viewHolder.removeLeadingAndTrailingWhitespace(test1))
val test2 = "test test "
val test2 = " test test "
val expected2 = "test test"
Assert.assertTrue(viewHolder.checkTrailingWhitespace(test2));
Assert.assertEquals(expected2, viewHolder.removeTrailingWhitespace(test2))
Assert.assertEquals(expected2, viewHolder.removeLeadingAndTrailingWhitespace(test2))
// No whitespace
val test3 = "No trailing space";
val expected3 = "No trailing space";
Assert.assertFalse(viewHolder.checkTrailingWhitespace(test3))
Assert.assertEquals(expected3, viewHolder.removeTrailingWhitespace(test3))
Assert.assertEquals(expected3, viewHolder.removeLeadingAndTrailingWhitespace(test3))
// blank string
val test4 = " \r \t "
val expected4 = "";
Assert.assertEquals(expected4, viewHolder.removeLeadingAndTrailingWhitespace(test4))
}
@Test
fun testRemoveTrailingInstanceTab() {
val test = "test\t"
fun testRemoveLeadingAndTrailingInstanceTab() {
val test = "\ttest\t"
val expected = "test"
Assert.assertTrue(viewHolder.checkTrailingWhitespace(test));
Assert.assertEquals(expected, viewHolder.removeTrailingWhitespace(test))
Assert.assertEquals(expected, viewHolder.removeLeadingAndTrailingWhitespace(test))
}
@Test
fun testRemoveTrailingCarriageReturn() {
val test = "test\r"
fun testRemoveLeadingAndTrailingCarriageReturn() {
val test = "\rtest\r"
val expected = "test"
Assert.assertTrue(viewHolder.checkTrailingWhitespace(test));
Assert.assertEquals(expected, viewHolder.removeTrailingWhitespace(test))
Assert.assertEquals(expected, viewHolder.removeLeadingAndTrailingWhitespace(test))
}
@Test
@ -289,9 +289,8 @@ class UploadMediaDetailAdapterUnitTest {
val expected1 = "テスト テスト"
Assert.assertEquals(expected1, viewHolder.convertIdeographicSpaceToLatinSpace(test1));
val test2 = "テスト \r \t "
val test2 = " \r \t テスト \r \t "
val expected2 = "テスト"
Assert.assertTrue(viewHolder.checkTrailingWhitespace(test2));
Assert.assertEquals(expected2, viewHolder.removeTrailingWhitespace(test2))
Assert.assertEquals(expected2, viewHolder.removeLeadingAndTrailingWhitespace(test2))
}
}