Unverified Commit cf87f68f authored by Hans Muller's avatar Hans Muller Committed by GitHub

Correct InheritedTheme.captureAll() for multiple theme ancestors of the same type (#39089)

parent d1e0273e
......@@ -114,10 +114,18 @@ abstract class InheritedTheme extends InheritedWidget {
assert(context != null);
final List<InheritedTheme> themes = <InheritedTheme>[];
final Set<Type> themeTypes = <Type>{};
context.visitAncestorElements((Element ancestor) {
if (ancestor is InheritedElement && ancestor.widget is InheritedTheme) {
final InheritedTheme theme = ancestor.widget;
themes.add(theme);
final Type themeType = theme.runtimeType;
// Only remember the first theme of any type. This assumes
// that inherited themes completely shadow ancestors of the
// the same type.
if (!themeTypes.contains(themeType)) {
themeTypes.add(themeType);
themes.add(theme);
}
}
return true;
});
......
......@@ -144,6 +144,111 @@ void main() {
expect(getTextStyle('Hello').fontSize, fontSize);
expect(getIconStyle().color, iconColor);
expect(getIconStyle().fontSize, iconSize);
});
testWidgets('InheritedTheme.captureAll() multiple IconTheme ancestors', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/39087
const Color outerColor = Color(0xFF0000FF);
const Color innerColor = Color(0xFF00FF00);
const double iconSize = 48;
final Key icon1 = UniqueKey();
final Key icon2 = UniqueKey();
await tester.pumpWidget(
WidgetsApp(
color: const Color(0xFFFFFFFF),
onGenerateRoute: (RouteSettings settings) {
return TestRoute(
IconTheme(
data: const IconThemeData(color: outerColor),
child: IconTheme(
data: const IconThemeData(size: iconSize, color: innerColor),
child: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(const IconData(0x41, fontFamily: 'Roboto'), key: icon1),
Builder(
builder: (BuildContext context) {
// The same IconThemes are visible from this context
// and the context that the widget returned by captureAll()
// is built in. So only the inner green IconTheme should
// apply to the icon, i.e. both icons will be big and green.
return InheritedTheme.captureAll(
context,
Icon(const IconData(0x41, fontFamily: 'Roboto'), key: icon2),
);
},
),
],
),
),
),
),
);
},
)
);
TextStyle getIconStyle(Key key) {
return tester.widget<RichText>(
find.descendant(
of: find.byKey(key),
matching: find.byType(RichText),
),
).text.style;
}
expect(getIconStyle(icon1).color, innerColor);
expect(getIconStyle(icon1).fontSize, iconSize);
expect(getIconStyle(icon2).color, innerColor);
expect(getIconStyle(icon2).fontSize, iconSize);
});
testWidgets('InheritedTheme.captureAll() multiple DefaultTextStyle ancestors', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/39087
const Color textColor = Color(0xFF00FF00);
await tester.pumpWidget(
WidgetsApp(
color: const Color(0xFFFFFFFF),
onGenerateRoute: (RouteSettings settings) {
return TestRoute(
DefaultTextStyle(
style: const TextStyle(fontSize: 48),
child: DefaultTextStyle(
style: const TextStyle(color: textColor),
child: Row(
children: <Widget>[
const Text('Hello'),
Builder(
builder: (BuildContext context) {
return InheritedTheme.captureAll(context, const Text('World'));
},
),
],
),
),
),
);
},
),
);
TextStyle getTextStyle(String text) {
return tester.widget<RichText>(
find.descendant(
of: find.text(text),
matching: find.byType(RichText),
),
).text.style;
}
expect(getTextStyle('Hello').fontSize, null);
expect(getTextStyle('Hello').color, textColor);
expect(getTextStyle('World').fontSize, null);
expect(getTextStyle('World').color, textColor);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment