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
e4995301
Unverified
Commit
e4995301
authored
Aug 01, 2022
by
pdblasi-google
Committed by
GitHub
Aug 01, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Create `containsSemantics` to allow for partial matching of semantics in tests. (#108573)
parent
e368e586
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
864 additions
and
130 deletions
+864
-130
semantics.dart
packages/flutter/lib/src/semantics/semantics.dart
+1
-1
matchers.dart
packages/flutter_test/lib/src/matchers.dart
+421
-123
matchers_test.dart
packages/flutter_test/test/matchers_test.dart
+442
-6
No files found.
packages/flutter/lib/src/semantics/semantics.dart
View file @
e4995301
...
...
@@ -2315,7 +2315,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
);
assert
(
!
_canPerformAction
(
SemanticsAction
.
decrease
)
||
(
value
==
''
)
==
(
decreasedValue
==
''
),
'A SemanticsNode with action "
in
crease" needs to be annotated with either both "value" and "decreasedValue" or neither'
,
'A SemanticsNode with action "
de
crease" needs to be annotated with either both "value" and "decreasedValue" or neither'
,
);
}
...
...
packages/flutter_test/lib/src/matchers.dart
View file @
e4995301
...
...
@@ -514,6 +514,7 @@ AsyncMatcher matchesReferenceImage(ui.Image image) {
/// See also:
///
/// * [WidgetTester.getSemantics], the tester method which retrieves semantics.
/// * [containsSemantics], a similar matcher without default values for flags or actions.
Matcher
matchesSemantics
(
{
String
?
label
,
AttributedString
?
attributedLabel
,
...
...
@@ -524,8 +525,8 @@ Matcher matchesSemantics({
String
?
increasedValue
,
AttributedString
?
attributedIncreasedValue
,
String
?
decreasedValue
,
String
?
tooltip
,
AttributedString
?
attributedDecreasedValue
,
String
?
tooltip
,
TextDirection
?
textDirection
,
Rect
?
rect
,
Size
?
size
,
...
...
@@ -588,67 +589,6 @@ Matcher matchesSemantics({
List
<
CustomSemanticsAction
>?
customActions
,
List
<
Matcher
>?
children
,
})
{
final
List
<
SemanticsFlag
>
flags
=
<
SemanticsFlag
>[
if
(
hasCheckedState
)
SemanticsFlag
.
hasCheckedState
,
if
(
isChecked
)
SemanticsFlag
.
isChecked
,
if
(
isSelected
)
SemanticsFlag
.
isSelected
,
if
(
isButton
)
SemanticsFlag
.
isButton
,
if
(
isSlider
)
SemanticsFlag
.
isSlider
,
if
(
isKeyboardKey
)
SemanticsFlag
.
isKeyboardKey
,
if
(
isLink
)
SemanticsFlag
.
isLink
,
if
(
isTextField
)
SemanticsFlag
.
isTextField
,
if
(
isReadOnly
)
SemanticsFlag
.
isReadOnly
,
if
(
isFocused
)
SemanticsFlag
.
isFocused
,
if
(
isFocusable
)
SemanticsFlag
.
isFocusable
,
if
(
hasEnabledState
)
SemanticsFlag
.
hasEnabledState
,
if
(
isEnabled
)
SemanticsFlag
.
isEnabled
,
if
(
isInMutuallyExclusiveGroup
)
SemanticsFlag
.
isInMutuallyExclusiveGroup
,
if
(
isHeader
)
SemanticsFlag
.
isHeader
,
if
(
isObscured
)
SemanticsFlag
.
isObscured
,
if
(
isMultiline
)
SemanticsFlag
.
isMultiline
,
if
(
namesRoute
)
SemanticsFlag
.
namesRoute
,
if
(
scopesRoute
)
SemanticsFlag
.
scopesRoute
,
if
(
isHidden
)
SemanticsFlag
.
isHidden
,
if
(
isImage
)
SemanticsFlag
.
isImage
,
if
(
isLiveRegion
)
SemanticsFlag
.
isLiveRegion
,
if
(
hasToggledState
)
SemanticsFlag
.
hasToggledState
,
if
(
isToggled
)
SemanticsFlag
.
isToggled
,
if
(
hasImplicitScrolling
)
SemanticsFlag
.
hasImplicitScrolling
,
if
(
isSlider
)
SemanticsFlag
.
isSlider
,
];
final
List
<
SemanticsAction
>
actions
=
<
SemanticsAction
>[
if
(
hasTapAction
)
SemanticsAction
.
tap
,
if
(
hasLongPressAction
)
SemanticsAction
.
longPress
,
if
(
hasScrollLeftAction
)
SemanticsAction
.
scrollLeft
,
if
(
hasScrollRightAction
)
SemanticsAction
.
scrollRight
,
if
(
hasScrollUpAction
)
SemanticsAction
.
scrollUp
,
if
(
hasScrollDownAction
)
SemanticsAction
.
scrollDown
,
if
(
hasIncreaseAction
)
SemanticsAction
.
increase
,
if
(
hasDecreaseAction
)
SemanticsAction
.
decrease
,
if
(
hasShowOnScreenAction
)
SemanticsAction
.
showOnScreen
,
if
(
hasMoveCursorForwardByCharacterAction
)
SemanticsAction
.
moveCursorForwardByCharacter
,
if
(
hasMoveCursorBackwardByCharacterAction
)
SemanticsAction
.
moveCursorBackwardByCharacter
,
if
(
hasSetSelectionAction
)
SemanticsAction
.
setSelection
,
if
(
hasCopyAction
)
SemanticsAction
.
copy
,
if
(
hasCutAction
)
SemanticsAction
.
cut
,
if
(
hasPasteAction
)
SemanticsAction
.
paste
,
if
(
hasDidGainAccessibilityFocusAction
)
SemanticsAction
.
didGainAccessibilityFocus
,
if
(
hasDidLoseAccessibilityFocusAction
)
SemanticsAction
.
didLoseAccessibilityFocus
,
if
(
customActions
!=
null
&&
customActions
.
isNotEmpty
)
SemanticsAction
.
customAction
,
if
(
hasDismissAction
)
SemanticsAction
.
dismiss
,
if
(
hasMoveCursorForwardByWordAction
)
SemanticsAction
.
moveCursorForwardByWord
,
if
(
hasMoveCursorBackwardByWordAction
)
SemanticsAction
.
moveCursorBackwardByWord
,
if
(
hasSetTextAction
)
SemanticsAction
.
setText
,
];
SemanticsHintOverrides
?
hintOverrides
;
if
(
onTapHint
!=
null
||
onLongPressHint
!=
null
)
{
hintOverrides
=
SemanticsHintOverrides
(
onTapHint:
onTapHint
,
onLongPressHint:
onLongPressHint
,
);
}
return
_MatchesSemanticsData
(
label:
label
,
attributedLabel:
attributedLabel
,
...
...
@@ -657,12 +597,10 @@ Matcher matchesSemantics({
value:
value
,
attributedValue:
attributedValue
,
increasedValue:
increasedValue
,
tooltip:
tooltip
,
attributedIncreasedValue:
attributedIncreasedValue
,
decreasedValue:
decreasedValue
,
attributedDecreasedValue:
attributedDecreasedValue
,
actions:
actions
,
flags:
flags
,
tooltip:
tooltip
,
textDirection:
textDirection
,
rect:
rect
,
size:
size
,
...
...
@@ -670,10 +608,231 @@ Matcher matchesSemantics({
thickness:
thickness
,
platformViewId:
platformViewId
,
customActions:
customActions
,
hintOverrides:
hintOverrides
,
maxValueLength:
maxValueLength
,
currentValueLength:
currentValueLength
,
// Flags
hasCheckedState:
hasCheckedState
,
isChecked:
isChecked
,
isSelected:
isSelected
,
isButton:
isButton
,
isSlider:
isSlider
,
isKeyboardKey:
isKeyboardKey
,
isLink:
isLink
,
isFocused:
isFocused
,
isFocusable:
isFocusable
,
isTextField:
isTextField
,
isReadOnly:
isReadOnly
,
hasEnabledState:
hasEnabledState
,
isEnabled:
isEnabled
,
isInMutuallyExclusiveGroup:
isInMutuallyExclusiveGroup
,
isHeader:
isHeader
,
isObscured:
isObscured
,
isMultiline:
isMultiline
,
namesRoute:
namesRoute
,
scopesRoute:
scopesRoute
,
isHidden:
isHidden
,
isImage:
isImage
,
isLiveRegion:
isLiveRegion
,
hasToggledState:
hasToggledState
,
isToggled:
isToggled
,
hasImplicitScrolling:
hasImplicitScrolling
,
// Actions
hasTapAction:
hasTapAction
,
hasLongPressAction:
hasLongPressAction
,
hasScrollLeftAction:
hasScrollLeftAction
,
hasScrollRightAction:
hasScrollRightAction
,
hasScrollUpAction:
hasScrollUpAction
,
hasScrollDownAction:
hasScrollDownAction
,
hasIncreaseAction:
hasIncreaseAction
,
hasDecreaseAction:
hasDecreaseAction
,
hasShowOnScreenAction:
hasShowOnScreenAction
,
hasMoveCursorForwardByCharacterAction:
hasMoveCursorForwardByCharacterAction
,
hasMoveCursorBackwardByCharacterAction:
hasMoveCursorBackwardByCharacterAction
,
hasMoveCursorForwardByWordAction:
hasMoveCursorForwardByWordAction
,
hasMoveCursorBackwardByWordAction:
hasMoveCursorBackwardByWordAction
,
hasSetTextAction:
hasSetTextAction
,
hasSetSelectionAction:
hasSetSelectionAction
,
hasCopyAction:
hasCopyAction
,
hasCutAction:
hasCutAction
,
hasPasteAction:
hasPasteAction
,
hasDidGainAccessibilityFocusAction:
hasDidGainAccessibilityFocusAction
,
hasDidLoseAccessibilityFocusAction:
hasDidLoseAccessibilityFocusAction
,
hasDismissAction:
hasDismissAction
,
// Custom actions and overrides
children:
children
,
onLongPressHint:
onLongPressHint
,
onTapHint:
onTapHint
,
);
}
/// Asserts that a [SemanticsNode] contains the specified information.
///
/// There are no default expected values, so no unspecified values will be
/// validated.
///
/// To retrieve the semantics data of a widget, use [WidgetTester.getSemantics]
/// with a [Finder] that returns a single widget. Semantics must be enabled
/// in order to use this method.
///
/// ## Sample code
///
/// ```dart
/// final SemanticsHandle handle = tester.ensureSemantics();
/// expect(tester.getSemantics(find.text('hello')), hasSemantics(label: 'hello'));
/// handle.dispose();
/// ```
///
/// See also:
///
/// * [WidgetTester.getSemantics], the tester method which retrieves semantics.
/// * [matchesSemantics], a similar matcher with default values for flags and actions.
Matcher
containsSemantics
(
{
String
?
label
,
AttributedString
?
attributedLabel
,
String
?
hint
,
AttributedString
?
attributedHint
,
String
?
value
,
AttributedString
?
attributedValue
,
String
?
increasedValue
,
AttributedString
?
attributedIncreasedValue
,
String
?
decreasedValue
,
AttributedString
?
attributedDecreasedValue
,
String
?
tooltip
,
TextDirection
?
textDirection
,
Rect
?
rect
,
Size
?
size
,
double
?
elevation
,
double
?
thickness
,
int
?
platformViewId
,
int
?
maxValueLength
,
int
?
currentValueLength
,
// Flags
bool
?
hasCheckedState
,
bool
?
isChecked
,
bool
?
isSelected
,
bool
?
isButton
,
bool
?
isSlider
,
bool
?
isKeyboardKey
,
bool
?
isLink
,
bool
?
isFocused
,
bool
?
isFocusable
,
bool
?
isTextField
,
bool
?
isReadOnly
,
bool
?
hasEnabledState
,
bool
?
isEnabled
,
bool
?
isInMutuallyExclusiveGroup
,
bool
?
isHeader
,
bool
?
isObscured
,
bool
?
isMultiline
,
bool
?
namesRoute
,
bool
?
scopesRoute
,
bool
?
isHidden
,
bool
?
isImage
,
bool
?
isLiveRegion
,
bool
?
hasToggledState
,
bool
?
isToggled
,
bool
?
hasImplicitScrolling
,
// Actions
bool
?
hasTapAction
,
bool
?
hasLongPressAction
,
bool
?
hasScrollLeftAction
,
bool
?
hasScrollRightAction
,
bool
?
hasScrollUpAction
,
bool
?
hasScrollDownAction
,
bool
?
hasIncreaseAction
,
bool
?
hasDecreaseAction
,
bool
?
hasShowOnScreenAction
,
bool
?
hasMoveCursorForwardByCharacterAction
,
bool
?
hasMoveCursorBackwardByCharacterAction
,
bool
?
hasMoveCursorForwardByWordAction
,
bool
?
hasMoveCursorBackwardByWordAction
,
bool
?
hasSetTextAction
,
bool
?
hasSetSelectionAction
,
bool
?
hasCopyAction
,
bool
?
hasCutAction
,
bool
?
hasPasteAction
,
bool
?
hasDidGainAccessibilityFocusAction
,
bool
?
hasDidLoseAccessibilityFocusAction
,
bool
?
hasDismissAction
,
// Custom actions and overrides
String
?
onTapHint
,
String
?
onLongPressHint
,
List
<
CustomSemanticsAction
>?
customActions
,
List
<
Matcher
>?
children
,
})
{
return
_MatchesSemanticsData
(
label:
label
,
attributedLabel:
attributedLabel
,
hint:
hint
,
attributedHint:
attributedHint
,
value:
value
,
attributedValue:
attributedValue
,
increasedValue:
increasedValue
,
attributedIncreasedValue:
attributedIncreasedValue
,
decreasedValue:
decreasedValue
,
attributedDecreasedValue:
attributedDecreasedValue
,
tooltip:
tooltip
,
textDirection:
textDirection
,
rect:
rect
,
size:
size
,
elevation:
elevation
,
thickness:
thickness
,
platformViewId:
platformViewId
,
customActions:
customActions
,
maxValueLength:
maxValueLength
,
currentValueLength:
currentValueLength
,
// Flags
hasCheckedState:
hasCheckedState
,
isChecked:
isChecked
,
isSelected:
isSelected
,
isButton:
isButton
,
isSlider:
isSlider
,
isKeyboardKey:
isKeyboardKey
,
isLink:
isLink
,
isFocused:
isFocused
,
isFocusable:
isFocusable
,
isTextField:
isTextField
,
isReadOnly:
isReadOnly
,
hasEnabledState:
hasEnabledState
,
isEnabled:
isEnabled
,
isInMutuallyExclusiveGroup:
isInMutuallyExclusiveGroup
,
isHeader:
isHeader
,
isObscured:
isObscured
,
isMultiline:
isMultiline
,
namesRoute:
namesRoute
,
scopesRoute:
scopesRoute
,
isHidden:
isHidden
,
isImage:
isImage
,
isLiveRegion:
isLiveRegion
,
hasToggledState:
hasToggledState
,
isToggled:
isToggled
,
hasImplicitScrolling:
hasImplicitScrolling
,
// Actions
hasTapAction:
hasTapAction
,
hasLongPressAction:
hasLongPressAction
,
hasScrollLeftAction:
hasScrollLeftAction
,
hasScrollRightAction:
hasScrollRightAction
,
hasScrollUpAction:
hasScrollUpAction
,
hasScrollDownAction:
hasScrollDownAction
,
hasIncreaseAction:
hasIncreaseAction
,
hasDecreaseAction:
hasDecreaseAction
,
hasShowOnScreenAction:
hasShowOnScreenAction
,
hasMoveCursorForwardByCharacterAction:
hasMoveCursorForwardByCharacterAction
,
hasMoveCursorBackwardByCharacterAction:
hasMoveCursorBackwardByCharacterAction
,
hasMoveCursorForwardByWordAction:
hasMoveCursorForwardByWordAction
,
hasMoveCursorBackwardByWordAction:
hasMoveCursorBackwardByWordAction
,
hasSetTextAction:
hasSetTextAction
,
hasSetSelectionAction:
hasSetSelectionAction
,
hasCopyAction:
hasCopyAction
,
hasCutAction:
hasCutAction
,
hasPasteAction:
hasPasteAction
,
hasDidGainAccessibilityFocusAction:
hasDidGainAccessibilityFocusAction
,
hasDidLoseAccessibilityFocusAction:
hasDidLoseAccessibilityFocusAction
,
hasDismissAction:
hasDismissAction
,
// Custom actions and overrides
children:
children
,
onLongPressHint:
onLongPressHint
,
onTapHint:
onTapHint
,
);
}
...
...
@@ -1885,31 +2044,136 @@ class _MatchesReferenceImage extends AsyncMatcher {
class
_MatchesSemanticsData
extends
Matcher
{
_MatchesSemanticsData
({
this
.
label
,
this
.
attributedLabel
,
this
.
hint
,
this
.
attributedHint
,
this
.
value
,
this
.
attributedValue
,
this
.
increasedValue
,
this
.
attributedIncreasedValue
,
this
.
decreasedValue
,
this
.
attributedDecreasedValue
,
this
.
tooltip
,
this
.
flags
,
this
.
actions
,
this
.
textDirection
,
this
.
rect
,
this
.
size
,
this
.
elevation
,
this
.
thickness
,
this
.
platformViewId
,
this
.
maxValueLength
,
this
.
currentValueLength
,
this
.
customActions
,
this
.
hintOverrides
,
this
.
children
,
});
required
this
.
label
,
required
this
.
attributedLabel
,
required
this
.
hint
,
required
this
.
attributedHint
,
required
this
.
value
,
required
this
.
attributedValue
,
required
this
.
increasedValue
,
required
this
.
attributedIncreasedValue
,
required
this
.
decreasedValue
,
required
this
.
attributedDecreasedValue
,
required
this
.
tooltip
,
required
this
.
textDirection
,
required
this
.
rect
,
required
this
.
size
,
required
this
.
elevation
,
required
this
.
thickness
,
required
this
.
platformViewId
,
required
this
.
maxValueLength
,
required
this
.
currentValueLength
,
// Flags
required
bool
?
hasCheckedState
,
required
bool
?
isChecked
,
required
bool
?
isSelected
,
required
bool
?
isButton
,
required
bool
?
isSlider
,
required
bool
?
isKeyboardKey
,
required
bool
?
isLink
,
required
bool
?
isFocused
,
required
bool
?
isFocusable
,
required
bool
?
isTextField
,
required
bool
?
isReadOnly
,
required
bool
?
hasEnabledState
,
required
bool
?
isEnabled
,
required
bool
?
isInMutuallyExclusiveGroup
,
required
bool
?
isHeader
,
required
bool
?
isObscured
,
required
bool
?
isMultiline
,
required
bool
?
namesRoute
,
required
bool
?
scopesRoute
,
required
bool
?
isHidden
,
required
bool
?
isImage
,
required
bool
?
isLiveRegion
,
required
bool
?
hasToggledState
,
required
bool
?
isToggled
,
required
bool
?
hasImplicitScrolling
,
// Actions
required
bool
?
hasTapAction
,
required
bool
?
hasLongPressAction
,
required
bool
?
hasScrollLeftAction
,
required
bool
?
hasScrollRightAction
,
required
bool
?
hasScrollUpAction
,
required
bool
?
hasScrollDownAction
,
required
bool
?
hasIncreaseAction
,
required
bool
?
hasDecreaseAction
,
required
bool
?
hasShowOnScreenAction
,
required
bool
?
hasMoveCursorForwardByCharacterAction
,
required
bool
?
hasMoveCursorBackwardByCharacterAction
,
required
bool
?
hasMoveCursorForwardByWordAction
,
required
bool
?
hasMoveCursorBackwardByWordAction
,
required
bool
?
hasSetTextAction
,
required
bool
?
hasSetSelectionAction
,
required
bool
?
hasCopyAction
,
required
bool
?
hasCutAction
,
required
bool
?
hasPasteAction
,
required
bool
?
hasDidGainAccessibilityFocusAction
,
required
bool
?
hasDidLoseAccessibilityFocusAction
,
required
bool
?
hasDismissAction
,
// Custom actions and overrides
required
String
?
onTapHint
,
required
String
?
onLongPressHint
,
required
this
.
customActions
,
required
this
.
children
,
})
:
flags
=
<
SemanticsFlag
,
bool
>{
if
(
hasCheckedState
!=
null
)
SemanticsFlag
.
hasCheckedState
:
hasCheckedState
,
if
(
isChecked
!=
null
)
SemanticsFlag
.
isChecked
:
isChecked
,
if
(
isSelected
!=
null
)
SemanticsFlag
.
isSelected
:
isSelected
,
if
(
isButton
!=
null
)
SemanticsFlag
.
isButton
:
isButton
,
if
(
isSlider
!=
null
)
SemanticsFlag
.
isSlider
:
isSlider
,
if
(
isKeyboardKey
!=
null
)
SemanticsFlag
.
isKeyboardKey
:
isKeyboardKey
,
if
(
isLink
!=
null
)
SemanticsFlag
.
isLink
:
isLink
,
if
(
isTextField
!=
null
)
SemanticsFlag
.
isTextField
:
isTextField
,
if
(
isReadOnly
!=
null
)
SemanticsFlag
.
isReadOnly
:
isReadOnly
,
if
(
isFocused
!=
null
)
SemanticsFlag
.
isFocused
:
isFocused
,
if
(
isFocusable
!=
null
)
SemanticsFlag
.
isFocusable
:
isFocusable
,
if
(
hasEnabledState
!=
null
)
SemanticsFlag
.
hasEnabledState
:
hasEnabledState
,
if
(
isEnabled
!=
null
)
SemanticsFlag
.
isEnabled
:
isEnabled
,
if
(
isInMutuallyExclusiveGroup
!=
null
)
SemanticsFlag
.
isInMutuallyExclusiveGroup
:
isInMutuallyExclusiveGroup
,
if
(
isHeader
!=
null
)
SemanticsFlag
.
isHeader
:
isHeader
,
if
(
isObscured
!=
null
)
SemanticsFlag
.
isObscured
:
isObscured
,
if
(
isMultiline
!=
null
)
SemanticsFlag
.
isMultiline
:
isMultiline
,
if
(
namesRoute
!=
null
)
SemanticsFlag
.
namesRoute
:
namesRoute
,
if
(
scopesRoute
!=
null
)
SemanticsFlag
.
scopesRoute
:
scopesRoute
,
if
(
isHidden
!=
null
)
SemanticsFlag
.
isHidden
:
isHidden
,
if
(
isImage
!=
null
)
SemanticsFlag
.
isImage
:
isImage
,
if
(
isLiveRegion
!=
null
)
SemanticsFlag
.
isLiveRegion
:
isLiveRegion
,
if
(
hasToggledState
!=
null
)
SemanticsFlag
.
hasToggledState
:
hasToggledState
,
if
(
isToggled
!=
null
)
SemanticsFlag
.
isToggled
:
isToggled
,
if
(
hasImplicitScrolling
!=
null
)
SemanticsFlag
.
hasImplicitScrolling
:
hasImplicitScrolling
,
if
(
isSlider
!=
null
)
SemanticsFlag
.
isSlider
:
isSlider
,
},
actions
=
<
SemanticsAction
,
bool
>{
if
(
hasTapAction
!=
null
)
SemanticsAction
.
tap
:
hasTapAction
,
if
(
hasLongPressAction
!=
null
)
SemanticsAction
.
longPress
:
hasLongPressAction
,
if
(
hasScrollLeftAction
!=
null
)
SemanticsAction
.
scrollLeft
:
hasScrollLeftAction
,
if
(
hasScrollRightAction
!=
null
)
SemanticsAction
.
scrollRight
:
hasScrollRightAction
,
if
(
hasScrollUpAction
!=
null
)
SemanticsAction
.
scrollUp
:
hasScrollUpAction
,
if
(
hasScrollDownAction
!=
null
)
SemanticsAction
.
scrollDown
:
hasScrollDownAction
,
if
(
hasIncreaseAction
!=
null
)
SemanticsAction
.
increase
:
hasIncreaseAction
,
if
(
hasDecreaseAction
!=
null
)
SemanticsAction
.
decrease
:
hasDecreaseAction
,
if
(
hasShowOnScreenAction
!=
null
)
SemanticsAction
.
showOnScreen
:
hasShowOnScreenAction
,
if
(
hasMoveCursorForwardByCharacterAction
!=
null
)
SemanticsAction
.
moveCursorForwardByCharacter
:
hasMoveCursorForwardByCharacterAction
,
if
(
hasMoveCursorBackwardByCharacterAction
!=
null
)
SemanticsAction
.
moveCursorBackwardByCharacter
:
hasMoveCursorBackwardByCharacterAction
,
if
(
hasSetSelectionAction
!=
null
)
SemanticsAction
.
setSelection
:
hasSetSelectionAction
,
if
(
hasCopyAction
!=
null
)
SemanticsAction
.
copy
:
hasCopyAction
,
if
(
hasCutAction
!=
null
)
SemanticsAction
.
cut
:
hasCutAction
,
if
(
hasPasteAction
!=
null
)
SemanticsAction
.
paste
:
hasPasteAction
,
if
(
hasDidGainAccessibilityFocusAction
!=
null
)
SemanticsAction
.
didGainAccessibilityFocus
:
hasDidGainAccessibilityFocusAction
,
if
(
hasDidLoseAccessibilityFocusAction
!=
null
)
SemanticsAction
.
didLoseAccessibilityFocus
:
hasDidLoseAccessibilityFocusAction
,
if
(
customActions
!=
null
)
SemanticsAction
.
customAction
:
customActions
.
isNotEmpty
,
if
(
hasDismissAction
!=
null
)
SemanticsAction
.
dismiss
:
hasDismissAction
,
if
(
hasMoveCursorForwardByWordAction
!=
null
)
SemanticsAction
.
moveCursorForwardByWord
:
hasMoveCursorForwardByWordAction
,
if
(
hasMoveCursorBackwardByWordAction
!=
null
)
SemanticsAction
.
moveCursorBackwardByWord
:
hasMoveCursorBackwardByWordAction
,
if
(
hasSetTextAction
!=
null
)
SemanticsAction
.
setText
:
hasSetTextAction
,
},
hintOverrides
=
onTapHint
==
null
&&
onLongPressHint
==
null
?
null
:
SemanticsHintOverrides
(
onTapHint:
onTapHint
,
onLongPressHint:
onLongPressHint
,
);
final
String
?
label
;
final
AttributedString
?
attributedLabel
;
...
...
@@ -1923,9 +2187,7 @@ class _MatchesSemanticsData extends Matcher {
final
AttributedString
?
attributedDecreasedValue
;
final
String
?
tooltip
;
final
SemanticsHintOverrides
?
hintOverrides
;
final
List
<
SemanticsAction
>?
actions
;
final
List
<
CustomSemanticsAction
>?
customActions
;
final
List
<
SemanticsFlag
>?
flags
;
final
TextDirection
?
textDirection
;
final
Rect
?
rect
;
final
Size
?
size
;
...
...
@@ -1936,6 +2198,14 @@ class _MatchesSemanticsData extends Matcher {
final
int
?
currentValueLength
;
final
List
<
Matcher
>?
children
;
/// There are three possible states for these two maps:
///
/// 1. If the flag/action maps to `true`, then it must be present in the SemanticData
/// 2. If the flag/action maps to `false`, then it must not be present in the SemanticData
/// 3. If the flag/action is not in the map, then it will not be validated against
final
Map
<
SemanticsAction
,
bool
>
actions
;
final
Map
<
SemanticsFlag
,
bool
>
flags
;
@override
Description
describe
(
Description
description
)
{
description
.
add
(
'has semantics'
);
...
...
@@ -1972,11 +2242,39 @@ class _MatchesSemanticsData extends Matcher {
if
(
tooltip
!=
null
)
{
description
.
add
(
' with tooltip:
$tooltip
'
);
}
if
(
actions
!=
null
)
{
description
.
add
(
' with actions: '
).
addDescriptionOf
(
actions
);
if
(
actions
.
isNotEmpty
)
{
final
List
<
SemanticsAction
>
expectedActions
=
actions
.
entries
.
where
((
MapEntry
<
ui
.
SemanticsAction
,
bool
>
e
)
=>
e
.
value
)
.
map
((
MapEntry
<
ui
.
SemanticsAction
,
bool
>
e
)
=>
e
.
key
)
.
toList
();
final
List
<
SemanticsAction
>
notExpectedActions
=
actions
.
entries
.
where
((
MapEntry
<
ui
.
SemanticsAction
,
bool
>
e
)
=>
!
e
.
value
)
.
map
((
MapEntry
<
ui
.
SemanticsAction
,
bool
>
e
)
=>
e
.
key
)
.
toList
();
if
(
expectedActions
.
isNotEmpty
)
{
description
.
add
(
' with actions: '
).
addDescriptionOf
(
expectedActions
);
}
if
(
notExpectedActions
.
isNotEmpty
)
{
description
.
add
(
' without actions: '
).
addDescriptionOf
(
notExpectedActions
);
}
}
if
(
flags
!=
null
)
{
description
.
add
(
' with flags: '
).
addDescriptionOf
(
flags
);
if
(
flags
.
isNotEmpty
)
{
final
List
<
SemanticsFlag
>
expectedFlags
=
flags
.
entries
.
where
((
MapEntry
<
ui
.
SemanticsFlag
,
bool
>
e
)
=>
e
.
value
)
.
map
((
MapEntry
<
ui
.
SemanticsFlag
,
bool
>
e
)
=>
e
.
key
)
.
toList
();
final
List
<
SemanticsFlag
>
notExpectedFlags
=
flags
.
entries
.
where
((
MapEntry
<
ui
.
SemanticsFlag
,
bool
>
e
)
=>
!
e
.
value
)
.
map
((
MapEntry
<
ui
.
SemanticsFlag
,
bool
>
e
)
=>
e
.
key
)
.
toList
();
if
(
expectedFlags
.
isNotEmpty
)
{
description
.
add
(
' with flags: '
).
addDescriptionOf
(
expectedFlags
);
}
if
(
notExpectedFlags
.
isNotEmpty
)
{
description
.
add
(
' without flags: '
).
addDescriptionOf
(
notExpectedFlags
);
}
}
if
(
textDirection
!=
null
)
{
description
.
add
(
' with textDirection:
$textDirection
'
);
...
...
@@ -2116,18 +2414,18 @@ class _MatchesSemanticsData extends Matcher {
if
(
maxValueLength
!=
null
&&
maxValueLength
!=
data
.
maxValueLength
)
{
return
failWithDescription
(
matchState
,
'maxValueLength was:
${data.maxValueLength}
'
);
}
if
(
actions
!=
null
)
{
int
actionBits
=
0
;
for
(
final
SemanticsAction
action
in
actions
!)
{
actionBits
|=
action
.
index
;
}
if
(
actionBits
!=
data
.
actions
)
{
final
List
<
String
>
actionSummary
=
<
String
>[
for
(
final
SemanticsAction
action
in
SemanticsAction
.
values
.
value
s
)
if
((
data
.
actions
&
action
.
index
)
!=
0
)
describeEnum
(
action
),
]
;
return
failWithDescription
(
matchState
,
'actions were:
$actionSummary
'
);
if
(
actions
.
isNotEmpty
)
{
for
(
final
MapEntry
<
ui
.
SemanticsAction
,
bool
>
actionEntry
in
actions
.
entries
)
{
final
ui
.
SemanticsAction
action
=
actionEntry
.
key
;
final
bool
actionExpected
=
actionEntry
.
value
;
final
bool
actionPresent
=
(
action
.
index
&
data
.
actions
)
==
action
.
index
;
if
(
actionPresent
!=
actionExpected
)
{
final
List
<
String
>
actionSummary
=
<
String
>[
for
(
final
int
action
in
SemanticsAction
.
values
.
key
s
)
if
((
data
.
actions
&
action
)
!=
0
)
describeEnum
(
action
),
];
return
failWithDescription
(
matchState
,
'actions were:
$actionSummary
'
)
;
}
}
}
if
(
customActions
!=
null
||
hintOverrides
!=
null
)
{
...
...
@@ -2142,7 +2440,7 @@ class _MatchesSemanticsData extends Matcher {
expectedCustomActions
.
add
(
CustomSemanticsAction
.
overridingAction
(
hint:
hintOverrides
!.
onLongPressHint
!,
action:
SemanticsAction
.
longPress
));
}
if
(
expectedCustomActions
.
length
!=
providedCustomActions
.
length
)
{
return
failWithDescription
(
matchState
,
'custom actions w
h
ere:
$providedCustomActions
'
);
return
failWithDescription
(
matchState
,
'custom actions were:
$providedCustomActions
'
);
}
int
sortActions
(
CustomSemanticsAction
left
,
CustomSemanticsAction
right
)
{
return
CustomSemanticsAction
.
getIdentifier
(
left
)
-
CustomSemanticsAction
.
getIdentifier
(
right
);
...
...
@@ -2151,22 +2449,22 @@ class _MatchesSemanticsData extends Matcher {
providedCustomActions
.
sort
(
sortActions
);
for
(
int
i
=
0
;
i
<
expectedCustomActions
.
length
;
i
++)
{
if
(
expectedCustomActions
[
i
]
!=
providedCustomActions
[
i
])
{
return
failWithDescription
(
matchState
,
'custom actions w
h
ere:
$providedCustomActions
'
);
return
failWithDescription
(
matchState
,
'custom actions were:
$providedCustomActions
'
);
}
}
}
if
(
flags
!=
null
)
{
int
flagBits
=
0
;
for
(
final
SemanticsFlag
flag
in
flags
!)
{
f
lagBits
|=
flag
.
index
;
}
if
(
flagBits
!=
data
.
flags
)
{
final
List
<
String
>
flagSummary
=
<
String
>[
for
(
final
SemanticsFlag
flag
in
SemanticsFlag
.
values
.
value
s
)
if
((
data
.
flags
&
flag
.
index
)
!=
0
)
describeEnum
(
flag
),
]
;
return
failWithDescription
(
matchState
,
'flags were:
$flagSummary
'
);
if
(
flags
.
isNotEmpty
)
{
for
(
final
MapEntry
<
ui
.
SemanticsFlag
,
bool
>
flagEntry
in
flags
.
entries
)
{
final
ui
.
SemanticsFlag
flag
=
flagEntry
.
key
;
f
inal
bool
flagExpected
=
flagEntry
.
value
;
final
bool
flagPresent
=
flag
.
index
&
data
.
flags
==
flag
.
index
;
if
(
flagPresent
!=
flagExpected
)
{
final
List
<
String
>
flagSummary
=
<
String
>[
for
(
final
int
flag
in
SemanticsFlag
.
values
.
key
s
)
if
((
data
.
flags
&
flag
)
!=
0
)
describeEnum
(
flag
),
];
return
failWithDescription
(
matchState
,
'flags were:
$flagSummary
'
)
;
}
}
}
bool
allMatched
=
true
;
...
...
packages/flutter_test/test/matchers_test.dart
View file @
e4995301
...
...
@@ -599,10 +599,7 @@ void main() {
actions
|=
index
;
}
for
(
final
int
index
in
SemanticsFlag
.
values
.
keys
)
{
// TODO(mdebbar): Remove this if after https://github.com/flutter/engine/pull/9894
if
(
SemanticsFlag
.
values
[
index
]
!=
SemanticsFlag
.
isMultiline
)
{
flags
|=
index
;
}
flags
|=
index
;
}
final
SemanticsData
data
=
SemanticsData
(
flags:
flags
,
...
...
@@ -655,8 +652,7 @@ void main() {
isInMutuallyExclusiveGroup:
true
,
isHeader:
true
,
isObscured:
true
,
// TODO(mdebbar): Uncomment after https://github.com/flutter/engine/pull/9894
//isMultiline: true,
isMultiline:
true
,
namesRoute:
true
,
scopesRoute:
true
,
isHidden:
true
,
...
...
@@ -721,6 +717,446 @@ void main() {
});
});
group
(
'containsSemantics'
,
()
{
testWidgets
(
'matches SemanticsData'
,
(
WidgetTester
tester
)
async
{
final
SemanticsHandle
handle
=
tester
.
ensureSemantics
();
addTearDown
(()
=>
handle
.
dispose
());
const
Key
key
=
Key
(
'semantics'
);
await
tester
.
pumpWidget
(
Semantics
(
key:
key
,
namesRoute:
true
,
header:
true
,
button:
true
,
link:
true
,
onTap:
()
{
},
onLongPress:
()
{
},
label:
'foo'
,
hint:
'bar'
,
value:
'baz'
,
increasedValue:
'a'
,
decreasedValue:
'b'
,
textDirection:
TextDirection
.
rtl
,
onTapHint:
'scan'
,
onLongPressHint:
'fill'
,
customSemanticsActions:
<
CustomSemanticsAction
,
VoidCallback
>{
const
CustomSemanticsAction
(
label:
'foo'
):
()
{
},
const
CustomSemanticsAction
(
label:
'bar'
):
()
{
},
},
));
expect
(
tester
.
getSemantics
(
find
.
byKey
(
key
)),
containsSemantics
(
label:
'foo'
,
hint:
'bar'
,
value:
'baz'
,
increasedValue:
'a'
,
decreasedValue:
'b'
,
textDirection:
TextDirection
.
rtl
,
hasTapAction:
true
,
hasLongPressAction:
true
,
isButton:
true
,
isLink:
true
,
isHeader:
true
,
namesRoute:
true
,
onTapHint:
'scan'
,
onLongPressHint:
'fill'
,
customActions:
<
CustomSemanticsAction
>[
const
CustomSemanticsAction
(
label:
'foo'
),
const
CustomSemanticsAction
(
label:
'bar'
),
],
),
);
expect
(
tester
.
getSemantics
(
find
.
byKey
(
key
)),
isNot
(
containsSemantics
(
label:
'foo'
,
hint:
'bar'
,
value:
'baz'
,
textDirection:
TextDirection
.
rtl
,
hasTapAction:
true
,
hasLongPressAction:
true
,
isButton:
true
,
isLink:
true
,
isHeader:
true
,
namesRoute:
true
,
onTapHint:
'scan'
,
onLongPressHint:
'fill'
,
customActions:
<
CustomSemanticsAction
>[
const
CustomSemanticsAction
(
label:
'foo'
),
const
CustomSemanticsAction
(
label:
'barz'
),
],
)),
reason:
'CustomSemanticsAction "barz" should not have matched "bar".'
);
expect
(
tester
.
getSemantics
(
find
.
byKey
(
key
)),
isNot
(
matchesSemantics
(
label:
'foo'
,
hint:
'bar'
,
value:
'baz'
,
textDirection:
TextDirection
.
rtl
,
hasTapAction:
true
,
hasLongPressAction:
true
,
isButton:
true
,
isLink:
true
,
isHeader:
true
,
namesRoute:
true
,
onTapHint:
'scans'
,
onLongPressHint:
'fills'
,
customActions:
<
CustomSemanticsAction
>[
const
CustomSemanticsAction
(
label:
'foo'
),
const
CustomSemanticsAction
(
label:
'bar'
),
],
)),
reason:
'onTapHint "scans" should not have matched "scan".'
,
);
});
testWidgets
(
'can match all semantics flags and actions enabled'
,
(
WidgetTester
tester
)
async
{
int
actions
=
0
;
int
flags
=
0
;
const
CustomSemanticsAction
action
=
CustomSemanticsAction
(
label:
'test'
);
for
(
final
int
index
in
SemanticsAction
.
values
.
keys
)
{
actions
|=
index
;
}
for
(
final
int
index
in
SemanticsFlag
.
values
.
keys
)
{
flags
|=
index
;
}
final
SemanticsData
data
=
SemanticsData
(
flags:
flags
,
actions:
actions
,
attributedLabel:
AttributedString
(
'a'
),
attributedIncreasedValue:
AttributedString
(
'b'
),
attributedValue:
AttributedString
(
'c'
),
attributedDecreasedValue:
AttributedString
(
'd'
),
attributedHint:
AttributedString
(
'e'
),
tooltip:
'f'
,
textDirection:
TextDirection
.
ltr
,
rect:
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
elevation:
3.0
,
thickness:
4.0
,
textSelection:
null
,
scrollIndex:
null
,
scrollChildCount:
null
,
scrollPosition:
null
,
scrollExtentMax:
null
,
scrollExtentMin:
null
,
platformViewId:
105
,
customSemanticsActionIds:
<
int
>[
CustomSemanticsAction
.
getIdentifier
(
action
)],
currentValueLength:
10
,
maxValueLength:
15
,
);
final
_FakeSemanticsNode
node
=
_FakeSemanticsNode
(
data
);
expect
(
node
,
containsSemantics
(
rect:
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
size:
const
Size
(
10.0
,
10.0
),
elevation:
3.0
,
thickness:
4.0
,
platformViewId:
105
,
currentValueLength:
10
,
maxValueLength:
15
,
/* Flags */
hasCheckedState:
true
,
isChecked:
true
,
isSelected:
true
,
isButton:
true
,
isSlider:
true
,
isKeyboardKey:
true
,
isLink:
true
,
isTextField:
true
,
isReadOnly:
true
,
hasEnabledState:
true
,
isFocused:
true
,
isFocusable:
true
,
isEnabled:
true
,
isInMutuallyExclusiveGroup:
true
,
isHeader:
true
,
isObscured:
true
,
isMultiline:
true
,
namesRoute:
true
,
scopesRoute:
true
,
isHidden:
true
,
isImage:
true
,
isLiveRegion:
true
,
hasToggledState:
true
,
isToggled:
true
,
hasImplicitScrolling:
true
,
/* Actions */
hasTapAction:
true
,
hasLongPressAction:
true
,
hasScrollLeftAction:
true
,
hasScrollRightAction:
true
,
hasScrollUpAction:
true
,
hasScrollDownAction:
true
,
hasIncreaseAction:
true
,
hasDecreaseAction:
true
,
hasShowOnScreenAction:
true
,
hasMoveCursorForwardByCharacterAction:
true
,
hasMoveCursorBackwardByCharacterAction:
true
,
hasMoveCursorForwardByWordAction:
true
,
hasMoveCursorBackwardByWordAction:
true
,
hasSetTextAction:
true
,
hasSetSelectionAction:
true
,
hasCopyAction:
true
,
hasCutAction:
true
,
hasPasteAction:
true
,
hasDidGainAccessibilityFocusAction:
true
,
hasDidLoseAccessibilityFocusAction:
true
,
hasDismissAction:
true
,
customActions:
<
CustomSemanticsAction
>[
action
],
),
);
});
testWidgets
(
'can match all flags and actions disabled'
,
(
WidgetTester
tester
)
async
{
final
SemanticsData
data
=
SemanticsData
(
flags:
0
,
actions:
0
,
attributedLabel:
AttributedString
(
'a'
),
attributedIncreasedValue:
AttributedString
(
'b'
),
attributedValue:
AttributedString
(
'c'
),
attributedDecreasedValue:
AttributedString
(
'd'
),
attributedHint:
AttributedString
(
'e'
),
tooltip:
'f'
,
textDirection:
TextDirection
.
ltr
,
rect:
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
elevation:
3.0
,
thickness:
4.0
,
textSelection:
null
,
scrollIndex:
null
,
scrollChildCount:
null
,
scrollPosition:
null
,
scrollExtentMax:
null
,
scrollExtentMin:
null
,
platformViewId:
105
,
currentValueLength:
10
,
maxValueLength:
15
,
);
final
_FakeSemanticsNode
node
=
_FakeSemanticsNode
(
data
);
expect
(
node
,
containsSemantics
(
rect:
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
size:
const
Size
(
10.0
,
10.0
),
elevation:
3.0
,
thickness:
4.0
,
platformViewId:
105
,
currentValueLength:
10
,
maxValueLength:
15
,
/* Flags */
hasCheckedState:
false
,
isChecked:
false
,
isSelected:
false
,
isButton:
false
,
isSlider:
false
,
isKeyboardKey:
false
,
isLink:
false
,
isTextField:
false
,
isReadOnly:
false
,
hasEnabledState:
false
,
isFocused:
false
,
isFocusable:
false
,
isEnabled:
false
,
isInMutuallyExclusiveGroup:
false
,
isHeader:
false
,
isObscured:
false
,
isMultiline:
false
,
namesRoute:
false
,
scopesRoute:
false
,
isHidden:
false
,
isImage:
false
,
isLiveRegion:
false
,
hasToggledState:
false
,
isToggled:
false
,
hasImplicitScrolling:
false
,
/* Actions */
hasTapAction:
false
,
hasLongPressAction:
false
,
hasScrollLeftAction:
false
,
hasScrollRightAction:
false
,
hasScrollUpAction:
false
,
hasScrollDownAction:
false
,
hasIncreaseAction:
false
,
hasDecreaseAction:
false
,
hasShowOnScreenAction:
false
,
hasMoveCursorForwardByCharacterAction:
false
,
hasMoveCursorBackwardByCharacterAction:
false
,
hasMoveCursorForwardByWordAction:
false
,
hasMoveCursorBackwardByWordAction:
false
,
hasSetTextAction:
false
,
hasSetSelectionAction:
false
,
hasCopyAction:
false
,
hasCutAction:
false
,
hasPasteAction:
false
,
hasDidGainAccessibilityFocusAction:
false
,
hasDidLoseAccessibilityFocusAction:
false
,
hasDismissAction:
false
,
),
);
});
testWidgets
(
'only matches given flags and actions'
,
(
WidgetTester
tester
)
async
{
int
allActions
=
0
;
int
allFlags
=
0
;
for
(
final
int
index
in
SemanticsAction
.
values
.
keys
)
{
allActions
|=
index
;
}
for
(
final
int
index
in
SemanticsFlag
.
values
.
keys
)
{
allFlags
|=
index
;
}
final
SemanticsData
emptyData
=
SemanticsData
(
flags:
0
,
actions:
0
,
attributedLabel:
AttributedString
(
'a'
),
attributedIncreasedValue:
AttributedString
(
'b'
),
attributedValue:
AttributedString
(
'c'
),
attributedDecreasedValue:
AttributedString
(
'd'
),
attributedHint:
AttributedString
(
'e'
),
tooltip:
'f'
,
textDirection:
TextDirection
.
ltr
,
rect:
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
elevation:
3.0
,
thickness:
4.0
,
textSelection:
null
,
scrollIndex:
null
,
scrollChildCount:
null
,
scrollPosition:
null
,
scrollExtentMax:
null
,
scrollExtentMin:
null
,
platformViewId:
105
,
currentValueLength:
10
,
maxValueLength:
15
,
);
final
_FakeSemanticsNode
emptyNode
=
_FakeSemanticsNode
(
emptyData
);
const
CustomSemanticsAction
action
=
CustomSemanticsAction
(
label:
'test'
);
final
SemanticsData
fullData
=
SemanticsData
(
flags:
allFlags
,
actions:
allActions
,
attributedLabel:
AttributedString
(
'a'
),
attributedIncreasedValue:
AttributedString
(
'b'
),
attributedValue:
AttributedString
(
'c'
),
attributedDecreasedValue:
AttributedString
(
'd'
),
attributedHint:
AttributedString
(
'e'
),
tooltip:
'f'
,
textDirection:
TextDirection
.
ltr
,
rect:
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
elevation:
3.0
,
thickness:
4.0
,
textSelection:
null
,
scrollIndex:
null
,
scrollChildCount:
null
,
scrollPosition:
null
,
scrollExtentMax:
null
,
scrollExtentMin:
null
,
platformViewId:
105
,
currentValueLength:
10
,
maxValueLength:
15
,
customSemanticsActionIds:
<
int
>[
CustomSemanticsAction
.
getIdentifier
(
action
)],
);
final
_FakeSemanticsNode
fullNode
=
_FakeSemanticsNode
(
fullData
);
expect
(
emptyNode
,
containsSemantics
(
rect:
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
size:
const
Size
(
10.0
,
10.0
),
elevation:
3.0
,
thickness:
4.0
,
platformViewId:
105
,
currentValueLength:
10
,
maxValueLength:
15
,
),
);
expect
(
fullNode
,
containsSemantics
(
rect:
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
size:
const
Size
(
10.0
,
10.0
),
elevation:
3.0
,
thickness:
4.0
,
platformViewId:
105
,
currentValueLength:
10
,
maxValueLength:
15
,
customActions:
<
CustomSemanticsAction
>[
action
],
),
);
});
testWidgets
(
'can match child semantics'
,
(
WidgetTester
tester
)
async
{
final
SemanticsHandle
handle
=
tester
.
ensureSemantics
();
const
Key
key
=
Key
(
'a'
);
await
tester
.
pumpWidget
(
Semantics
(
key:
key
,
label:
'Foo'
,
container:
true
,
explicitChildNodes:
true
,
textDirection:
TextDirection
.
ltr
,
child:
Semantics
(
label:
'Bar'
,
textDirection:
TextDirection
.
ltr
,
),
));
final
SemanticsNode
node
=
tester
.
getSemantics
(
find
.
byKey
(
key
));
expect
(
node
,
containsSemantics
(
label:
'Foo'
,
textDirection:
TextDirection
.
ltr
,
children:
<
Matcher
>[
containsSemantics
(
label:
'Bar'
,
textDirection:
TextDirection
.
ltr
,
),
],
),
);
handle
.
dispose
();
});
testWidgets
(
'can match only custom actions'
,
(
WidgetTester
tester
)
async
{
const
CustomSemanticsAction
action
=
CustomSemanticsAction
(
label:
'test'
);
final
SemanticsData
data
=
SemanticsData
(
flags:
0
,
actions:
SemanticsAction
.
customAction
.
index
,
attributedLabel:
AttributedString
(
'a'
),
attributedIncreasedValue:
AttributedString
(
'b'
),
attributedValue:
AttributedString
(
'c'
),
attributedDecreasedValue:
AttributedString
(
'd'
),
attributedHint:
AttributedString
(
'e'
),
tooltip:
'f'
,
textDirection:
TextDirection
.
ltr
,
rect:
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
10.0
,
10.0
),
elevation:
3.0
,
thickness:
4.0
,
textSelection:
null
,
scrollIndex:
null
,
scrollChildCount:
null
,
scrollPosition:
null
,
scrollExtentMax:
null
,
scrollExtentMin:
null
,
platformViewId:
105
,
currentValueLength:
10
,
maxValueLength:
15
,
customSemanticsActionIds:
<
int
>[
CustomSemanticsAction
.
getIdentifier
(
action
)],
);
final
_FakeSemanticsNode
node
=
_FakeSemanticsNode
(
data
);
expect
(
node
,
containsSemantics
(
customActions:
<
CustomSemanticsAction
>[
action
]));
});
});
group
(
'findsAtLeastNWidgets'
,
()
{
Widget
boilerplate
(
Widget
child
)
{
return
Directionality
(
...
...
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