Wrap the label widget of the Chip in a Flexible. (#11523) (#11554)

* Wrap the label widget of the Chip in a Flexible. (#11523)

* This allows the Chip to constrain the size of its content after taking into account the space occupied by the avatar and delete icon (if they are present)

* Adding unit tests to evaluate correct size constraints of the Chip widget's label. (#11523)

* Minor change in formatting.

* Adjust function formatting.
diff --git a/packages/flutter/lib/src/material/chip.dart b/packages/flutter/lib/src/material/chip.dart
index db7aae9..cb98ad2 100644
--- a/packages/flutter/lib/src/material/chip.dart
+++ b/packages/flutter/lib/src/material/chip.dart
@@ -123,9 +123,11 @@
       ));
     }
 
-    children.add(new DefaultTextStyle(
-      style: labelStyle ?? _kLabelStyle,
-      child: label,
+    children.add(new Flexible(
+      child: new DefaultTextStyle(
+        style: labelStyle ?? _kLabelStyle,
+        child: label,
+      ),
     ));
 
     if (deletable) {
diff --git a/packages/flutter/test/material/chip_test.dart b/packages/flutter/test/material/chip_test.dart
index 9e5e1be..c90c0ab 100644
--- a/packages/flutter/test/material/chip_test.dart
+++ b/packages/flutter/test/material/chip_test.dart
@@ -8,6 +8,50 @@
 import 'feedback_tester.dart';
 
 void main() {
+  /// Tests that a [Chip] that has its size constrained by its parent is
+  /// further constraining the size of its child, the label widget.
+  /// Optionally, adding an avatar or delete icon to the chip should not
+  /// cause the chip or label to exceed its constrained size.
+  Future<Null> _testConstrainedLabel(WidgetTester tester, {
+    CircleAvatar avatar, VoidCallback onDeleted,
+  }) async {
+    const double labelWidth = 100.0;
+    const double labelHeight = 50.0;
+    const double chipParentWidth = 75.0;
+    const double chipParentHeight = 25.0;
+    final Key labelKey = new UniqueKey();
+
+    await tester.pumpWidget(
+      new MaterialApp(
+        home: new Material(
+          child: new Center(
+            child: new Container(
+              width: chipParentWidth,
+              height: chipParentHeight,
+              child: new Chip(
+                avatar: avatar,
+                label: new Container(
+                  key: labelKey,
+                  width: labelWidth,
+                  height: labelHeight,
+                ),
+                onDeleted: onDeleted,
+              ),
+            ),
+          ),
+        ),
+      ),
+    );
+
+    final Size labelSize = tester.getSize(find.byKey(labelKey));
+    expect(labelSize.width, lessThan(chipParentWidth));
+    expect(labelSize.height, lessThanOrEqualTo(chipParentHeight));
+
+    final Size chipSize = tester.getSize(find.byType(Chip));
+    expect(chipSize.width, chipParentWidth);
+    expect(chipSize.height, chipParentHeight);
+  }
+
   testWidgets('Chip control test', (WidgetTester tester) async {
     final FeedbackTester feedback = new FeedbackTester();
     final List<String> deletedChipLabels = <String>[];
@@ -62,4 +106,78 @@
 
     feedback.dispose();
   });
+
+  testWidgets(
+      'Chip does not constrain size of label widget if it does not exceed '
+      'the available space', (WidgetTester tester) async {
+    const double labelWidth = 50.0;
+    const double labelHeight = 30.0;
+    final Key labelKey = new UniqueKey();
+
+    await tester.pumpWidget(
+      new Material(
+        child: new Center(
+          child: new Container(
+            width: 500.0,
+            height: 500.0,
+            child: new Column(
+              children: <Widget>[
+                new Chip(
+                  label: new Container(
+                    key: labelKey,
+                    width: labelWidth,
+                    height: labelHeight,
+                  ),
+                ),
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+
+    final Size labelSize = tester.getSize(find.byKey(labelKey));
+    expect(labelSize.width, labelWidth);
+    expect(labelSize.height, labelHeight);
+  });
+
+  testWidgets(
+      'Chip constrains the size of the label widget when it exceeds the '
+      'available space', (WidgetTester tester) async {
+    await _testConstrainedLabel(tester);
+  });
+
+  testWidgets(
+      'Chip constrains the size of the label widget when it exceeds the '
+      'available space and the avatar is present', (WidgetTester tester) async {
+    await _testConstrainedLabel(
+      tester,
+      avatar: const CircleAvatar(
+        child: const Text('A')
+      ),
+    );
+  });
+
+  testWidgets(
+      'Chip constrains the size of the label widget when it exceeds the '
+      'available space and the delete icon is present',
+      (WidgetTester tester) async {
+    await _testConstrainedLabel(
+      tester,
+      onDeleted: () {},
+    );
+  });
+
+  testWidgets(
+      'Chip constrains the size of the label widget when it exceeds the '
+      'available space and both avatar and delete icons are present',
+      (WidgetTester tester) async {
+    await _testConstrainedLabel(
+      tester,
+      avatar: const CircleAvatar(
+        child: const Text('A')
+      ),
+      onDeleted: () {},
+    );
+  });
 }