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
ee8488e8
Unverified
Commit
ee8488e8
authored
Aug 29, 2022
by
Greg Spencer
Committed by
GitHub
Aug 29, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove warnings when `UnconstrainedBox` and `ConstraintsTransformBox` are clipped (#110393)
parent
45570b13
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
312 additions
and
128 deletions
+312
-128
shifted_box.dart
packages/flutter/lib/src/rendering/shifted_box.dart
+19
-9
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+14
-7
box_test.dart
packages/flutter/test/rendering/box_test.dart
+100
-27
editable_test.dart
packages/flutter/test/rendering/editable_test.dart
+35
-31
flex_test.dart
packages/flutter/test/rendering/flex_test.dart
+23
-11
proxy_box_test.dart
packages/flutter/test/rendering/proxy_box_test.dart
+17
-12
rendering_tester.dart
packages/flutter/test/rendering/rendering_tester.dart
+14
-5
stack_test.dart
packages/flutter/test/rendering/stack_test.dart
+25
-16
wrap_test.dart
packages/flutter/test/rendering/wrap_test.dart
+16
-10
basic_test.dart
packages/flutter/test/widgets/basic_test.dart
+49
-0
No files found.
packages/flutter/lib/src/rendering/shifted_box.dart
View file @
ee8488e8
...
@@ -656,9 +656,9 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox {
...
@@ -656,9 +656,9 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox {
}
}
}
}
/// A [RenderBox] that applies an arbitrary transform to its
[constraints]
/// A [RenderBox] that applies an arbitrary transform to its
constraints,
///
before sizing its child using the new constraints, treating any overflow as
///
and sizes its child using the resulting [BoxConstraints], optionally
/// error.
///
clipping, or treating the overflow as an
error.
///
///
/// This [RenderBox] sizes its child using a [BoxConstraints] created by
/// This [RenderBox] sizes its child using a [BoxConstraints] created by
/// applying [constraintsTransform] to this [RenderBox]'s own [constraints].
/// applying [constraintsTransform] to this [RenderBox]'s own [constraints].
...
@@ -668,9 +668,9 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox {
...
@@ -668,9 +668,9 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox {
/// the entire child, the child will be clipped if [clipBehavior] is not
/// the entire child, the child will be clipped if [clipBehavior] is not
/// [Clip.none].
/// [Clip.none].
///
///
/// In debug mode, if
the child overflows the box, a warning will be printed on
/// In debug mode, if
[clipBehavior] is [Clip.none] and the child overflows the
///
the console, and black and yellow striped areas will appear where the
///
container, a warning will be printed on the console, and black and yellow
/// overflow occurs.
///
striped areas will appear where the
overflow occurs.
///
///
/// When [child] is null, this [RenderBox] takes the smallest possible size and
/// When [child] is null, this [RenderBox] takes the smallest possible size and
/// never overflows.
/// never overflows.
...
@@ -732,7 +732,9 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
...
@@ -732,7 +732,9 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
/// {@macro flutter.material.Material.clipBehavior}
/// {@macro flutter.material.Material.clipBehavior}
///
///
/// Defaults to [Clip.none], and must not be null.
/// {@macro flutter.widgets.ConstraintsTransformBox.clipBehavior}
///
/// Defaults to [Clip.none].
Clip
get
clipBehavior
=>
_clipBehavior
;
Clip
get
clipBehavior
=>
_clipBehavior
;
Clip
_clipBehavior
;
Clip
_clipBehavior
;
set
clipBehavior
(
Clip
value
)
{
set
clipBehavior
(
Clip
value
)
{
...
@@ -830,9 +832,17 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
...
@@ -830,9 +832,17 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
oldLayer:
_clipRectLayer
.
layer
,
oldLayer:
_clipRectLayer
.
layer
,
);
);
// Display the overflow indicator.
// Display the overflow indicator
if clipBehavior is Clip.none
.
assert
(()
{
assert
(()
{
switch
(
clipBehavior
)
{
case
Clip
.
none
:
paintOverflowIndicator
(
context
,
offset
,
_overflowContainerRect
,
_overflowChildRect
);
paintOverflowIndicator
(
context
,
offset
,
_overflowContainerRect
,
_overflowChildRect
);
break
;
case
Clip
.
hardEdge
:
case
Clip
.
antiAlias
:
case
Clip
.
antiAliasWithSaveLayer
:
break
;
}
return
true
;
return
true
;
}());
}());
}
}
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
ee8488e8
...
@@ -2513,8 +2513,8 @@ class ConstrainedBox extends SingleChildRenderObjectWidget {
...
@@ -2513,8 +2513,8 @@ class ConstrainedBox extends SingleChildRenderObjectWidget {
}
}
/// A container widget that applies an arbitrary transform to its constraints,
/// A container widget that applies an arbitrary transform to its constraints,
/// and sizes its child using the resulting [BoxConstraints],
treating an
y
/// and sizes its child using the resulting [BoxConstraints],
optionall
y
///
overflow as
error.
///
clipping, or treating the overflow as an
error.
///
///
/// This container sizes its child using a [BoxConstraints] created by applying
/// This container sizes its child using a [BoxConstraints] created by applying
/// [constraintsTransform] to its own constraints. This container will then
/// [constraintsTransform] to its own constraints. This container will then
...
@@ -2523,12 +2523,12 @@ class ConstrainedBox extends SingleChildRenderObjectWidget {
...
@@ -2523,12 +2523,12 @@ class ConstrainedBox extends SingleChildRenderObjectWidget {
/// [alignment]. If the container cannot expand enough to accommodate the entire
/// [alignment]. If the container cannot expand enough to accommodate the entire
/// child, the child will be clipped if [clipBehavior] is not [Clip.none].
/// child, the child will be clipped if [clipBehavior] is not [Clip.none].
///
///
/// In debug mode, if
the child overflows the container, a warning will b
e
/// In debug mode, if
[clipBehavior] is [Clip.none] and the child overflows th
e
///
printed on the console, and black and yellow striped areas will appear where
///
container, a warning will be printed on the console, and black and yellow
/// the overflow occurs.
///
striped areas will appear where
the overflow occurs.
///
///
/// When [child] is null, this widget becomes as small as possible and never
/// When [child] is null, this widget becomes as small as possible and never
/// overflows
/// overflows
.
///
///
/// This widget can be used to ensure some of [child]'s natural dimensions are
/// This widget can be used to ensure some of [child]'s natural dimensions are
/// honored, and get an early warning otherwise during development. For
/// honored, and get an early warning otherwise during development. For
...
@@ -2564,7 +2564,7 @@ class ConstrainedBox extends SingleChildRenderObjectWidget {
...
@@ -2564,7 +2564,7 @@ class ConstrainedBox extends SingleChildRenderObjectWidget {
/// * [OverflowBox], a widget that imposes additional constraints on its child,
/// * [OverflowBox], a widget that imposes additional constraints on its child,
/// and allows the child to overflow itself.
/// and allows the child to overflow itself.
/// * [UnconstrainedBox] which allows its children to render themselves
/// * [UnconstrainedBox] which allows its children to render themselves
/// unconstrained
, expands to fit them, and considers overflow to be an error
.
/// unconstrained
and expands to fit them
.
class
ConstraintsTransformBox
extends
SingleChildRenderObjectWidget
{
class
ConstraintsTransformBox
extends
SingleChildRenderObjectWidget
{
/// Creates a widget that uses a function to transform the constraints it
/// Creates a widget that uses a function to transform the constraints it
/// passes to its child. If the child overflows the parent's constraints, a
/// passes to its child. If the child overflows the parent's constraints, a
...
@@ -2686,6 +2686,13 @@ class ConstraintsTransformBox extends SingleChildRenderObjectWidget {
...
@@ -2686,6 +2686,13 @@ class ConstraintsTransformBox extends SingleChildRenderObjectWidget {
/// {@macro flutter.material.Material.clipBehavior}
/// {@macro flutter.material.Material.clipBehavior}
///
///
/// {@template flutter.widgets.ConstraintsTransformBox.clipBehavior}
/// In debug mode, if `clipBehavior` is [Clip.none], and the child overflows
/// its constraints, a warning will be printed on the console, and black and
/// yellow striped areas will appear where the overflow occurs. For other
/// values of `clipBehavior`, the contents are clipped accordingly.
/// {@endtemplate}
///
/// Defaults to [Clip.none].
/// Defaults to [Clip.none].
final
Clip
clipBehavior
;
final
Clip
clipBehavior
;
...
...
packages/flutter/test/rendering/box_test.dart
View file @
ee8488e8
...
@@ -410,16 +410,65 @@ void main() {
...
@@ -410,16 +410,65 @@ void main() {
expect
(
firstErrorDetails
?.
toString
(),
contains
(
'is not normalized'
));
expect
(
firstErrorDetails
?.
toString
(),
contains
(
'is not normalized'
));
});
});
test
(
'overflow is reported when insufficient size is given'
,
()
{
test
(
'overflow is reported when insufficient size is given and clipBehavior is Clip.none'
,
()
{
final
RenderConstrainedBox
child
=
RenderConstrainedBox
(
additionalConstraints:
const
BoxConstraints
.
tightFor
(
width:
double
.
maxFinite
));
bool
hadErrors
=
false
;
final
RenderConstraintsTransformBox
box
=
RenderConstraintsTransformBox
(
void
expectOverflowedErrors
()
{
absorbOverflowedErrors
();
hadErrors
=
true
;
}
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
for
(
final
Clip
?
clip
in
<
Clip
?>[
null
,
...
Clip
.
values
])
{
final
RenderConstraintsTransformBox
box
;
switch
(
clip
)
{
case
Clip
.
none
:
case
Clip
.
hardEdge
:
case
Clip
.
antiAlias
:
case
Clip
.
antiAliasWithSaveLayer
:
box
=
RenderConstraintsTransformBox
(
alignment:
Alignment
.
center
,
alignment:
Alignment
.
center
,
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
constraintsTransform:
(
BoxConstraints
constraints
)
=>
constraints
.
copyWith
(
maxWidth:
double
.
infinity
),
constraintsTransform:
(
BoxConstraints
constraints
)
=>
constraints
.
copyWith
(
maxWidth:
double
.
infinity
),
child:
child
,
clipBehavior:
clip
!,
child:
RenderConstrainedBox
(
additionalConstraints:
const
BoxConstraints
.
tightFor
(
width:
double
.
maxFinite
,
height:
double
.
maxFinite
,
),
),
);
);
break
;
case
null
:
box
=
RenderConstraintsTransformBox
(
alignment:
Alignment
.
center
,
textDirection:
TextDirection
.
ltr
,
constraintsTransform:
(
BoxConstraints
constraints
)
=>
constraints
.
copyWith
(
maxWidth:
double
.
infinity
),
child:
RenderConstrainedBox
(
additionalConstraints:
const
BoxConstraints
.
tightFor
(
width:
double
.
maxFinite
,
height:
double
.
maxFinite
,
),
),
);
break
;
}
layout
(
box
,
constraints:
const
BoxConstraints
(),
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
layout
(
box
,
constraints:
const
BoxConstraints
(),
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
context
.
paintChild
(
box
,
Offset
.
zero
);
// By default, clipBehavior should be Clip.none
expect
(
context
.
clipBehavior
,
equals
(
clip
??
Clip
.
none
));
switch
(
clip
)
{
case
null
:
case
Clip
.
none
:
expect
(
hadErrors
,
isTrue
,
reason:
'Should have had overflow errors for
$clip
'
);
break
;
case
Clip
.
hardEdge
:
case
Clip
.
antiAlias
:
case
Clip
.
antiAliasWithSaveLayer
:
expect
(
hadErrors
,
isFalse
,
reason:
'Should not have had overflow errors for
$clip
'
);
break
;
}
hadErrors
=
false
;
}
});
});
test
(
'handles flow layout'
,
()
{
test
(
'handles flow layout'
,
()
{
...
@@ -642,26 +691,50 @@ void main() {
...
@@ -642,26 +691,50 @@ void main() {
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
// By default, clipBehavior should be Clip.none
bool
hadErrors
=
false
;
final
RenderUnconstrainedBox
defaultBox
=
RenderUnconstrainedBox
(
void
expectOverflowedErrors
()
{
absorbOverflowedErrors
();
hadErrors
=
true
;
}
for
(
final
Clip
?
clip
in
<
Clip
?>[
null
,
...
Clip
.
values
])
{
final
RenderUnconstrainedBox
box
;
switch
(
clip
)
{
case
Clip
.
none
:
case
Clip
.
hardEdge
:
case
Clip
.
antiAlias
:
case
Clip
.
antiAliasWithSaveLayer
:
box
=
RenderUnconstrainedBox
(
alignment:
Alignment
.
center
,
alignment:
Alignment
.
center
,
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
box200x200
,
child:
box200x200
,
clipBehavior:
clip
!,
);
);
layout
(
defaultBox
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
break
;
context
.
paintChild
(
defaultBox
,
Offset
.
zero
);
case
null
:
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
none
));
box
=
RenderUnconstrainedBox
(
for
(
final
Clip
clip
in
Clip
.
values
)
{
final
RenderUnconstrainedBox
box
=
RenderUnconstrainedBox
(
alignment:
Alignment
.
center
,
alignment:
Alignment
.
center
,
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
child:
box200x200
,
child:
box200x200
,
clipBehavior:
clip
,
);
);
break
;
}
layout
(
box
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
layout
(
box
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
switch
(
clip
)
{
case
null
:
case
Clip
.
none
:
expect
(
hadErrors
,
isTrue
,
reason:
'Should have had overflow errors for
$clip
'
);
break
;
case
Clip
.
hardEdge
:
case
Clip
.
antiAlias
:
case
Clip
.
antiAliasWithSaveLayer
:
expect
(
hadErrors
,
isFalse
,
reason:
'Should not have had overflow errors for
$clip
'
);
break
;
}
hadErrors
=
false
;
context
.
paintChild
(
box
,
Offset
.
zero
);
context
.
paintChild
(
box
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
// By default, clipBehavior should be Clip.none
expect
(
context
.
clipBehavior
,
equals
(
clip
??
Clip
.
none
),
reason:
'for
$clip
'
);
}
}
});
});
...
...
packages/flutter/test/rendering/editable_test.dart
View file @
ee8488e8
...
@@ -54,13 +54,18 @@ void main() {
...
@@ -54,13 +54,18 @@ void main() {
TestRenderingFlutterBinding
.
ensureInitialized
();
TestRenderingFlutterBinding
.
ensureInitialized
();
test
(
'RenderEditable respects clipBehavior'
,
()
{
test
(
'RenderEditable respects clipBehavior'
,
()
{
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
1.0
);
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
final
String
longString
=
'a'
*
10000
;
final
String
longString
=
'a'
*
10000
;
// By default, clipBehavior should be Clip.none
for
(
final
Clip
?
clip
in
<
Clip
?>[
null
,
...
Clip
.
values
])
{
final
RenderEditable
defaultEditable
=
RenderEditable
(
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
final
RenderEditable
editable
;
switch
(
clip
)
{
case
Clip
.
none
:
case
Clip
.
hardEdge
:
case
Clip
.
antiAlias
:
case
Clip
.
antiAliasWithSaveLayer
:
editable
=
RenderEditable
(
text:
TextSpan
(
text:
longString
),
text:
TextSpan
(
text:
longString
),
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
startHandleLayerLink:
LayerLink
(),
startHandleLayerLink:
LayerLink
(),
...
@@ -68,14 +73,11 @@ void main() {
...
@@ -68,14 +73,11 @@ void main() {
offset:
ViewportOffset
.
zero
(),
offset:
ViewportOffset
.
zero
(),
textSelectionDelegate:
_FakeEditableTextState
(),
textSelectionDelegate:
_FakeEditableTextState
(),
selection:
const
TextSelection
(
baseOffset:
0
,
extentOffset:
0
),
selection:
const
TextSelection
(
baseOffset:
0
,
extentOffset:
0
),
clipBehavior:
clip
!,
);
);
layout
(
defaultEditable
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
break
;
context
.
paintChild
(
defaultEditable
,
Offset
.
zero
);
case
null
:
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
hardEdge
));
editable
=
RenderEditable
(
context
.
clipBehavior
=
Clip
.
none
;
// Reset as Clip.none won't write into clipBehavior.
for
(
final
Clip
clip
in
Clip
.
values
)
{
final
RenderEditable
editable
=
RenderEditable
(
text:
TextSpan
(
text:
longString
),
text:
TextSpan
(
text:
longString
),
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
startHandleLayerLink:
LayerLink
(),
startHandleLayerLink:
LayerLink
(),
...
@@ -83,11 +85,13 @@ void main() {
...
@@ -83,11 +85,13 @@ void main() {
offset:
ViewportOffset
.
zero
(),
offset:
ViewportOffset
.
zero
(),
textSelectionDelegate:
_FakeEditableTextState
(),
textSelectionDelegate:
_FakeEditableTextState
(),
selection:
const
TextSelection
(
baseOffset:
0
,
extentOffset:
0
),
selection:
const
TextSelection
(
baseOffset:
0
,
extentOffset:
0
),
clipBehavior:
clip
,
);
);
layout
(
editable
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
break
;
}
layout
(
editable
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectNoFlutterErrors
);
context
.
paintChild
(
editable
,
Offset
.
zero
);
context
.
paintChild
(
editable
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
// By default, clipBehavior is Clip.hardEdge.
expect
(
context
.
clipBehavior
,
equals
(
clip
??
Clip
.
hardEdge
),
reason:
'for
$clip
'
);
}
}
});
});
...
...
packages/flutter/test/rendering/flex_test.dart
View file @
ee8488e8
...
@@ -60,18 +60,30 @@ void main() {
...
@@ -60,18 +60,30 @@ void main() {
test
(
'Clip behavior is respected'
,
()
{
test
(
'Clip behavior is respected'
,
()
{
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
bool
hadErrors
=
false
;
// By default, clipBehavior should be Clip.none
final
RenderFlex
defaultFlex
=
RenderFlex
(
direction:
Axis
.
vertical
,
children:
<
RenderBox
>[
box200x200
]);
for
(
final
Clip
?
clip
in
<
Clip
?>[
null
,
...
Clip
.
values
])
{
layout
(
defaultFlex
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
final
RenderFlex
flex
;
context
.
paintChild
(
defaultFlex
,
Offset
.
zero
);
switch
(
clip
)
{
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
none
));
case
Clip
.
none
:
case
Clip
.
hardEdge
:
for
(
final
Clip
clip
in
Clip
.
values
)
{
case
Clip
.
antiAlias
:
final
RenderFlex
flex
=
RenderFlex
(
direction:
Axis
.
vertical
,
children:
<
RenderBox
>[
box200x200
],
clipBehavior:
clip
);
case
Clip
.
antiAliasWithSaveLayer
:
layout
(
flex
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
flex
=
RenderFlex
(
direction:
Axis
.
vertical
,
children:
<
RenderBox
>[
box200x200
],
clipBehavior:
clip
!);
break
;
case
null
:
flex
=
RenderFlex
(
direction:
Axis
.
vertical
,
children:
<
RenderBox
>[
box200x200
]);
break
;
}
layout
(
flex
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
()
{
absorbOverflowedErrors
();
hadErrors
=
true
;
});
context
.
paintChild
(
flex
,
Offset
.
zero
);
context
.
paintChild
(
flex
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
// By default, clipBehavior should be Clip.none
expect
(
context
.
clipBehavior
,
equals
(
clip
??
Clip
.
none
));
expect
(
hadErrors
,
isTrue
);
hadErrors
=
false
;
}
}
});
});
...
...
packages/flutter/test/rendering/proxy_box_test.dart
View file @
ee8488e8
...
@@ -536,19 +536,24 @@ void main() {
...
@@ -536,19 +536,24 @@ void main() {
test
(
'RenderFittedBox respects clipBehavior'
,
()
{
test
(
'RenderFittedBox respects clipBehavior'
,
()
{
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
for
(
final
Clip
?
clip
in
<
Clip
?>[
null
,
...
Clip
.
values
])
{
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
final
RenderFittedBox
box
;
// By default, clipBehavior should be Clip.none
switch
(
clip
)
{
final
RenderFittedBox
defaultBox
=
RenderFittedBox
(
child:
box200x200
,
fit:
BoxFit
.
none
);
case
Clip
.
none
:
layout
(
defaultBox
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
case
Clip
.
hardEdge
:
defaultBox
.
paint
(
context
,
Offset
.
zero
);
case
Clip
.
antiAlias
:
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
none
));
case
Clip
.
antiAliasWithSaveLayer
:
box
=
RenderFittedBox
(
child:
box200x200
,
fit:
BoxFit
.
none
,
clipBehavior:
clip
!);
for
(
final
Clip
clip
in
Clip
.
values
)
{
break
;
final
RenderFittedBox
box
=
RenderFittedBox
(
child:
box200x200
,
fit:
BoxFit
.
none
,
clipBehavior:
clip
);
case
null
:
layout
(
box
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
box
=
RenderFittedBox
(
child:
box200x200
,
fit:
BoxFit
.
none
);
break
;
}
layout
(
box
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectNoFlutterErrors
);
box
.
paint
(
context
,
Offset
.
zero
);
box
.
paint
(
context
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
// By default, clipBehavior should be Clip.none
expect
(
context
.
clipBehavior
,
equals
(
clip
??
Clip
.
none
));
}
}
});
});
...
...
packages/flutter/test/rendering/rendering_tester.dart
View file @
ee8488e8
...
@@ -382,13 +382,22 @@ class TestPushLayerPaintingContext extends PaintingContext {
...
@@ -382,13 +382,22 @@ class TestPushLayerPaintingContext extends PaintingContext {
}
}
}
}
void
expectOverflowedErrors
(
)
{
// Absorbs errors that don't have "overflowed" in their error details.
final
FlutterErrorDetails
errorDetails
=
TestRenderingFlutterBinding
.
instance
.
takeFlutterErrorDetails
()!;
void
absorbOverflowedErrors
(
)
{
final
bool
overflowed
=
errorDetails
.
toString
().
contains
(
'overflowed'
);
final
Iterable
<
FlutterErrorDetails
>
errorDetails
=
TestRenderingFlutterBinding
.
instance
.
takeAllFlutterErrorDetails
();
if
(!
overflowed
)
{
final
Iterable
<
FlutterErrorDetails
>
filtered
=
errorDetails
.
where
((
FlutterErrorDetails
details
)
{
FlutterError
.
reportError
(
errorDetails
);
return
!
details
.
toString
().
contains
(
'overflowed'
);
});
if
(
filtered
.
isNotEmpty
)
{
filtered
.
forEach
(
FlutterError
.
reportError
);
}
}
}
}
// Reports any FlutterErrors.
void
expectNoFlutterErrors
(
)
{
final
Iterable
<
FlutterErrorDetails
>
errorDetails
=
TestRenderingFlutterBinding
.
instance
.
takeAllFlutterErrorDetails
();
errorDetails
.
forEach
(
FlutterError
.
reportError
);
}
RenderConstrainedBox
get
box200x200
=>
RenderConstrainedBox
get
box200x200
=>
RenderConstrainedBox
(
additionalConstraints:
const
BoxConstraints
.
tightFor
(
height:
200.0
,
width:
200.0
));
RenderConstrainedBox
(
additionalConstraints:
const
BoxConstraints
.
tightFor
(
height:
200.0
,
width:
200.0
));
packages/flutter/test/rendering/stack_test.dart
View file @
ee8488e8
...
@@ -63,30 +63,39 @@ void main() {
...
@@ -63,30 +63,39 @@ void main() {
expect
(
stack
.
size
.
height
,
equals
(
100.0
));
expect
(
stack
.
size
.
height
,
equals
(
100.0
));
});
});
test
(
'Stack
respects
clipBehavior'
,
()
{
test
(
'Stack
has correct
clipBehavior'
,
()
{
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
// By default, clipBehavior should be Clip.none
final
RenderStack
defaultStack
=
RenderStack
(
textDirection:
TextDirection
.
ltr
,
children:
<
RenderBox
>[
box200x200
]);
layout
(
defaultStack
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
defaultStack
.
paint
(
context
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
none
));
for
(
final
Clip
clip
in
Clip
.
values
)
{
for
(
final
Clip
?
clip
in
<
Clip
?>[
null
,
...
Clip
.
values
])
{
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
final
RenderBox
child
=
box200x200
;
final
RenderBox
child
=
box200x200
;
final
RenderStack
stack
=
RenderStack
(
final
RenderStack
stack
;
switch
(
clip
){
case
Clip
.
none
:
case
Clip
.
hardEdge
:
case
Clip
.
antiAlias
:
case
Clip
.
antiAliasWithSaveLayer
:
stack
=
RenderStack
(
textDirection:
TextDirection
.
ltr
,
textDirection:
TextDirection
.
ltr
,
children:
<
RenderBox
>[
child
],
children:
<
RenderBox
>[
child
],
clipBehavior:
clip
,
clipBehavior:
clip
!
,
);
);
break
;
case
null
:
stack
=
RenderStack
(
textDirection:
TextDirection
.
ltr
,
children:
<
RenderBox
>[
child
],
);
break
;
}
{
// Make sure that the child is positioned so the stack will consider it as overflowed.
{
// Make sure that the child is positioned so the stack will consider it as overflowed.
final
StackParentData
parentData
=
child
.
parentData
!
as
StackParentData
;
final
StackParentData
parentData
=
child
.
parentData
!
as
StackParentData
;
parentData
.
left
=
parentData
.
right
=
0
;
parentData
.
left
=
parentData
.
right
=
0
;
}
}
layout
(
stack
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expect
Overflowed
Errors
);
layout
(
stack
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expect
NoFlutter
Errors
);
context
.
paintChild
(
stack
,
Offset
.
zero
);
context
.
paintChild
(
stack
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
// By default, clipBehavior should be Clip.hardEdge
expect
(
context
.
clipBehavior
,
equals
(
clip
??
Clip
.
hardEdge
),
reason:
'for
$clip
'
);
}
}
});
});
...
...
packages/flutter/test/rendering/wrap_test.dart
View file @
ee8488e8
...
@@ -208,17 +208,23 @@ void main() {
...
@@ -208,17 +208,23 @@ void main() {
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
const
BoxConstraints
viewport
=
BoxConstraints
(
maxHeight:
100.0
,
maxWidth:
100.0
);
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
final
TestClipPaintingContext
context
=
TestClipPaintingContext
();
// By default, clipBehavior should be Clip.none
for
(
final
Clip
?
clip
in
<
Clip
?>[
null
,
...
Clip
.
values
])
{
final
RenderWrap
defaultWrap
=
RenderWrap
(
textDirection:
TextDirection
.
ltr
,
children:
<
RenderBox
>[
box200x200
]);
final
RenderWrap
wrap
;
layout
(
defaultWrap
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
switch
(
clip
){
context
.
paintChild
(
defaultWrap
,
Offset
.
zero
);
case
Clip
.
none
:
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
none
));
case
Clip
.
hardEdge
:
case
Clip
.
antiAlias
:
for
(
final
Clip
clip
in
Clip
.
values
)
{
case
Clip
.
antiAliasWithSaveLayer
:
final
RenderWrap
wrap
=
RenderWrap
(
textDirection:
TextDirection
.
ltr
,
children:
<
RenderBox
>[
box200x200
],
clipBehavior:
clip
);
wrap
=
RenderWrap
(
textDirection:
TextDirection
.
ltr
,
children:
<
RenderBox
>[
box200x200
],
clipBehavior:
clip
!);
layout
(
wrap
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
break
;
case
null
:
wrap
=
RenderWrap
(
textDirection:
TextDirection
.
ltr
,
children:
<
RenderBox
>[
box200x200
]);
break
;
}
layout
(
wrap
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectNoFlutterErrors
);
context
.
paintChild
(
wrap
,
Offset
.
zero
);
context
.
paintChild
(
wrap
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
// By default, clipBehavior should be Clip.none
expect
(
context
.
clipBehavior
,
equals
(
clip
??
Clip
.
none
));
}
}
});
});
}
}
packages/flutter/test/widgets/basic_test.dart
View file @
ee8488e8
...
@@ -578,6 +578,55 @@ void main() {
...
@@ -578,6 +578,55 @@ void main() {
expect
(
renderObject
.
clipBehavior
,
equals
(
Clip
.
antiAlias
));
expect
(
renderObject
.
clipBehavior
,
equals
(
Clip
.
antiAlias
));
});
});
testWidgets
(
'UnconstrainedBox warns only when clipBehavior is Clip.none'
,
(
WidgetTester
tester
)
async
{
for
(
final
Clip
?
clip
in
<
Clip
?>[
null
,
...
Clip
.
values
])
{
// Clear any render objects that were there before so that we can see more
// than one error. Otherwise, it just throws the first one and skips the
// rest, since the render objects haven't changed.
await
tester
.
pumpWidget
(
const
SizedBox
());
await
tester
.
pumpWidget
(
Center
(
child:
ConstrainedBox
(
constraints:
const
BoxConstraints
(
maxHeight:
200
,
maxWidth:
200
),
child:
clip
==
null
?
const
UnconstrainedBox
(
child:
SizedBox
(
width:
400
,
height:
400
))
:
UnconstrainedBox
(
clipBehavior:
clip
,
child:
const
SizedBox
(
width:
400
,
height:
400
),
),
),
),
);
final
RenderConstraintsTransformBox
renderObject
=
tester
.
allRenderObjects
.
whereType
<
RenderConstraintsTransformBox
>().
first
;
// Defaults to Clip.none
expect
(
renderObject
.
clipBehavior
,
equals
(
clip
??
Clip
.
none
),
reason:
'for clip =
$clip
'
);
switch
(
clip
)
{
case
null
:
case
Clip
.
none
:
// the UnconstrainedBox overflows.
final
dynamic
exception
=
tester
.
takeException
();
expect
(
exception
,
isFlutterError
,
reason:
'for clip =
$clip
'
);
// ignore: avoid_dynamic_calls
expect
(
exception
.
diagnostics
.
first
.
level
,
DiagnosticLevel
.
summary
,
reason:
'for clip =
$clip
'
);
expect
(
// ignore: avoid_dynamic_calls
exception
.
diagnostics
.
first
.
toString
(),
startsWith
(
'A RenderConstraintsTransformBox overflowed'
),
reason:
'for clip =
$clip
'
,
);
break
;
case
Clip
.
hardEdge
:
case
Clip
.
antiAlias
:
case
Clip
.
antiAliasWithSaveLayer
:
expect
(
tester
.
takeException
(),
isNull
,
reason:
'for clip =
$clip
'
);
break
;
}
}
});
group
(
'ConstraintsTransformBox'
,
()
{
group
(
'ConstraintsTransformBox'
,
()
{
test
(
'toString'
,
()
{
test
(
'toString'
,
()
{
expect
(
expect
(
...
...
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