blob: fd291b291ada0467dda039e2a6767384f4830979 [file] [log] [blame]
package io.flutter.plugin.editing;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SpellCheckerSession;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
import android.view.textservice.TextServicesManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.systemchannels.SpellCheckChannel;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.StandardMethodCodec;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@RunWith(AndroidJUnit4.class)
public class SpellCheckPluginTest {
private static void sendToBinaryMessageHandler(
BinaryMessenger.BinaryMessageHandler binaryMessageHandler, String method, Object args) {
MethodCall methodCall = new MethodCall(method, args);
ByteBuffer encodedMethodCall = StandardMethodCodec.INSTANCE.encodeMethodCall(methodCall);
binaryMessageHandler.onMessage(
(ByteBuffer) encodedMethodCall.flip(), mock(BinaryMessenger.BinaryReply.class));
}
@SuppressWarnings("deprecation")
// setMessageHandler is deprecated.
@Test
public void respondsToSpellCheckChannelMessage() {
ArgumentCaptor<BinaryMessenger.BinaryMessageHandler> binaryMessageHandlerCaptor =
ArgumentCaptor.forClass(BinaryMessenger.BinaryMessageHandler.class);
DartExecutor mockBinaryMessenger = mock(DartExecutor.class);
SpellCheckChannel.SpellCheckMethodHandler mockHandler =
mock(SpellCheckChannel.SpellCheckMethodHandler.class);
SpellCheckChannel spellCheckChannel = new SpellCheckChannel(mockBinaryMessenger);
spellCheckChannel.setSpellCheckMethodHandler(mockHandler);
verify(mockBinaryMessenger, times(1))
.setMessageHandler(any(String.class), binaryMessageHandlerCaptor.capture());
BinaryMessenger.BinaryMessageHandler binaryMessageHandler =
binaryMessageHandlerCaptor.getValue();
sendToBinaryMessageHandler(
binaryMessageHandler,
"SpellCheck.initiateSpellCheck",
Arrays.asList("en-US", "Hello, wrold!"));
verify(mockHandler)
.initiateSpellCheck(eq("en-US"), eq("Hello, wrold!"), any(MethodChannel.Result.class));
}
@Test
public void initiateSpellCheckPerformsSpellCheckWhenNoResultPending() {
SpellCheckChannel fakeSpellCheckChannel = mock(SpellCheckChannel.class);
TextServicesManager fakeTextServicesManager = mock(TextServicesManager.class);
SpellCheckPlugin spellCheckPlugin =
spy(new SpellCheckPlugin(fakeTextServicesManager, fakeSpellCheckChannel));
MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
SpellCheckerSession fakeSpellCheckerSession = mock(SpellCheckerSession.class);
when(fakeTextServicesManager.newSpellCheckerSession(
null, new Locale("en", "US"), spellCheckPlugin, true))
.thenReturn(fakeSpellCheckerSession);
spellCheckPlugin.initiateSpellCheck("en-US", "Hello, wrold!", mockResult);
verify(spellCheckPlugin).performSpellCheck("en-US", "Hello, wrold!");
}
@Test
public void initiateSpellCheckThrowsErrorWhenResultPending() {
SpellCheckChannel fakeSpellCheckChannel = mock(SpellCheckChannel.class);
TextServicesManager fakeTextServicesManager = mock(TextServicesManager.class);
SpellCheckPlugin spellCheckPlugin =
spy(new SpellCheckPlugin(fakeTextServicesManager, fakeSpellCheckChannel));
MethodChannel.Result mockPendingResult = mock(MethodChannel.Result.class);
MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
spellCheckPlugin.pendingResult = mockPendingResult;
spellCheckPlugin.initiateSpellCheck("en-US", "Hello, wrold!", mockResult);
verify(mockResult).error("error", "Previous spell check request still pending.", null);
verify(spellCheckPlugin, never()).performSpellCheck("en-US", "Hello, wrold!");
}
@Test
public void destroyClosesSpellCheckerSessionAndClearsSpellCheckMethodHandler() {
Context fakeContext = mock(Context.class);
SpellCheckChannel fakeSpellCheckChannel = mock(SpellCheckChannel.class);
TextServicesManager fakeTextServicesManager = mock(TextServicesManager.class);
when(fakeContext.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE))
.thenReturn(fakeTextServicesManager);
SpellCheckPlugin spellCheckPlugin =
spy(new SpellCheckPlugin(fakeTextServicesManager, fakeSpellCheckChannel));
SpellCheckerSession fakeSpellCheckerSession = mock(SpellCheckerSession.class);
when(fakeTextServicesManager.newSpellCheckerSession(
null, new Locale("en", "US"), spellCheckPlugin, true))
.thenReturn(fakeSpellCheckerSession);
spellCheckPlugin.performSpellCheck("en-US", "Hello, wrold!");
spellCheckPlugin.destroy();
verify(fakeSpellCheckChannel).setSpellCheckMethodHandler(isNull());
verify(fakeSpellCheckerSession).close();
}
@Test
public void performSpellCheckSendsRequestToAndroidSpellCheckService() {
Context fakeContext = mock(Context.class);
SpellCheckChannel fakeSpellCheckChannel = mock(SpellCheckChannel.class);
TextServicesManager fakeTextServicesManager = mock(TextServicesManager.class);
when(fakeContext.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE))
.thenReturn(fakeTextServicesManager);
SpellCheckPlugin spellCheckPlugin =
spy(new SpellCheckPlugin(fakeTextServicesManager, fakeSpellCheckChannel));
SpellCheckerSession fakeSpellCheckerSession = mock(SpellCheckerSession.class);
Locale english_US = new Locale("en", "US");
when(fakeTextServicesManager.newSpellCheckerSession(null, english_US, spellCheckPlugin, true))
.thenReturn(fakeSpellCheckerSession);
int maxSuggestions = 5;
ArgumentCaptor<TextInfo[]> textInfosCaptor = ArgumentCaptor.forClass(TextInfo[].class);
ArgumentCaptor<Integer> maxSuggestionsCaptor = ArgumentCaptor.forClass(Integer.class);
spellCheckPlugin.performSpellCheck("en-US", "Hello, wrold!");
verify(fakeSpellCheckerSession)
.getSentenceSuggestions(textInfosCaptor.capture(), maxSuggestionsCaptor.capture());
assertEquals("Hello, wrold!", textInfosCaptor.getValue()[0].getText());
assertEquals(Integer.valueOf(maxSuggestions), maxSuggestionsCaptor.getValue());
}
@Test
public void performSpellCheckCreatesNewSpellCheckerSession() {
Context fakeContext = mock(Context.class);
SpellCheckChannel fakeSpellCheckChannel = mock(SpellCheckChannel.class);
TextServicesManager fakeTextServicesManager = mock(TextServicesManager.class);
when(fakeContext.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE))
.thenReturn(fakeTextServicesManager);
SpellCheckPlugin spellCheckPlugin =
spy(new SpellCheckPlugin(fakeTextServicesManager, fakeSpellCheckChannel));
SpellCheckerSession fakeSpellCheckerSession = mock(SpellCheckerSession.class);
Locale english_US = new Locale("en", "US");
when(fakeTextServicesManager.newSpellCheckerSession(null, english_US, spellCheckPlugin, true))
.thenReturn(fakeSpellCheckerSession);
spellCheckPlugin.performSpellCheck("en-US", "Hello, worl!");
spellCheckPlugin.performSpellCheck("en-US", "Hello, world!");
verify(fakeTextServicesManager, times(1))
.newSpellCheckerSession(null, english_US, spellCheckPlugin, true);
}
@Test
public void onGetSentenceSuggestionsResultsWithSuccessAndNoResultsProperly() {
TextServicesManager fakeTextServicesManager = mock(TextServicesManager.class);
SpellCheckChannel fakeSpellCheckChannel = mock(SpellCheckChannel.class);
SpellCheckPlugin spellCheckPlugin =
spy(new SpellCheckPlugin(fakeTextServicesManager, fakeSpellCheckChannel));
MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
spellCheckPlugin.pendingResult = mockResult;
spellCheckPlugin.onGetSentenceSuggestions(new SentenceSuggestionsInfo[] {});
verify(mockResult).success(new ArrayList<HashMap<String, Object>>());
}
@Test
public void onGetSentenceSuggestionsResultsWithSuccessAndResultsProperly() {
TextServicesManager fakeTextServicesManager = mock(TextServicesManager.class);
SpellCheckChannel fakeSpellCheckChannel = mock(SpellCheckChannel.class);
SpellCheckPlugin spellCheckPlugin =
spy(new SpellCheckPlugin(fakeTextServicesManager, fakeSpellCheckChannel));
MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
spellCheckPlugin.pendingResult = mockResult;
spellCheckPlugin.onGetSentenceSuggestions(
new SentenceSuggestionsInfo[] {
new SentenceSuggestionsInfo(
(new SuggestionsInfo[] {
new SuggestionsInfo(
SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO,
new String[] {"world", "word", "old"})
}),
new int[] {7},
new int[] {5})
});
ArrayList<HashMap<String, Object>> expectedResults = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> expectedResult = new HashMap<String, Object>();
expectedResult.put(SpellCheckPlugin.START_INDEX_KEY, 7);
expectedResult.put(SpellCheckPlugin.END_INDEX_KEY, 12);
expectedResult.put(
SpellCheckPlugin.SUGGESTIONS_KEY,
new ArrayList<String>(Arrays.asList("world", "word", "old")));
expectedResults.add(expectedResult);
verify(mockResult).success(expectedResults);
}
@Test
public void onGetSentenceSuggestionsResultsWithSuccessAndNoResultsWhenSuggestionsAreInvalid() {
TextServicesManager fakeTextServicesManager = mock(TextServicesManager.class);
SpellCheckChannel fakeSpellCheckChannel = mock(SpellCheckChannel.class);
SpellCheckPlugin spellCheckPlugin =
spy(new SpellCheckPlugin(fakeTextServicesManager, fakeSpellCheckChannel));
MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
spellCheckPlugin.pendingResult = mockResult;
spellCheckPlugin.onGetSentenceSuggestions(
new SentenceSuggestionsInfo[] {
new SentenceSuggestionsInfo(
(new SuggestionsInfo[] {
new SuggestionsInfo(
SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO,
// This is the suggestion that may be provided by the Samsung spell checker:
new String[] {""})
}),
new int[] {7},
new int[] {5})
});
verify(mockResult).success(new ArrayList<HashMap<String, Object>>());
}
@Test
public void onGetSentenceSuggestionsResultsWithSuccessAndNoResultsWhenSuggestionsAreInvalid2() {
TextServicesManager fakeTextServicesManager = mock(TextServicesManager.class);
SpellCheckChannel fakeSpellCheckChannel = mock(SpellCheckChannel.class);
SpellCheckPlugin spellCheckPlugin =
spy(new SpellCheckPlugin(fakeTextServicesManager, fakeSpellCheckChannel));
MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
spellCheckPlugin.pendingResult = mockResult;
spellCheckPlugin.onGetSentenceSuggestions(
new SentenceSuggestionsInfo[] {
// This "suggestion" may be provided by the Samsung spell checker:
null
});
verify(mockResult).success(new ArrayList<HashMap<String, Object>>());
}
}