util.dart 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import 'dart:collection';
  2. import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
  3. import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
  4. import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
  5. import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart';
  6. import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
  7. import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
  8. import 'package:app_flowy/plugins/grid/application/grid_data_controller.dart';
  9. import 'package:app_flowy/plugins/grid/application/row/row_bloc.dart';
  10. import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
  11. import 'package:app_flowy/plugins/grid/application/row/row_data_controller.dart';
  12. import 'package:app_flowy/plugins/grid/grid.dart';
  13. import 'package:app_flowy/workspace/application/app/app_service.dart';
  14. import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
  15. import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
  16. import '../../util.dart';
  17. class GridTestContext {
  18. final ViewPB gridView;
  19. final GridDataController _gridDataController;
  20. GridTestContext(this.gridView, this._gridDataController);
  21. List<RowInfo> get rowInfos {
  22. return _gridDataController.rowInfos;
  23. }
  24. UnmodifiableMapView<String, GridBlockCache> get blocks {
  25. return _gridDataController.blocks;
  26. }
  27. List<GridFieldContext> get fieldContexts => fieldController.fieldContexts;
  28. GridFieldController get fieldController {
  29. return _gridDataController.fieldController;
  30. }
  31. Future<void> createRow() async {
  32. return _gridDataController.createRow();
  33. }
  34. FieldEditorBloc createFieldEditor({
  35. GridFieldContext? fieldContext,
  36. }) {
  37. IFieldTypeOptionLoader loader;
  38. if (fieldContext == null) {
  39. loader = NewFieldTypeOptionLoader(gridId: gridView.id);
  40. } else {
  41. loader =
  42. FieldTypeOptionLoader(gridId: gridView.id, field: fieldContext.field);
  43. }
  44. final editorBloc = FieldEditorBloc(
  45. fieldName: fieldContext?.name ?? '',
  46. isGroupField: fieldContext?.isGroupField ?? false,
  47. loader: loader,
  48. gridId: gridView.id,
  49. );
  50. return editorBloc;
  51. }
  52. Future<IGridCellController> makeCellController(String fieldId) async {
  53. final builder = await makeCellControllerBuilder(fieldId);
  54. return builder.build();
  55. }
  56. Future<GridCellControllerBuilder> makeCellControllerBuilder(
  57. String fieldId,
  58. ) async {
  59. final RowInfo rowInfo = rowInfos.last;
  60. final blockCache = blocks[rowInfo.rowPB.blockId];
  61. final rowCache = blockCache?.rowCache;
  62. final fieldController = _gridDataController.fieldController;
  63. final rowDataController = GridRowDataController(
  64. rowInfo: rowInfo,
  65. fieldController: fieldController,
  66. rowCache: rowCache!,
  67. );
  68. final rowBloc = RowBloc(
  69. rowInfo: rowInfo,
  70. dataController: rowDataController,
  71. )..add(const RowEvent.initial());
  72. await gridResponseFuture();
  73. return GridCellControllerBuilder(
  74. cellId: rowBloc.state.gridCellMap[fieldId]!,
  75. cellCache: rowCache.cellCache,
  76. delegate: rowDataController,
  77. );
  78. }
  79. Future<FieldEditorBloc> createField(FieldType fieldType) async {
  80. final editorBloc = createFieldEditor()
  81. ..add(const FieldEditorEvent.initial());
  82. await gridResponseFuture();
  83. editorBloc.add(FieldEditorEvent.switchToField(fieldType));
  84. await gridResponseFuture();
  85. return Future(() => editorBloc);
  86. }
  87. GridFieldContext singleSelectFieldContext() {
  88. final fieldContext = fieldContexts
  89. .firstWhere((element) => element.fieldType == FieldType.SingleSelect);
  90. return fieldContext;
  91. }
  92. GridFieldCellContext singleSelectFieldCellContext() {
  93. final field = singleSelectFieldContext().field;
  94. return GridFieldCellContext(gridId: gridView.id, field: field);
  95. }
  96. GridFieldContext textFieldContext() {
  97. final fieldContext = fieldContexts
  98. .firstWhere((element) => element.fieldType == FieldType.RichText);
  99. return fieldContext;
  100. }
  101. GridFieldContext checkboxFieldContext() {
  102. final fieldContext = fieldContexts
  103. .firstWhere((element) => element.fieldType == FieldType.Checkbox);
  104. return fieldContext;
  105. }
  106. }
  107. /// Create a empty Grid for test
  108. class AppFlowyGridTest {
  109. final AppFlowyUnitTest unitTest;
  110. AppFlowyGridTest({required this.unitTest});
  111. static Future<AppFlowyGridTest> ensureInitialized() async {
  112. final inner = await AppFlowyUnitTest.ensureInitialized();
  113. return AppFlowyGridTest(unitTest: inner);
  114. }
  115. Future<GridTestContext> createTestGrid() async {
  116. final app = await unitTest.createTestApp();
  117. final builder = GridPluginBuilder();
  118. final context = await AppService()
  119. .createView(
  120. appId: app.id,
  121. name: "Test Grid",
  122. dataFormatType: builder.dataFormatType,
  123. pluginType: builder.pluginType,
  124. layoutType: builder.layoutType!,
  125. )
  126. .then((result) {
  127. return result.fold(
  128. (view) async {
  129. final context = GridTestContext(view, GridDataController(view: view));
  130. final result = await context._gridDataController.openGrid();
  131. result.fold((l) => null, (r) => throw Exception(r));
  132. return context;
  133. },
  134. (error) {
  135. throw Exception();
  136. },
  137. );
  138. });
  139. return context;
  140. }
  141. }
  142. /// Create a new Grid for cell test
  143. class AppFlowyGridCellTest {
  144. late GridTestContext context;
  145. final AppFlowyGridTest gridTest;
  146. AppFlowyGridCellTest({required this.gridTest});
  147. static Future<AppFlowyGridCellTest> ensureInitialized() async {
  148. final gridTest = await AppFlowyGridTest.ensureInitialized();
  149. return AppFlowyGridCellTest(gridTest: gridTest);
  150. }
  151. Future<void> createTestGrid() async {
  152. context = await gridTest.createTestGrid();
  153. }
  154. Future<void> createTestRow() async {
  155. await context.createRow();
  156. }
  157. Future<GridSelectOptionCellController> makeCellController(
  158. FieldType fieldType) async {
  159. assert(fieldType == FieldType.SingleSelect ||
  160. fieldType == FieldType.MultiSelect);
  161. final fieldContexts = context.fieldContexts;
  162. final field =
  163. fieldContexts.firstWhere((element) => element.fieldType == fieldType);
  164. final cellController = await context.makeCellController(field.id)
  165. as GridSelectOptionCellController;
  166. return cellController;
  167. }
  168. }
  169. Future<void> gridResponseFuture({int milliseconds = 500}) {
  170. return Future.delayed(gridResponseDuration(milliseconds: milliseconds));
  171. }
  172. Duration gridResponseDuration({int milliseconds = 200}) {
  173. return Duration(milliseconds: milliseconds);
  174. }