Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 4cbce78

Browse files
committed
Clean up
1 parent 3928860 commit 4cbce78

File tree

2 files changed

+31
-29
lines changed

2 files changed

+31
-29
lines changed

shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -996,11 +996,11 @@ - (void)updateEditingState {
996996
@"text" : [NSString stringWithString:self.text],
997997
};
998998

999-
// Debounce calls to updateEditingClient. This makes iOS text editing behave
1000-
// more similarly to Android's, which has built-in event batching, and avoids
1001-
// race conditions. The delay value was chosen to be imperceptible by the user
1002-
// but still long enough to allow the framework to respond with formatting
1003-
// updates, thereby avoiding common race conditions.
999+
// Debounce calls to updateEditingClient on the leading edge. This makes iOS
1000+
// text editing behave more similarly to Android's, which has built-in event
1001+
// batching, and avoids race conditions. The delay value was chosen to be
1002+
// imperceptible by the user but still long enough to allow the framework to
1003+
// respond with formatting updates, thereby avoiding common race conditions.
10041004
if (_latestState == nil) {
10051005
_latestState = state;
10061006
[self updateEditingClient];

shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.m

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -174,19 +174,13 @@ - (void)testUITextInputCallsUpdateEditingStateOnce {
174174
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] init];
175175
inputView.textInputDelegate = engine;
176176

177-
XCTestExpectation* expectation2 = [self expectationWithDescription:@"called updateEditingClient twice"];
178-
XCTestExpectation* expectation4 = [self expectationWithDescription:@"called updateEditingClient four times"];
179-
XCTestExpectation* expectation6 = [self expectationWithDescription:@"called updateEditingClient six times"];
177+
__block XCTestExpectation* expectation;
180178
__block int updateCount = 0;
181179
OCMStub([engine updateEditingClient:0 withState:[OCMArg isNotNil]])
182180
.andDo(^(NSInvocation* invocation) {
183181
updateCount++;
184-
if (updateCount == 2) {
185-
[expectation2 fulfill];
186-
} else if (updateCount == 4) {
187-
[expectation4 fulfill];
188-
} else if (updateCount == 6) {
189-
[expectation6 fulfill];
182+
if (expectation != nil) {
183+
[expectation fulfill];
190184
}
191185
});
192186

@@ -195,10 +189,12 @@ - (void)testUITextInputCallsUpdateEditingStateOnce {
195189
// because calls to updateEditingState are debounced on the leading edge.
196190
XCTAssertEqual(updateCount, 1);
197191

192+
expectation = [self expectationWithDescription:@"called updateEditingClient"];
198193
[inputView deleteBackward];
199194
// Due to the debouncing, this call will happen after a short delay.
200195
XCTAssertEqual(updateCount, 1);
201-
[self waitForExpectations:@[expectation2] timeout:1];
196+
[self waitForExpectations:@[expectation] timeout:1];
197+
expectation = nil;
202198
XCTAssertEqual(updateCount, 2);
203199

204200
// Subsequent calls follow this pattern of leading edge debouncing. Now that
@@ -208,32 +204,36 @@ - (void)testUITextInputCallsUpdateEditingStateOnce {
208204
inputView.selectedTextRange = [FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)];
209205
XCTAssertEqual(updateCount, 3);
210206

207+
expectation = [self expectationWithDescription:@"called updateEditingClient"];
211208
[inputView replaceRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]
212209
withText:@"replace text"];
213210
XCTAssertEqual(updateCount, 3);
214-
[self waitForExpectations:@[expectation4] timeout:1];
211+
[self waitForExpectations:@[expectation] timeout:1];
212+
expectation = nil;
215213
XCTAssertEqual(updateCount, 4);
216214

217215
[inputView setMarkedText:@"marked text" selectedRange:NSMakeRange(0, 1)];
218216
XCTAssertEqual(updateCount, 5);
219217

218+
expectation = [self expectationWithDescription:@"called updateEditingClient"];
220219
[inputView unmarkText];
221220
XCTAssertEqual(updateCount, 5);
222-
[self waitForExpectations:@[expectation6] timeout:1];
221+
[self waitForExpectations:@[expectation] timeout:1];
222+
expectation = nil;
223223
XCTAssertEqual(updateCount, 6);
224224
}
225225

226226
- (void)testUITextInputCallsToUpdateEditingStateAreDebounced {
227227
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] init];
228228
inputView.textInputDelegate = engine;
229229

230-
XCTestExpectation* expectation2 = [self expectationWithDescription:@"called updateEditingClient twice"];
230+
__block XCTestExpectation* expectation;
231231
__block int updateCount = 0;
232232
OCMStub([engine updateEditingClient:0 withState:[OCMArg isNotNil]])
233233
.andDo(^(NSInvocation* invocation) {
234234
updateCount++;
235-
if (updateCount == 2) {
236-
[expectation2 fulfill];
235+
if (expectation != nil) {
236+
[expectation fulfill];
237237
}
238238
});
239239

@@ -243,11 +243,12 @@ - (void)testUITextInputCallsToUpdateEditingStateAreDebounced {
243243
XCTAssertEqual(updateCount, 1);
244244

245245
// These calls will be batched and come through after a short delay.
246+
expectation = [self expectationWithDescription:@"called updateEditingClient twice"];
246247
[inputView deleteBackward];
247248
[inputView deleteBackward];
248249
[inputView deleteBackward];
249250
XCTAssertEqual(updateCount, 1);
250-
[self waitForExpectations:@[expectation2] timeout:1];
251+
[self waitForExpectations:@[expectation] timeout:1];
251252
XCTAssertEqual(updateCount, 2);
252253
XCTAssertTrue([inputView.text isEqualToString:@"text to ins"]);
253254
}
@@ -366,16 +367,13 @@ - (void)testUpdateEditingClientSelectionClamping {
366367
inputView.textInputDelegate = engine;
367368

368369
// Debounced calls need to be waited for using these expectations.
369-
XCTestExpectation* expectation2 = [self expectationWithDescription:@"called updateEditingClient twice"];
370-
XCTestExpectation* expectation4 = [self expectationWithDescription:@"called updateEditingClient four times"];
370+
__block XCTestExpectation* expectation;
371371
__block int updateCount = 0;
372372
OCMStub([engine updateEditingClient:0 withState:[OCMArg isNotNil]])
373373
.andDo(^(NSInvocation* invocation) {
374374
updateCount++;
375-
if (updateCount == 2) {
376-
[expectation2 fulfill];
377-
} else if (updateCount == 4) {
378-
[expectation4 fulfill];
375+
if (expectation != nil) {
376+
[expectation fulfill];
379377
}
380378
});
381379

@@ -393,14 +391,16 @@ - (void)testUpdateEditingClientSelectionClamping {
393391
}]]);
394392

395393
// Needs clamping.
394+
expectation = [self expectationWithDescription:@"called updateEditingClient"];
396395
[inputView setTextInputState:@{
397396
@"text" : @"SELECTION",
398397
@"selectionBase" : @0,
399398
@"selectionExtent" : @9999
400399
}];
401400
[inputView updateEditingState];
402401

403-
[self waitForExpectations:@[expectation2] timeout:1];
402+
[self waitForExpectations:@[expectation] timeout:1];
403+
expectation = nil;
404404
OCMVerify([engine updateEditingClient:0
405405
withState:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
406406
return ([state[@"selectionBase"] intValue]) == 0 &&
@@ -418,13 +418,15 @@ - (void)testUpdateEditingClientSelectionClamping {
418418
}]]);
419419

420420
// Both ends need clamping.
421+
expectation = [self expectationWithDescription:@"called updateEditingClient"];
421422
[inputView setTextInputState:@{
422423
@"text" : @"SELECTION",
423424
@"selectionBase" : @9999,
424425
@"selectionExtent" : @9999
425426
}];
426427
[inputView updateEditingState];
427-
[self waitForExpectations:@[expectation4] timeout:1];
428+
[self waitForExpectations:@[expectation] timeout:1];
429+
expectation = nil;
428430
OCMVerify([engine updateEditingClient:0
429431
withState:[OCMArg checkWithBlock:^BOOL(NSDictionary* state) {
430432
return ([state[@"selectionBase"] intValue]) == 9 &&

0 commit comments

Comments
 (0)