zefyr

buttons_test.dart 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // Copyright (c) 2018, the Zefyr project authors. Please see the AUTHORS file
  2. // for details. All rights reserved. Use of this source code is governed by a
  3. // BSD-style license that can be found in the LICENSE file.
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter/services.dart';
  6. import 'package:flutter_test/flutter_test.dart';
  7. import 'package:zefyr/src/widgets/buttons.dart';
  8. import 'package:zefyr/zefyr.dart';
  9. import '../testing.dart';
  10. void main() {
  11. group('$ZefyrButton', () {
  12. testWidgets('toggle style', (tester) async {
  13. final editor = new EditorSandBox(tester: tester);
  14. await editor.tapEditor();
  15. await editor.updateSelection(base: 5, extent: 10);
  16. await editor.tapButtonWithIcon(Icons.format_bold);
  17. LineNode line = editor.document.root.children.first;
  18. expect(line.childCount, 3);
  19. TextNode bold = line.children.elementAt(1);
  20. expect(bold.style.toJson(), NotusAttribute.bold.toJson());
  21. expect(bold.value, 'House');
  22. await editor.tapButtonWithIcon(Icons.format_bold);
  23. line = editor.document.root.children.first;
  24. expect(line.childCount, 1);
  25. });
  26. testWidgets('toggle state for different styles of the same attribute',
  27. (tester) async {
  28. final editor = new EditorSandBox(tester: tester);
  29. await editor.tapEditor();
  30. await editor.tapButtonWithIcon(Icons.format_list_bulleted);
  31. expect(editor.document.root.children.first, isInstanceOf<BlockNode>());
  32. var ul = editor.findButtonWithIcon(Icons.format_list_bulleted);
  33. var ol = editor.findButtonWithIcon(Icons.format_list_numbered);
  34. expect(ul.isToggled, isTrue);
  35. expect(ol.isToggled, isFalse);
  36. });
  37. });
  38. group('$HeadingButton', () {
  39. testWidgets('toggle menu', (tester) async {
  40. final editor = new EditorSandBox(tester: tester);
  41. await editor.tapEditor();
  42. await editor.tapButtonWithIcon(Icons.format_size);
  43. expect(find.text('H1'), findsOneWidget);
  44. var h1 = editor.findButtonWithText('H1');
  45. expect(h1.action, ZefyrToolbarAction.headingLevel1);
  46. var h2 = editor.findButtonWithText('H2');
  47. expect(h2.action, ZefyrToolbarAction.headingLevel2);
  48. var h3 = editor.findButtonWithText('H3');
  49. expect(h3.action, ZefyrToolbarAction.headingLevel3);
  50. });
  51. testWidgets('toggle styles', (tester) async {
  52. final editor = new EditorSandBox(tester: tester);
  53. await editor.tapEditor();
  54. await editor.tapButtonWithIcon(Icons.format_size);
  55. await editor.tapButtonWithText('H3');
  56. LineNode line = editor.document.root.children.first;
  57. expect(line.style.containsSame(NotusAttribute.heading.level3), isTrue);
  58. await editor.tapButtonWithText('H2');
  59. expect(line.style.containsSame(NotusAttribute.heading.level2), isTrue);
  60. });
  61. testWidgets('close overlay', (tester) async {
  62. final editor = new EditorSandBox(tester: tester);
  63. await editor.tapEditor();
  64. await editor.tapButtonWithIcon(Icons.format_size);
  65. expect(find.text('H1'), findsOneWidget);
  66. await editor.tapButtonWithIcon(Icons.close);
  67. expect(find.text('H1'), findsNothing);
  68. });
  69. });
  70. group('$LinkButton', () {
  71. testWidgets('disabled when selection is collapsed', (tester) async {
  72. final editor = new EditorSandBox(tester: tester);
  73. await editor.tapEditor();
  74. await editor.tapButtonWithIcon(Icons.link);
  75. expect(find.byIcon(Icons.link_off), findsNothing);
  76. });
  77. testWidgets('enabled and toggles menu with non-empty selection',
  78. (tester) async {
  79. final editor = new EditorSandBox(tester: tester);
  80. await editor.tapEditor();
  81. await editor.updateSelection(base: 5, extent: 10);
  82. await editor.tapButtonWithIcon(Icons.link);
  83. expect(find.byIcon(Icons.link_off), findsOneWidget);
  84. });
  85. testWidgets('auto cancels edit on selection update', (tester) async {
  86. final editor = new EditorSandBox(tester: tester);
  87. await editor.tapEditor();
  88. await editor.updateSelection(base: 5, extent: 10);
  89. await editor.tapButtonWithIcon(Icons.link);
  90. await tester
  91. .tap(find.widgetWithText(GestureDetector, 'Tap to edit link'));
  92. await tester.pumpAndSettle();
  93. expect(editor.focusNode.hasFocus, isFalse);
  94. await editor.updateSelection(base: 10, extent: 10);
  95. expect(find.byIcon(Icons.link_off), findsNothing);
  96. });
  97. testWidgets('editing link', (tester) async {
  98. final editor = new EditorSandBox(tester: tester);
  99. await editor.tapEditor();
  100. await editor.updateSelection(base: 5, extent: 10);
  101. await editor.tapButtonWithIcon(Icons.link);
  102. await tester
  103. .tap(find.widgetWithText(GestureDetector, 'Tap to edit link'));
  104. await tester.pumpAndSettle();
  105. // TODO: figure out why below finder finds 2 instances of TextField
  106. expect(find.byType(TextField), findsOneWidget);
  107. await tester.enterText(find.widgetWithText(TextField, 'https://').first,
  108. 'https://github.com');
  109. await tester.pumpAndSettle();
  110. expect(
  111. find.widgetWithText(TextField, 'https://github.com'), findsOneWidget);
  112. await editor.tapButtonWithIcon(Icons.check);
  113. expect(find.widgetWithText(ZefyrToolbarScaffold, 'https://github.com'),
  114. findsOneWidget);
  115. LineNode line = editor.document.root.children.first;
  116. expect(line.childCount, 3);
  117. TextNode link = line.children.elementAt(1);
  118. expect(link.value, 'House');
  119. expect(link.style.toJson(),
  120. NotusAttribute.link.fromString('https://github.com').toJson());
  121. // unlink
  122. await editor.updateSelection(base: 7, extent: 7);
  123. await editor.tapButtonWithIcon(Icons.link);
  124. await editor.tapButtonWithIcon(Icons.link_off);
  125. line = editor.document.root.children.first;
  126. expect(line.childCount, 1);
  127. });
  128. });
  129. group('$ImageButton', () {
  130. const MethodChannel channel =
  131. const MethodChannel('plugins.flutter.io/image_picker');
  132. final List<MethodCall> log = <MethodCall>[];
  133. setUp(() {
  134. channel.setMockMethodCallHandler((MethodCall methodCall) async {
  135. log.add(methodCall);
  136. return '/tmp/test.jpg';
  137. });
  138. log.clear();
  139. });
  140. testWidgets('toggle overlay', (tester) async {
  141. final editor = new EditorSandBox(tester: tester);
  142. await editor.tapEditor();
  143. await editor.tapButtonWithIcon(Icons.photo);
  144. expect(find.byIcon(Icons.photo_camera), findsOneWidget);
  145. await editor.tapButtonWithIcon(Icons.close);
  146. expect(find.byIcon(Icons.photo_camera), findsNothing);
  147. });
  148. testWidgets('pick from camera', (tester) async {
  149. final editor = new EditorSandBox(tester: tester);
  150. await editor.tapEditor();
  151. await editor.tapButtonWithIcon(Icons.photo);
  152. await editor.tapButtonWithIcon(Icons.photo_camera);
  153. expect(log, hasLength(1));
  154. expect(
  155. log.single,
  156. isMethodCall(
  157. 'pickImage',
  158. arguments: <String, dynamic>{
  159. 'source': 0,
  160. 'maxWidth': null,
  161. 'maxHeight': null,
  162. },
  163. ),
  164. );
  165. });
  166. testWidgets('pick from gallery', (tester) async {
  167. final editor = new EditorSandBox(tester: tester);
  168. await editor.tapEditor();
  169. await editor.tapButtonWithIcon(Icons.photo);
  170. await editor.tapButtonWithIcon(Icons.photo_library);
  171. expect(log, hasLength(1));
  172. expect(
  173. log.single,
  174. isMethodCall(
  175. 'pickImage',
  176. arguments: <String, dynamic>{
  177. 'source': 1,
  178. 'maxWidth': null,
  179. 'maxHeight': null,
  180. },
  181. ),
  182. );
  183. });
  184. });
  185. }