5#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.h"
7#import <OCMock/OCMock.h>
8#import <XCTest/XCTest.h>
26@property(strong, nonatomic)
35- (void)mockResultRange:(NSRange)range
36 suggestions:(nonnull NSArray<NSString*>*)suggestions
37 withStartingIndex:(NSInteger)startingIndex;
49 _startingIndexToRange = [[NSMutableDictionary alloc] init];
50 _rangeToSuggestions = [[NSMutableDictionary alloc] init];
55- (void)mockResultRange:(NSRange)range
56 suggestions:(NSArray<NSString*>*)suggestions
57 withStartingIndex:(NSInteger)startingIndex {
58 NSValue* valueForRange = [NSValue valueWithRange:range];
59 self.startingIndexToRange[@(startingIndex)] = valueForRange;
60 NSString* rangeString = NSStringFromRange(valueForRange.rangeValue);
61 self.rangeToSuggestions[rangeString] = suggestions;
65 [
self.startingIndexToRange removeAllObjects];
66 [
self.rangeToSuggestions removeAllObjects];
69#pragma mark UITextChecker Overrides
71- (NSRange)rangeOfMisspelledWordInString:(NSString*)stringToCheck
73 startingAt:(NSInteger)startingOffset
75 language:(NSString*)language {
76 return self.startingIndexToRange[@(startingOffset)].rangeValue;
79- (NSArray<NSString*>*)guessesForWordRange:(NSRange)range
80 inString:(NSString*)string
81 language:(NSString*)language {
82 return self.rangeToSuggestions[NSStringFromRange(range)];
94@property(strong, nonatomic)
id mockMethodChannel;
96@property(strong, nonatomic)
id mockTextChecker;
97@property(strong, nonatomic)
id partialMockPlugin;
110 OCMStub([
self.mockMethodChannel invokeMethod:[OCMArg
any]
111 arguments:[OCMArg
any]
113 .andDo(^(NSInvocation* invocation) {
117 [invocation getArgument:&name atIndex:2];
118 [invocation getArgument:&args atIndex:3];
119 [invocation getArgument:&result atIndex:4];
122 [weakPlugin handleMethodCall:methodCall result:result];
137 self.partialMockPlugin = OCMPartialMock(
self.plugin);
138 OCMStub([
self.partialMockPlugin textChecker]).andReturn(
self.mockTextChecker);
139 id textCheckerClassMock = OCMClassMock([UITextChecker
class]);
140 [[[textCheckerClassMock stub] andReturn:@[ @"en" ]] availableLanguages];
141 NSArray* suggestions1 = @[ @"suggestion 1", @"suggestion 2" ];
142 NSArray* suggestions2 = @[ @"suggestion 3", @"suggestion 4" ];
144 [
self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(0, 5)
146 suggestions:suggestions1];
148 [
self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(5, 5)
150 suggestions:suggestions2];
152 [
self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(NSNotFound, 0)
155 __block NSArray* capturedResult;
156 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
157 arguments:@[ @"en", @"ksajlkdf aslkdfl kasdf asdfjk" ]
158 result:^(id _Nullable result) {
159 capturedResult = result;
161 XCTAssertTrue(capturedResult.count == 2);
162 NSDictionary* suggestionsJSON1 = capturedResult.firstObject;
163 XCTAssertEqualObjects(suggestionsJSON1[
@"startIndex"], @0);
164 XCTAssertEqualObjects(suggestionsJSON1[
@"endIndex"], @5);
165 XCTAssertEqualObjects(suggestionsJSON1[
@"suggestions"], suggestions1);
166 NSDictionary* suggestionsJSON2 = capturedResult[1];
167 XCTAssertEqualObjects(suggestionsJSON2[
@"startIndex"], @5);
168 XCTAssertEqualObjects(suggestionsJSON2[
@"endIndex"], @10);
169 XCTAssertEqualObjects(suggestionsJSON2[
@"suggestions"], suggestions2);
170 [
self.mockTextChecker reset];
171 [textCheckerClassMock stopMocking];
177 self.partialMockPlugin = OCMPartialMock(
self.plugin);
178 OCMStub([
self.partialMockPlugin textChecker]).andReturn(
self.mockTextChecker);
179 id textCheckerClassMock = OCMClassMock([UITextChecker
class]);
180 [[[textCheckerClassMock stub] andReturn:@[ @"en" ]] availableLanguages];
181 NSArray* suggestions1 = @[ @"suggestion 1", @"suggestion 2" ];
182 NSArray* suggestions2 = @[ @"suggestion 3", @"suggestion 4" ];
184 [
self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(0, 5)
186 suggestions:suggestions1];
188 [
self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(6, 4)
190 suggestions:suggestions2];
192 __block NSArray* capturedResult;
193 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
194 arguments:@[ @"en", @"hejjo abcd" ]
195 result:^(id _Nullable result) {
196 capturedResult = result;
198 XCTAssertTrue(capturedResult.count == 2);
199 NSDictionary* suggestionsJSON1 = capturedResult.firstObject;
200 XCTAssertEqualObjects(suggestionsJSON1[
@"startIndex"], @0);
201 XCTAssertEqualObjects(suggestionsJSON1[
@"endIndex"], @5);
202 XCTAssertEqualObjects(suggestionsJSON1[
@"suggestions"], suggestions1);
203 NSDictionary* suggestionsJSON2 = capturedResult[1];
204 XCTAssertEqualObjects(suggestionsJSON2[
@"startIndex"], @6);
205 XCTAssertEqualObjects(suggestionsJSON2[
@"endIndex"], @10);
206 XCTAssertEqualObjects(suggestionsJSON2[
@"suggestions"], suggestions2);
207 [
self.mockTextChecker reset];
208 [textCheckerClassMock stopMocking];
212 self.partialMockPlugin = OCMPartialMock(
self.plugin);
213 OCMStub([
self.partialMockPlugin textChecker]).andReturn(
self.mockTextChecker);
214 id textCheckerClassMock = OCMClassMock([UITextChecker
class]);
215 [[[textCheckerClassMock stub] andReturn:@[ @"en" ]] availableLanguages];
216 NSArray* suggestions1 = @[ @"suggestion 1", @"suggestion 2" ];
218 [
self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(0, 5)
220 suggestions:suggestions1];
222 __block NSArray* capturedResult;
223 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
224 arguments:@[ @"en", @"hejjo" ]
225 result:^(id _Nullable result) {
226 capturedResult = result;
228 XCTAssertTrue(capturedResult.count == 1);
229 NSDictionary* suggestionsJSON1 = capturedResult.firstObject;
230 XCTAssertEqualObjects(suggestionsJSON1[
@"startIndex"], @0);
231 XCTAssertEqualObjects(suggestionsJSON1[
@"endIndex"], @5);
232 XCTAssertEqualObjects(suggestionsJSON1[
@"suggestions"], suggestions1);
233 [
self.mockTextChecker reset];
234 [textCheckerClassMock stopMocking];
238 self.partialMockPlugin = OCMPartialMock(
self.plugin);
239 OCMStub([
self.partialMockPlugin textChecker]).andReturn(
self.mockTextChecker);
240 id textCheckerClassMock = OCMClassMock([UITextChecker
class]);
241 [[[textCheckerClassMock stub] andReturn:@[ @"en" ]] availableLanguages];
242 [
self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(NSNotFound, 0)
245 __block
id capturedResult;
246 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
247 arguments:@[ @"en", @"helloo" ]
248 result:^(id _Nullable result) {
249 capturedResult = result;
251 XCTAssertEqualObjects(capturedResult, @[]);
252 [textCheckerClassMock stopMocking];
256 self.partialMockPlugin = OCMPartialMock(
self.plugin);
257 OCMStub([
self.partialMockPlugin textChecker]).andReturn(
self.mockTextChecker);
258 id textCheckerClassMock = OCMClassMock([UITextChecker
class]);
259 [[[textCheckerClassMock stub] andReturn:@[ @"en" ]] availableLanguages];
260 [
self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(0, 5)
263 __block
id capturedResult;
264 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
265 arguments:@[ @"xx", @"helloo" ]
266 result:^(id _Nullable result) {
267 capturedResult = result;
269 XCTAssertNil(capturedResult);
270 [textCheckerClassMock stopMocking];
274 self.partialMockPlugin = OCMPartialMock(
self.plugin);
275 OCMStub([
self.partialMockPlugin textChecker]).andReturn(
self.mockTextChecker);
276 id textCheckerClassMock = OCMClassMock([UITextChecker
class]);
277 [[[textCheckerClassMock stub] andReturn:@[ @"en_US" ]] availableLanguages];
278 NSArray* suggestions1 = @[ @"suggestion 1", @"suggestion 2" ];
280 [
self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(0, 5)
282 suggestions:suggestions1];
283 __block NSArray* capturedResult;
284 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
285 arguments:@[ @"en-us", @"hejjo" ]
286 result:^(id _Nullable result) {
287 capturedResult = result;
289 NSDictionary* suggestionsJSON1 = capturedResult.firstObject;
290 XCTAssertEqualObjects(suggestionsJSON1[
@"startIndex"], @0);
291 XCTAssertEqualObjects(suggestionsJSON1[
@"endIndex"], @5);
292 XCTAssertEqualObjects(suggestionsJSON1[
@"suggestions"], suggestions1);
293 [textCheckerClassMock stopMocking];
297 self.partialMockPlugin = OCMPartialMock(
self.plugin);
298 OCMStub([
self.partialMockPlugin textChecker]).andReturn(
self.mockTextChecker);
301 [
self.partialMockPlugin stopMocking];
303 id textCheckerClassMock = OCMClassMock([UITextChecker
class]);
304 [[[textCheckerClassMock stub] andReturn:@[ @"en" ]] availableLanguages];
305 __block
id capturedResult;
306 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
307 arguments:@[ @"en", @"" ]
308 result:^(id _Nullable result) {
309 capturedResult = result;
311 XCTAssertEqualObjects(capturedResult, @[]);
312 [textCheckerClassMock stopMocking];
316 self.partialMockPlugin = OCMPartialMock(
self.plugin);
317 OCMStub([
self.partialMockPlugin textChecker]).andReturn(
self.mockTextChecker);
318 id textCheckerClassMock = OCMClassMock([UITextChecker
class]);
319 [[[textCheckerClassMock stub] andReturn:@[ @"en" ]] availableLanguages];
320 __block
id capturedResult;
321 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
322 arguments:@[ @"en", [NSNull null] ]
323 result:^(id _Nullable result) {
324 capturedResult = result;
326 XCTAssertNil(capturedResult);
327 [textCheckerClassMock stopMocking];
331 self.partialMockPlugin = OCMPartialMock(
self.plugin);
332 OCMStub([
self.partialMockPlugin textChecker]).andReturn(
self.mockTextChecker);
333 id textCheckerClassMock = OCMClassMock([UITextChecker
class]);
334 [[[textCheckerClassMock stub] andReturn:@[ @"en" ]] availableLanguages];
335 __block
id capturedResult;
336 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
337 arguments:@[ [NSNull null], @"some string" ]
338 result:^(id _Nullable result) {
339 capturedResult = result;
341 XCTAssertNil(capturedResult);
342 [textCheckerClassMock stopMocking];
346 XCTAssertNil([
self.plugin textChecker]);
347 __block
id capturedResult;
348 [
self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck"
349 arguments:@[ [NSNull null], @"some string" ]
350 result:^(id _Nullable result) {
351 capturedResult = result;
353 XCTAssertNotNil([
self.plugin textChecker]);
356- (void)mockUITextCheckerWithExpectedMisspelledWordRange:(NSRange)expectedRange
357 startingIndex:(NSInteger)startingIndex
358 suggestions:(NSArray*)suggestions {
359 [
self.mockTextChecker mockResultRange:expectedRange
360 suggestions:suggestions
361 withStartingIndex:startingIndex];
void(^ FlutterResult)(id _Nullable result)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
void testStopFindingMoreWhenTheLastWordIsMisspelled()
void testUITextCheckerIsInitializedAfterMethodChannelCall()
void testStopFindingMoreWhenTheWholeStringIsAMisspelledWord()
void testSupportSubLanguage()
void testNullStringArgumentShouldReturnNilResults()
void testInitiateSpellCheckWithNoMisspelledWord()
void testEmptyStringShouldReturnEmptyResults()
void testNullLanguageArgumentShouldReturnNilResults()
void testFindAllSpellCheckSuggestionsForText()
void testUnsupportedLanguageShouldReturnNil()
UITextChecker * textChecker
NSMutableDictionary< NSNumber *, NSValue * > * startingIndexToRange
NSMutableDictionary< NSString *, NSArray< NSString * > * > * rangeToSuggestions
DEF_SWITCHES_START aot vmservice shared library name
SIT bool any(const Vec< 1, T > &x)