Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
32b9c2f0
Unverified
Commit
32b9c2f0
authored
Feb 05, 2019
by
xster
Committed by
GitHub
Feb 05, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add more RenderEditable test coverage (#27003)
parent
37108c4c
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1111 additions
and
824 deletions
+1111
-824
editable.dart
packages/flutter/lib/src/rendering/editable.dart
+1
-1
editable_text.dart
packages/flutter/lib/src/widgets/editable_text.dart
+13
-9
text_field_test.dart
packages/flutter/test/material/text_field_test.dart
+21
-20
editable_test.dart
packages/flutter/test/rendering/editable_test.dart
+63
-76
editable_text_cursor_test.dart
packages/flutter/test/widgets/editable_text_cursor_test.dart
+584
-0
editable_text_test.dart
packages/flutter/test/widgets/editable_text_test.dart
+429
-718
No files found.
packages/flutter/lib/src/rendering/editable.dart
View file @
32b9c2f0
...
...
@@ -1516,7 +1516,7 @@ class RenderEditable extends RenderBox {
_textPainter
.
paint
(
context
.
canvas
,
effectiveOffset
);
if
(
_selection
!=
null
&&
!
_floatingCursorOn
)
{
if
(
_selection
.
isCollapsed
&&
cursorColor
!=
null
&&
_hasFocus
)
{
if
(
_selection
.
isCollapsed
&&
_showCursor
.
value
&&
cursorColor
!=
null
)
{
_paintCaret
(
context
.
canvas
,
effectiveOffset
,
_selection
.
extent
);
}
else
if
(!
_selection
.
isCollapsed
&&
_selectionColor
!=
null
)
{
_selectionRects
??=
_textPainter
.
getBoxesForSelection
(
_selection
);
...
...
packages/flutter/lib/src/widgets/editable_text.dart
View file @
32b9c2f0
...
...
@@ -565,7 +565,8 @@ class EditableText extends StatefulWidget {
/// State for a [EditableText].
class
EditableTextState
extends
State
<
EditableText
>
with
AutomaticKeepAliveClientMixin
<
EditableText
>,
WidgetsBindingObserver
,
TickerProviderStateMixin
<
EditableText
>
implements
TextInputClient
,
TextSelectionDelegate
{
Timer
_cursorTimer
;
final
ValueNotifier
<
bool
>
_showCursor
=
ValueNotifier
<
bool
>(
false
);
bool
_targetCursorVisibility
=
false
;
final
ValueNotifier
<
bool
>
_cursorVisibilityNotifier
=
ValueNotifier
<
bool
>(
true
);
final
GlobalKey
_editableKey
=
GlobalKey
();
TextInputConnection
_textInputConnection
;
...
...
@@ -1006,12 +1007,13 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
void
_onCursorColorTick
()
{
renderEditable
.
cursorColor
=
widget
.
cursorColor
.
withOpacity
(
_cursorBlinkOpacityController
.
value
);
_cursorVisibilityNotifier
.
value
=
_cursorBlinkOpacityController
.
value
>
0
;
}
/// Whether the blinking cursor is actually visible at this precise moment
/// (it's hidden half the time, since it blinks).
@visibleForTesting
bool
get
cursorCurrentlyVisible
=>
_
showCursor
.
value
;
bool
get
cursorCurrentlyVisible
=>
_
cursorBlinkOpacityController
.
value
>
0
;
/// The cursor blink interval (the amount of time the cursor is in the "on"
/// state or the "off" state). A complete cursor blink period is twice this
...
...
@@ -1027,7 +1029,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
int
_obscureLatestCharIndex
;
void
_cursorTick
(
Timer
timer
)
{
_showCursor
.
value
=
!
_showCursor
.
value
;
_targetCursorVisibility
=
!
_targetCursorVisibility
;
final
double
targetOpacity
=
_targetCursorVisibility
?
1.0
:
0.0
;
if
(
widget
.
cursorOpacityAnimates
)
{
// If we want to show the cursor, we will animate the opacity to the value
// of 1.0, and likewise if we want to make it disappear, to 0.0. An easing
...
...
@@ -1036,10 +1039,9 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
//
// These values and curves have been obtained through eyeballing, so are
// likely not exactly the same as the values for native iOS.
final
double
toValue
=
_showCursor
.
value
?
1.0
:
0.0
;
_cursorBlinkOpacityController
.
animateTo
(
toValue
,
curve:
Curves
.
easeOut
);
_cursorBlinkOpacityController
.
animateTo
(
targetOpacity
,
curve:
Curves
.
easeOut
);
}
else
{
_cursorBlinkOpacityController
.
value
=
_showCursor
.
value
?
1.0
:
0.0
;
_cursorBlinkOpacityController
.
value
=
targetOpacity
;
}
if
(
_obscureShowCharTicksPending
>
0
)
{
...
...
@@ -1056,7 +1058,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
}
void
_startCursorTimer
()
{
_
showCursor
.
value
=
true
;
_
targetCursorVisibility
=
true
;
_cursorBlinkOpacityController
.
value
=
1.0
;
if
(
EditableText
.
debugDeterministicCursor
)
return
;
...
...
@@ -1070,7 +1072,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
void
_stopCursorTimer
({
bool
resetCharTicks
=
true
})
{
_cursorTimer
?.
cancel
();
_cursorTimer
=
null
;
_
showCursor
.
value
=
false
;
_
targetCursorVisibility
=
false
;
_cursorBlinkOpacityController
.
value
=
0.0
;
if
(
EditableText
.
debugDeterministicCursor
)
return
;
...
...
@@ -1196,7 +1198,9 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
value:
_value
,
cursorColor:
_cursorColor
,
backgroundCursorColor:
widget
.
backgroundCursorColor
,
showCursor:
EditableText
.
debugDeterministicCursor
?
ValueNotifier
<
bool
>(
true
)
:
_showCursor
,
showCursor:
EditableText
.
debugDeterministicCursor
?
ValueNotifier
<
bool
>(
true
)
:
_cursorVisibilityNotifier
,
hasFocus:
_hasFocus
,
maxLines:
widget
.
maxLines
,
selectionColor:
widget
.
selectionColor
,
...
...
packages/flutter/test/material/text_field_test.dart
View file @
32b9c2f0
...
...
@@ -125,12 +125,12 @@ void main() {
SystemChannels
.
platform
.
setMockMethodCallHandler
(
mockClipboard
.
handleMethodCall
);
const
String
kThreeLines
=
'First line of text is
'
'Second line goes until
'
'Third line of stuff
'
;
'First line of text is
\n
'
'Second line goes until
\n
'
'Third line of stuff'
;
const
String
kMoreThanFourLines
=
kThreeLines
+
'Fourth line won
\'
t display and ends at'
;
'
\n
Fourth line won
\'
t display and ends at'
;
// Returns the first RenderEditable.
RenderEditable
findRenderEditable
(
WidgetTester
tester
)
{
...
...
@@ -903,7 +903,7 @@ void main() {
);
const
String
testValue
=
kThreeLines
;
const
String
cutValue
=
'First line of stuff
'
;
const
String
cutValue
=
'First line of stuff'
;
await
tester
.
enterText
(
find
.
byType
(
TextField
),
testValue
);
await
skipPastScrollingAnimation
(
tester
);
...
...
@@ -973,7 +973,9 @@ void main() {
testWidgets
(
'Can scroll multiline input'
,
(
WidgetTester
tester
)
async
{
final
Key
textFieldKey
=
UniqueKey
();
final
TextEditingController
controller
=
TextEditingController
();
final
TextEditingController
controller
=
TextEditingController
(
text:
kMoreThanFourLines
,
);
await
tester
.
pumpWidget
(
overlay
(
...
...
@@ -986,12 +988,6 @@ void main() {
),
),
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
await
tester
.
enterText
(
find
.
byType
(
TextField
),
kMoreThanFourLines
);
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
RenderBox
findInputBox
()
=>
tester
.
renderObject
(
find
.
byKey
(
textFieldKey
));
final
RenderBox
inputBox
=
findInputBox
();
...
...
@@ -1016,6 +1012,7 @@ void main() {
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
await
gesture
.
up
();
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
// Now the first line is scrolled up, and the fourth line is visible.
Offset
newFirstPos
=
textOffsetToPosition
(
tester
,
kMoreThanFourLines
.
indexOf
(
'First'
));
...
...
@@ -1026,15 +1023,21 @@ void main() {
expect
(
inputBox
.
hitTest
(
HitTestResult
(),
position:
inputBox
.
globalToLocal
(
newFourthPos
)),
isTrue
);
// Now try scrolling by dragging the selection handle.
// Long press the 'i' in 'Fourth line' to select the word.
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
final
Offset
untilPos
=
textOffsetToPosition
(
tester
,
kMoreThanFourLines
.
indexOf
(
'Fourth line'
)+
8
);
gesture
=
await
tester
.
startGesture
(
untilPos
,
pointer:
7
);
final
Offset
selectedWordPos
=
textOffsetToPosition
(
tester
,
kMoreThanFourLines
.
indexOf
(
'Fourth line'
)
+
8
,
);
gesture
=
await
tester
.
startGesture
(
selectedWordPos
,
pointer:
7
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
await
gesture
.
up
();
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
controller
.
selection
.
base
.
offset
,
91
);
expect
(
controller
.
selection
.
extent
.
offset
,
94
);
final
RenderEditable
renderEditable
=
findRenderEditable
(
tester
);
final
List
<
TextSelectionPoint
>
endpoints
=
globalize
(
renderEditable
.
getEndpointsForSelection
(
controller
.
selection
),
...
...
@@ -1043,7 +1046,7 @@ void main() {
expect
(
endpoints
.
length
,
2
);
// Drag the left handle to the first line, just after 'First'.
final
Offset
handlePos
=
endpoints
[
0
].
point
+
const
Offset
(-
1
.0
,
1.0
);
final
Offset
handlePos
=
endpoints
[
0
].
point
+
const
Offset
(-
1
,
1
);
final
Offset
newHandlePos
=
textOffsetToPosition
(
tester
,
kMoreThanFourLines
.
indexOf
(
'First'
)
+
5
);
gesture
=
await
tester
.
startGesture
(
handlePos
,
pointer:
7
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
...
...
@@ -1059,9 +1062,7 @@ void main() {
expect
(
newFirstPos
.
dy
,
firstPos
.
dy
);
expect
(
inputBox
.
hitTest
(
HitTestResult
(),
position:
inputBox
.
globalToLocal
(
newFirstPos
)),
isTrue
);
expect
(
inputBox
.
hitTest
(
HitTestResult
(),
position:
inputBox
.
globalToLocal
(
newFourthPos
)),
isFalse
);
},
// This test fails on some Mac environments when libtxt is enabled.
skip:
Platform
.
isMacOS
);
});
testWidgets
(
'TextField smoke test'
,
(
WidgetTester
tester
)
async
{
String
textFieldValue
;
...
...
packages/flutter/test/rendering/editable_test.dart
View file @
32b9c2f0
...
...
@@ -10,6 +10,7 @@ import 'package:flutter/foundation.dart';
import
'../rendering/mock_canvas.dart'
;
import
'../rendering/recording_canvas.dart'
;
import
'rendering_tester.dart'
;
class
FakeEditableTextState
extends
TextSelectionDelegate
{
@override
...
...
@@ -26,10 +27,6 @@ class FakeEditableTextState extends TextSelectionDelegate {
}
void
main
(
)
{
final
TextEditingController
controller
=
TextEditingController
();
const
TextStyle
textStyle
=
TextStyle
();
test
(
'editable intrinsics'
,
()
{
final
TextSelectionDelegate
delegate
=
FakeEditableTextState
();
final
RenderEditable
editable
=
RenderEditable
(
...
...
@@ -99,86 +96,76 @@ void main() {
);
});
RenderEditable
findRenderEditable
(
WidgetTester
tester
)
{
final
RenderObject
root
=
tester
.
renderObject
(
find
.
byType
(
EditableText
));
expect
(
root
,
isNotNull
);
RenderEditable
renderEditable
;
void
recursiveFinder
(
RenderObject
child
)
{
if
(
child
is
RenderEditable
)
{
renderEditable
=
child
;
return
;
}
child
.
visitChildren
(
recursiveFinder
);
}
root
.
visitChildren
(
recursiveFinder
);
expect
(
renderEditable
,
isNotNull
);
return
renderEditable
;
}
testWidgets
(
'Floating cursor is painted'
,
(
WidgetTester
tester
)
async
{
debugDefaultTargetPlatformOverride
=
TargetPlatform
.
iOS
;
const
String
text
=
'hello world this is fun and cool and awesome!'
;
controller
.
text
=
text
;
final
FocusNode
focusNode
=
FocusNode
();
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Padding
(
padding:
const
EdgeInsets
.
only
(
top:
0.25
),
child:
Material
(
child:
TextField
(
controller:
controller
,
focusNode:
focusNode
,
style:
textStyle
,
),
),
test
(
'Can change cursor color, radius, visibility'
,
()
{
final
TextSelectionDelegate
delegate
=
FakeEditableTextState
();
final
ValueNotifier
<
bool
>
showCursor
=
ValueNotifier
<
bool
>(
true
);
EditableText
.
debugDeterministicCursor
=
true
;
final
RenderEditable
editable
=
RenderEditable
(
backgroundCursorColor:
Colors
.
grey
,
textDirection:
TextDirection
.
ltr
,
cursorColor:
const
Color
.
fromARGB
(
0xFF
,
0xFF
,
0x00
,
0x00
),
offset:
ViewportOffset
.
zero
(),
textSelectionDelegate:
delegate
,
text:
const
TextSpan
(
text:
'test'
,
style:
TextStyle
(
height:
1.0
,
fontSize:
10.0
,
fontFamily:
'Ahem'
,
),
),
selection:
const
TextSelection
.
collapsed
(
offset:
4
,
affinity:
TextAffinity
.
upstream
,
),
);
await
tester
.
tap
(
find
.
byType
(
EditableText
));
final
RenderEditable
editable
=
findRenderEditable
(
tester
);
editable
.
selection
=
const
TextSelection
(
baseOffset:
29
,
extentOffset:
29
);
final
EditableTextState
editableTextState
=
tester
.
firstState
(
find
.
byType
(
EditableText
));
editableTextState
.
updateFloatingCursor
(
RawFloatingCursorPoint
(
state:
FloatingCursorDragState
.
Start
));
editableTextState
.
updateFloatingCursor
(
RawFloatingCursorPoint
(
state:
FloatingCursorDragState
.
Update
,
offset:
const
Offset
(
20
,
20
)));
await
tester
.
pump
();
expect
(
editable
,
paints
..
rrect
(
rrect:
RRect
.
fromRectAndRadius
(
Rect
.
fromLTRB
(
464.6666564941406
,
-
1.5833333730697632
,
466.6666564941406
,
16.41666603088379
),
const
Radius
.
circular
(
2.0
)),
color:
const
Color
(
0xff8e8e93
))
..
rrect
(
rrect:
RRect
.
fromRectAndRadius
(
Rect
.
fromLTRB
(
465.1666564941406
,
-
2.416666269302368
,
468.1666564941406
,
17.58333396911621
),
const
Radius
.
circular
(
1.0
)),
color:
const
Color
(
0xbf2196f3
))
);
layout
(
editable
);
// Moves the cursor right a few characters.
editableTextState
.
updateFloatingCursor
(
RawFloatingCursorPoint
(
state:
FloatingCursorDragState
.
Update
,
offset:
const
Offset
(-
250
,
20
)));
expect
(
find
.
byType
(
EditableText
),
paints
..
rrect
(
rrect:
RRect
.
fromRectAndRadius
(
Rect
.
fromLTRB
(
192.6666717529297
,
-
1.5833333730697632
,
194.6666717529297
,
16.41666603088379
),
const
Radius
.
circular
(
2.0
)),
color:
const
Color
(
0xff8e8e93
))
..
rrect
(
rrect:
RRect
.
fromRectAndRadius
(
Rect
.
fromLTRB
(
195.16665649414062
,
-
2.416666269302368
,
198.16665649414062
,
17.58333396911621
),
const
Radius
.
circular
(
1.0
)),
color:
const
Color
(
0xbf2196f3
))
editable
.
layout
(
BoxConstraints
.
loose
(
const
Size
(
100
,
100
)));
expect
(
editable
,
// Draw no cursor by default.
paintsExactlyCountTimes
(
#drawRect
,
0
),
);
editableTextState
.
updateFloatingCursor
(
RawFloatingCursorPoint
(
state:
FloatingCursorDragState
.
End
));
editable
.
showCursor
=
showCursor
;
pumpFrame
();
expect
(
editable
,
paints
..
rect
(
color:
const
Color
.
fromARGB
(
0xFF
,
0xFF
,
0x00
,
0x00
),
rect:
Rect
.
fromLTWH
(
40
,
2
,
1
,
6
),
));
// Now change to a rounded caret.
editable
.
cursorColor
=
const
Color
.
fromARGB
(
0xFF
,
0x00
,
0x00
,
0xFF
);
editable
.
cursorWidth
=
4
;
editable
.
cursorRadius
=
const
Radius
.
circular
(
3
);
pumpFrame
();
expect
(
editable
,
paints
..
rrect
(
color:
const
Color
.
fromARGB
(
0xFF
,
0x00
,
0x00
,
0xFF
),
rrect:
RRect
.
fromRectAndRadius
(
Rect
.
fromLTWH
(
40
,
2
,
4
,
6
),
const
Radius
.
circular
(
3
),
),
));
editable
.
textScaleFactor
=
2
;
pumpFrame
();
// Now the caret height is much bigger due to the bigger font scale.
expect
(
editable
,
paints
..
rrect
(
color:
const
Color
.
fromARGB
(
0xFF
,
0x00
,
0x00
,
0xFF
),
rrect:
RRect
.
fromRectAndRadius
(
Rect
.
fromLTWH
(
80
,
2
,
4
,
16
),
const
Radius
.
circular
(
3
),
),
));
await
tester
.
pumpAndSettle
();
// Can turn off caret.
showCursor
.
value
=
false
;
pumpFrame
();
debugDefaultTargetPlatformOverride
=
null
;
expect
(
editable
,
paintsExactlyCountTimes
(
#drawRRect
,
0
))
;
});
}
packages/flutter/test/widgets/editable_text_cursor_test.dart
0 → 100644
View file @
32b9c2f0
This diff is collapsed.
Click to expand it.
packages/flutter/test/widgets/editable_text_test.dart
View file @
32b9c2f0
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment