mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-08-19 14:20:11 +00:00
test: rewrite bloc tests (#6492)
This commit is contained in:
parent
a763304386
commit
9ee39f45c9
@ -174,7 +174,8 @@ class FieldController {
|
||||
(FilterChangesetNotificationPB changeset) {
|
||||
_filterNotifier?.filters =
|
||||
_filterListFromPBs(changeset.filters.items);
|
||||
_updateFieldInfos();
|
||||
_fieldNotifier.fieldInfos =
|
||||
_updateFieldInfos(_fieldNotifier.fieldInfos);
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
@ -396,7 +397,7 @@ class FieldController {
|
||||
(updatedFields, fieldInfos) =
|
||||
await updateFields(changeset.updatedFields, fieldInfos);
|
||||
|
||||
_fieldNotifier.fieldInfos = fieldInfos;
|
||||
_fieldNotifier.fieldInfos = _updateFieldInfos(fieldInfos);
|
||||
for (final listener in _updatedFieldCallbacks.values) {
|
||||
listener(updatedFields);
|
||||
}
|
||||
@ -465,25 +466,22 @@ class FieldController {
|
||||
_fieldSettings.clear();
|
||||
_fieldSettings.addAll(setting.fieldSettings.items);
|
||||
|
||||
_updateFieldInfos();
|
||||
_fieldNotifier.fieldInfos = _updateFieldInfos(_fieldNotifier.fieldInfos);
|
||||
}
|
||||
|
||||
/// Attach sort, filter, group information and field settings to `FieldInfo`
|
||||
void _updateFieldInfos() {
|
||||
final List<FieldInfo> newFieldInfos = [];
|
||||
for (final field in _fieldNotifier.fieldInfos) {
|
||||
newFieldInfos.add(
|
||||
field.copyWith(
|
||||
fieldSettings: _fieldSettings
|
||||
.firstWhereOrNull((setting) => setting.fieldId == field.id),
|
||||
isGroupField: _groupConfigurationByFieldId[field.id] != null,
|
||||
hasFilter: getFilterByFieldId(field.id) != null,
|
||||
hasSort: getSortByFieldId(field.id) != null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_fieldNotifier.fieldInfos = newFieldInfos;
|
||||
List<FieldInfo> _updateFieldInfos(List<FieldInfo> fieldInfos) {
|
||||
return fieldInfos
|
||||
.map(
|
||||
(field) => field.copyWith(
|
||||
fieldSettings: _fieldSettings
|
||||
.firstWhereOrNull((setting) => setting.fieldId == field.id),
|
||||
isGroupField: _groupConfigurationByFieldId[field.id] != null,
|
||||
hasFilter: getFilterByFieldId(field.id) != null,
|
||||
hasSort: getSortByFieldId(field.id) != null,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// Load all of the fields. This is required when opening the database
|
||||
@ -506,7 +504,8 @@ class FieldController {
|
||||
_loadAllFieldSettings(),
|
||||
_loadSettings(),
|
||||
]);
|
||||
_updateFieldInfos();
|
||||
_fieldNotifier.fieldInfos =
|
||||
_updateFieldInfos(_fieldNotifier.fieldInfos);
|
||||
|
||||
return FlowyResult.success(null);
|
||||
},
|
||||
|
@ -14,11 +14,12 @@ import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart';
|
||||
import 'package:appflowy/util/int64_extension.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
abstract class DatabaseFilter {
|
||||
abstract class DatabaseFilter extends Equatable {
|
||||
const DatabaseFilter({
|
||||
required this.filterId,
|
||||
required this.fieldId,
|
||||
@ -112,16 +113,18 @@ abstract class DatabaseFilter {
|
||||
}
|
||||
|
||||
final class TextFilter extends DatabaseFilter {
|
||||
const TextFilter({
|
||||
TextFilter({
|
||||
required super.filterId,
|
||||
required super.fieldId,
|
||||
required super.fieldType,
|
||||
required this.condition,
|
||||
required this.content,
|
||||
});
|
||||
required String content,
|
||||
}) {
|
||||
this.content = canAttachContent ? content : "";
|
||||
}
|
||||
|
||||
final TextFilterConditionPB condition;
|
||||
final String content;
|
||||
late final String content;
|
||||
|
||||
@override
|
||||
String get conditionName => condition.filterName;
|
||||
@ -182,19 +185,24 @@ final class TextFilter extends DatabaseFilter {
|
||||
content: content ?? this.content,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [filterId, fieldId, condition, content];
|
||||
}
|
||||
|
||||
final class NumberFilter extends DatabaseFilter {
|
||||
const NumberFilter({
|
||||
NumberFilter({
|
||||
required super.filterId,
|
||||
required super.fieldId,
|
||||
required super.fieldType,
|
||||
required this.condition,
|
||||
required this.content,
|
||||
});
|
||||
required String content,
|
||||
}) {
|
||||
this.content = canAttachContent ? content : "";
|
||||
}
|
||||
|
||||
final NumberFilterConditionPB condition;
|
||||
final String content;
|
||||
late final String content;
|
||||
|
||||
@override
|
||||
String get conditionName => condition.filterName;
|
||||
@ -253,6 +261,9 @@ final class NumberFilter extends DatabaseFilter {
|
||||
content: content ?? this.content,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [filterId, fieldId, condition, content];
|
||||
}
|
||||
|
||||
final class CheckboxFilter extends DatabaseFilter {
|
||||
@ -289,6 +300,9 @@ final class CheckboxFilter extends DatabaseFilter {
|
||||
condition: condition ?? this.condition,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [filterId, fieldId, condition];
|
||||
}
|
||||
|
||||
final class ChecklistFilter extends DatabaseFilter {
|
||||
@ -325,19 +339,33 @@ final class ChecklistFilter extends DatabaseFilter {
|
||||
condition: condition ?? this.condition,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [filterId, fieldId, condition];
|
||||
}
|
||||
|
||||
final class SelectOptionFilter extends DatabaseFilter {
|
||||
const SelectOptionFilter({
|
||||
SelectOptionFilter({
|
||||
required super.filterId,
|
||||
required super.fieldId,
|
||||
required super.fieldType,
|
||||
required this.condition,
|
||||
required this.optionIds,
|
||||
});
|
||||
required List<String> optionIds,
|
||||
}) {
|
||||
if (canAttachContent) {
|
||||
if (fieldType == FieldType.SingleSelect &&
|
||||
(condition == SelectOptionFilterConditionPB.OptionIs ||
|
||||
condition == SelectOptionFilterConditionPB.OptionIsNot) &&
|
||||
optionIds.isNotEmpty) {
|
||||
this.optionIds.add(optionIds.first);
|
||||
} else {
|
||||
this.optionIds.addAll(optionIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final SelectOptionFilterConditionPB condition;
|
||||
final List<String> optionIds;
|
||||
final List<String> optionIds = [];
|
||||
|
||||
@override
|
||||
String get conditionName => condition.i18n;
|
||||
@ -428,6 +456,9 @@ final class SelectOptionFilter extends DatabaseFilter {
|
||||
field.fieldType == FieldType.SingleSelect
|
||||
? const SingleSelectOptionFilterDelegateImpl()
|
||||
: const MultiSelectOptionFilterDelegateImpl();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [filterId, fieldId, condition, optionIds];
|
||||
}
|
||||
|
||||
enum DateTimeFilterCondition {
|
||||
@ -491,7 +522,8 @@ enum DateTimeFilterCondition {
|
||||
}
|
||||
|
||||
static List<DateTimeFilterCondition> availableConditionsForFieldType(
|
||||
FieldType fieldType,) {
|
||||
FieldType fieldType,
|
||||
) {
|
||||
final result = [...values];
|
||||
if (fieldType == FieldType.CreatedTime ||
|
||||
fieldType == FieldType.LastEditedTime) {
|
||||
@ -504,20 +536,37 @@ enum DateTimeFilterCondition {
|
||||
}
|
||||
|
||||
final class DateTimeFilter extends DatabaseFilter {
|
||||
const DateTimeFilter({
|
||||
DateTimeFilter({
|
||||
required super.filterId,
|
||||
required super.fieldId,
|
||||
required super.fieldType,
|
||||
required this.condition,
|
||||
this.timestamp,
|
||||
this.start,
|
||||
this.end,
|
||||
});
|
||||
DateTime? timestamp,
|
||||
DateTime? start,
|
||||
DateTime? end,
|
||||
}) {
|
||||
if (canAttachContent) {
|
||||
if (condition == DateFilterConditionPB.DateStartsBetween ||
|
||||
condition == DateFilterConditionPB.DateEndsBetween) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.timestamp = null;
|
||||
} else {
|
||||
this.timestamp = timestamp;
|
||||
this.start = null;
|
||||
this.end = null;
|
||||
}
|
||||
} else {
|
||||
this.timestamp = null;
|
||||
this.start = null;
|
||||
this.end = null;
|
||||
}
|
||||
}
|
||||
|
||||
final DateFilterConditionPB condition;
|
||||
final DateTime? timestamp;
|
||||
final DateTime? start;
|
||||
final DateTime? end;
|
||||
late final DateTime? timestamp;
|
||||
late final DateTime? start;
|
||||
late final DateTime? end;
|
||||
|
||||
@override
|
||||
String get conditionName => condition.toCondition().filterName;
|
||||
@ -654,6 +703,10 @@ final class DateTimeFilter extends DatabaseFilter {
|
||||
timestamp: timestamp,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props =>
|
||||
[filterId, fieldId, condition, timestamp, start, end];
|
||||
}
|
||||
|
||||
final class TimeFilter extends DatabaseFilter {
|
||||
@ -703,4 +756,7 @@ final class TimeFilter extends DatabaseFilter {
|
||||
content: content ?? this.content,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [filterId, fieldId, condition, content];
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/import.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
|
||||
class ImportPayload {
|
||||
@ -17,7 +16,7 @@ class ImportPayload {
|
||||
}
|
||||
|
||||
class ImportBackendService {
|
||||
static Future<FlowyResult<void, FlowyError>> importPages(
|
||||
static Future<FlowyResult<RepeatedViewPB, FlowyError>> importPages(
|
||||
String parentViewId,
|
||||
List<ImportValuePayloadPB> values,
|
||||
) async {
|
||||
|
@ -1,4 +1,6 @@
|
||||
import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy/plugins/database/application/row/row_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -6,20 +8,25 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import '../util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridCellTest cellTest;
|
||||
late AppFlowyGridTest cellTest;
|
||||
|
||||
setUpAll(() async {
|
||||
cellTest = await AppFlowyGridCellTest.ensureInitialized();
|
||||
cellTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
group('SingleSelectOptionBloc', () {
|
||||
test('create options', () async {
|
||||
await cellTest.createTestGrid();
|
||||
await cellTest.createTestRow();
|
||||
final cellController = cellTest.makeSelectOptionCellController(
|
||||
FieldType.SingleSelect,
|
||||
0,
|
||||
);
|
||||
group('select cell bloc:', () {
|
||||
late GridTestContext context;
|
||||
late SelectOptionCellController cellController;
|
||||
|
||||
setUp(() async {
|
||||
context = await cellTest.makeDefaultTestGrid();
|
||||
await RowBackendService.createRow(viewId: context.view.id);
|
||||
final fieldIndex = context.fieldController.fieldInfos
|
||||
.indexWhere((field) => field.fieldType == FieldType.SingleSelect);
|
||||
cellController = context.makeGridCellController(fieldIndex, 0).as();
|
||||
});
|
||||
|
||||
test('create options', () async {
|
||||
final bloc = SelectOptionCellEditorBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
@ -32,13 +39,6 @@ void main() {
|
||||
});
|
||||
|
||||
test('update options', () async {
|
||||
await cellTest.createTestGrid();
|
||||
await cellTest.createTestRow();
|
||||
final cellController = cellTest.makeSelectOptionCellController(
|
||||
FieldType.SingleSelect,
|
||||
0,
|
||||
);
|
||||
|
||||
final bloc = SelectOptionCellEditorBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
@ -57,13 +57,6 @@ void main() {
|
||||
});
|
||||
|
||||
test('delete options', () async {
|
||||
await cellTest.createTestGrid();
|
||||
await cellTest.createTestRow();
|
||||
final cellController = cellTest.makeSelectOptionCellController(
|
||||
FieldType.SingleSelect,
|
||||
0,
|
||||
);
|
||||
|
||||
final bloc = SelectOptionCellEditorBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
@ -108,13 +101,6 @@ void main() {
|
||||
});
|
||||
|
||||
test('select/unselect option', () async {
|
||||
await cellTest.createTestGrid();
|
||||
await cellTest.createTestRow();
|
||||
final cellController = cellTest.makeSelectOptionCellController(
|
||||
FieldType.SingleSelect,
|
||||
0,
|
||||
);
|
||||
|
||||
final bloc = SelectOptionCellEditorBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
@ -135,13 +121,6 @@ void main() {
|
||||
});
|
||||
|
||||
test('select an option or create one', () async {
|
||||
await cellTest.createTestGrid();
|
||||
await cellTest.createTestRow();
|
||||
final cellController = cellTest.makeSelectOptionCellController(
|
||||
FieldType.SingleSelect,
|
||||
0,
|
||||
);
|
||||
|
||||
final bloc = SelectOptionCellEditorBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
@ -163,13 +142,6 @@ void main() {
|
||||
});
|
||||
|
||||
test('select multiple options', () async {
|
||||
await cellTest.createTestGrid();
|
||||
await cellTest.createTestRow();
|
||||
final cellController = cellTest.makeSelectOptionCellController(
|
||||
FieldType.SingleSelect,
|
||||
0,
|
||||
);
|
||||
|
||||
final bloc = SelectOptionCellEditorBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
@ -195,13 +167,6 @@ void main() {
|
||||
});
|
||||
|
||||
test('filter options', () async {
|
||||
await cellTest.createTestGrid();
|
||||
await cellTest.createTestRow();
|
||||
final cellController = cellTest.makeSelectOptionCellController(
|
||||
FieldType.SingleSelect,
|
||||
0,
|
||||
);
|
||||
|
||||
final bloc = SelectOptionCellEditorBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
|
@ -0,0 +1,109 @@
|
||||
import 'package:appflowy/plugins/database/application/cell/bloc/text_cell_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy/plugins/database/application/row/row_service.dart';
|
||||
import 'package:appflowy/plugins/database/domain/field_service.dart';
|
||||
import 'package:appflowy/plugins/database/domain/field_settings_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest cellTest;
|
||||
|
||||
setUpAll(() async {
|
||||
cellTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
group('text cell bloc:', () {
|
||||
late GridTestContext context;
|
||||
late TextCellController cellController;
|
||||
|
||||
setUp(() async {
|
||||
context = await cellTest.makeDefaultTestGrid();
|
||||
await RowBackendService.createRow(viewId: context.view.id);
|
||||
final fieldIndex = context.fieldController.fieldInfos
|
||||
.indexWhere((field) => field.fieldType == FieldType.RichText);
|
||||
cellController = context.makeGridCellController(fieldIndex, 0).as();
|
||||
});
|
||||
|
||||
test('update text', () async {
|
||||
final bloc = TextCellBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(bloc.state.content, "");
|
||||
|
||||
bloc.add(const TextCellEvent.updateText("A"));
|
||||
await gridResponseFuture(milliseconds: 600);
|
||||
|
||||
expect(bloc.state.content, "A");
|
||||
});
|
||||
|
||||
test('non-primary text field emoji and hasDocument', () async {
|
||||
final primaryBloc = TextCellBloc(cellController: cellController);
|
||||
expect(primaryBloc.state.emoji == null, false);
|
||||
expect(primaryBloc.state.hasDocument == null, false);
|
||||
|
||||
await primaryBloc.close();
|
||||
|
||||
await FieldBackendService.createField(
|
||||
viewId: context.view.id,
|
||||
fieldName: "Second",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
final fieldIndex = context.fieldController.fieldInfos.indexWhere(
|
||||
(field) => field.fieldType == FieldType.RichText && !field.isPrimary,
|
||||
);
|
||||
cellController = context.makeGridCellController(fieldIndex, 0).as();
|
||||
final nonPrimaryBloc = TextCellBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(nonPrimaryBloc.state.emoji == null, true);
|
||||
expect(nonPrimaryBloc.state.hasDocument == null, true);
|
||||
});
|
||||
|
||||
test('update wrap cell content', () async {
|
||||
final bloc = TextCellBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(bloc.state.wrap, true);
|
||||
|
||||
await FieldSettingsBackendService(
|
||||
viewId: context.view.id,
|
||||
).updateFieldSettings(
|
||||
fieldId: cellController.fieldId,
|
||||
wrapCellContent: false,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(bloc.state.wrap, false);
|
||||
});
|
||||
|
||||
test('update emoji', () async {
|
||||
final bloc = TextCellBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(bloc.state.emoji!.value, "");
|
||||
|
||||
await RowBackendService(viewId: context.view.id)
|
||||
.updateMeta(rowId: cellController.rowId, iconURL: "dummy");
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(bloc.state.emoji!.value, "dummy");
|
||||
});
|
||||
|
||||
test('update document data', () async {
|
||||
// This is so fake?
|
||||
final bloc = TextCellBloc(cellController: cellController);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(bloc.state.hasDocument!.value, false);
|
||||
|
||||
await RowBackendService(viewId: context.view.id)
|
||||
.updateMeta(rowId: cellController.rowId, isDocumentEmpty: false);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(bloc.state.hasDocument!.value, true);
|
||||
});
|
||||
});
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
import 'package:appflowy/plugins/database/application/field/field_editor_bloc.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../util.dart';
|
||||
|
||||
Future<FieldEditorBloc> createEditorBloc(AppFlowyGridTest gridTest) async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final fieldInfo = context.getSelectOptionField();
|
||||
return FieldEditorBloc(
|
||||
viewId: context.gridView.id,
|
||||
fieldController: context.fieldController,
|
||||
fieldInfo: fieldInfo,
|
||||
isNew: false,
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest gridTest;
|
||||
|
||||
setUpAll(() async {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
test('rename field', () async {
|
||||
final editorBloc = await createEditorBloc(gridTest);
|
||||
editorBloc.add(const FieldEditorEvent.renameField('Hello world'));
|
||||
|
||||
await gridResponseFuture();
|
||||
expect(editorBloc.state.field.name, equals("Hello world"));
|
||||
});
|
||||
|
||||
test('switch to text field', () async {
|
||||
final editorBloc = await createEditorBloc(gridTest);
|
||||
|
||||
editorBloc.add(const FieldEditorEvent.switchFieldType(FieldType.RichText));
|
||||
await gridResponseFuture();
|
||||
|
||||
// The default length of the fields is 3. The length of the fields
|
||||
// should not change after switching to other field type
|
||||
expect(editorBloc.state.field.fieldType, equals(FieldType.RichText));
|
||||
});
|
||||
}
|
@ -11,19 +11,19 @@ void main() {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
group('$FieldCellBloc', () {
|
||||
group('field cell bloc:', () {
|
||||
late GridTestContext context;
|
||||
late double width;
|
||||
|
||||
setUp(() async {
|
||||
context = await gridTest.createTestGrid();
|
||||
context = await gridTest.makeDefaultTestGrid();
|
||||
});
|
||||
|
||||
blocTest(
|
||||
'update field width',
|
||||
build: () => FieldCellBloc(
|
||||
fieldInfo: context.fieldInfos[0],
|
||||
viewId: context.gridView.id,
|
||||
fieldInfo: context.fieldController.fieldInfos[0],
|
||||
viewId: context.view.id,
|
||||
),
|
||||
act: (bloc) {
|
||||
width = bloc.state.width;
|
||||
@ -37,10 +37,10 @@ void main() {
|
||||
);
|
||||
|
||||
blocTest(
|
||||
'field width should not be lesser than 50px',
|
||||
'field width should not be less than 50px',
|
||||
build: () => FieldCellBloc(
|
||||
viewId: context.gridView.id,
|
||||
fieldInfo: context.fieldInfos[0],
|
||||
viewId: context.view.id,
|
||||
fieldInfo: context.fieldController.fieldInfos[0],
|
||||
),
|
||||
act: (bloc) {
|
||||
bloc.add(const FieldCellEvent.onResizeStart());
|
||||
|
@ -0,0 +1,133 @@
|
||||
import 'package:appflowy/plugins/database/application/field/field_editor_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/type_option/type_option_data_parser.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:nanoid/nanoid.dart';
|
||||
|
||||
import '../util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest gridTest;
|
||||
|
||||
setUpAll(() async {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
group('field editor bloc:', () {
|
||||
late GridTestContext context;
|
||||
late FieldEditorBloc editorBloc;
|
||||
|
||||
setUp(() async {
|
||||
context = await gridTest.makeDefaultTestGrid();
|
||||
final fieldInfo = context.fieldController.fieldInfos
|
||||
.firstWhere((field) => field.fieldType == FieldType.SingleSelect);
|
||||
editorBloc = FieldEditorBloc(
|
||||
viewId: context.view.id,
|
||||
fieldController: context.fieldController,
|
||||
fieldInfo: fieldInfo,
|
||||
isNew: false,
|
||||
);
|
||||
});
|
||||
|
||||
test('rename field', () async {
|
||||
expect(editorBloc.state.field.name, equals("Type"));
|
||||
|
||||
editorBloc.add(const FieldEditorEvent.renameField('Hello world'));
|
||||
|
||||
await gridResponseFuture();
|
||||
expect(editorBloc.state.field.name, equals("Hello world"));
|
||||
});
|
||||
|
||||
test('edit icon', () async {
|
||||
expect(editorBloc.state.field.icon, equals(""));
|
||||
|
||||
editorBloc.add(const FieldEditorEvent.updateIcon('emoji/smiley-face'));
|
||||
|
||||
await gridResponseFuture();
|
||||
expect(editorBloc.state.field.icon, equals("emoji/smiley-face"));
|
||||
|
||||
editorBloc.add(const FieldEditorEvent.updateIcon(""));
|
||||
|
||||
await gridResponseFuture();
|
||||
expect(editorBloc.state.field.icon, equals(""));
|
||||
});
|
||||
|
||||
test('switch to text field', () async {
|
||||
expect(editorBloc.state.field.fieldType, equals(FieldType.SingleSelect));
|
||||
|
||||
editorBloc.add(
|
||||
const FieldEditorEvent.switchFieldType(FieldType.RichText),
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(editorBloc.state.field.fieldType, equals(FieldType.RichText));
|
||||
});
|
||||
|
||||
test('update field type option', () async {
|
||||
final selectOption = SelectOptionPB()
|
||||
..id = nanoid(4)
|
||||
..color = SelectOptionColorPB.Lime
|
||||
..name = "New option";
|
||||
final typeOptionData = SingleSelectTypeOptionPB()
|
||||
..options.addAll([selectOption]);
|
||||
|
||||
editorBloc.add(
|
||||
FieldEditorEvent.updateTypeOption(typeOptionData.writeToBuffer()),
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
final actual = SingleSelectTypeOptionDataParser()
|
||||
.fromBuffer(editorBloc.state.field.field.typeOptionData);
|
||||
|
||||
expect(actual, equals(typeOptionData));
|
||||
});
|
||||
|
||||
test('update visibility', () async {
|
||||
expect(
|
||||
editorBloc.state.field.visibility,
|
||||
equals(FieldVisibility.AlwaysShown),
|
||||
);
|
||||
|
||||
editorBloc.add(const FieldEditorEvent.toggleFieldVisibility());
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(
|
||||
editorBloc.state.field.visibility,
|
||||
equals(FieldVisibility.AlwaysHidden),
|
||||
);
|
||||
});
|
||||
|
||||
test('update wrap cell', () async {
|
||||
expect(
|
||||
editorBloc.state.field.wrapCellContent,
|
||||
equals(true),
|
||||
);
|
||||
|
||||
editorBloc.add(const FieldEditorEvent.toggleWrapCellContent());
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(
|
||||
editorBloc.state.field.wrapCellContent,
|
||||
equals(false),
|
||||
);
|
||||
});
|
||||
|
||||
test('insert left and right', () async {
|
||||
expect(
|
||||
context.fieldController.fieldInfos.length,
|
||||
equals(3),
|
||||
);
|
||||
|
||||
editorBloc.add(const FieldEditorEvent.insertLeft());
|
||||
// TODO(RS): Shouldn't need to wait here!?
|
||||
await gridResponseFuture();
|
||||
editorBloc.add(const FieldEditorEvent.insertRight());
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(
|
||||
context.fieldController.fieldInfos.length,
|
||||
equals(5),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
import 'package:appflowy/plugins/database/domain/filter_service.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/grid_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/application/database_controller.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/checkbox_filter.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/text_filter.pb.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest gridTest;
|
||||
setUpAll(() async {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
test('create a text filter)', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final textField = context.getTextField();
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
assert(context.fieldController.filters.length == 1);
|
||||
});
|
||||
|
||||
test('delete a text filter)', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final textField = context.getTextField();
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
final filter = context.fieldController.filters.first;
|
||||
await service.deleteFilter(
|
||||
filterId: filter.filterId,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(context.fieldController.filters.length, 0);
|
||||
});
|
||||
|
||||
test('filter rows with condition: text is empty', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final gridController = DatabaseController(
|
||||
view: context.gridView,
|
||||
);
|
||||
final gridBloc = GridBloc(
|
||||
view: context.gridView,
|
||||
databaseController: gridController,
|
||||
)..add(const GridEvent.initial());
|
||||
await gridResponseFuture();
|
||||
|
||||
final textField = context.getTextField();
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(gridBloc.state.rowInfos.length, 3);
|
||||
});
|
||||
|
||||
test('filter rows with condition: text is empty(After edit the row)',
|
||||
() async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final gridController = DatabaseController(
|
||||
view: context.gridView,
|
||||
);
|
||||
final gridBloc = GridBloc(
|
||||
view: context.gridView,
|
||||
databaseController: gridController,
|
||||
)..add(const GridEvent.initial());
|
||||
await gridResponseFuture();
|
||||
|
||||
final textField = context.getTextField();
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
final controller = context.makeTextCellController(0);
|
||||
await controller.saveCellData("edit text cell content");
|
||||
await gridResponseFuture();
|
||||
assert(gridBloc.state.rowInfos.length == 2);
|
||||
|
||||
await controller.saveCellData("");
|
||||
await gridResponseFuture();
|
||||
assert(gridBloc.state.rowInfos.length == 3);
|
||||
});
|
||||
|
||||
test('filter rows with condition: text is not empty', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final textField = context.getTextField();
|
||||
await gridResponseFuture();
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIsNotEmpty,
|
||||
content: "",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(context.rowInfos.isEmpty);
|
||||
});
|
||||
|
||||
test('filter rows with condition: checkbox uncheck', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final checkboxField = context.getCheckboxField();
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final gridController = DatabaseController(
|
||||
view: context.gridView,
|
||||
);
|
||||
final gridBloc = GridBloc(
|
||||
view: context.gridView,
|
||||
databaseController: gridController,
|
||||
)..add(const GridEvent.initial());
|
||||
|
||||
await gridResponseFuture();
|
||||
await service.insertCheckboxFilter(
|
||||
fieldId: checkboxField.id,
|
||||
condition: CheckboxFilterConditionPB.IsUnChecked,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(gridBloc.state.rowInfos.length == 3);
|
||||
});
|
||||
|
||||
test('filter rows with condition: checkbox check', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final checkboxField = context.getCheckboxField();
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final gridController = DatabaseController(
|
||||
view: context.gridView,
|
||||
);
|
||||
final gridBloc = GridBloc(
|
||||
view: context.gridView,
|
||||
databaseController: gridController,
|
||||
)..add(const GridEvent.initial());
|
||||
|
||||
await gridResponseFuture();
|
||||
await service.insertCheckboxFilter(
|
||||
fieldId: checkboxField.id,
|
||||
condition: CheckboxFilterConditionPB.IsChecked,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(gridBloc.state.rowInfos.isEmpty);
|
||||
});
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
import 'package:appflowy/plugins/database/application/field/field_info.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/filter_entities.dart';
|
||||
import 'package:appflowy/plugins/database/domain/field_service.dart';
|
||||
import 'package:appflowy/plugins/database/domain/filter_service.dart';
|
||||
@ -9,24 +10,35 @@ import '../util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest gridTest;
|
||||
|
||||
setUpAll(() async {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
group('filter editor bloc test:', () {
|
||||
test('create filter', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final filterBloc = FilterEditorBloc(
|
||||
viewId: context.gridView.id,
|
||||
group('filter editor bloc:', () {
|
||||
late GridTestContext context;
|
||||
late FilterEditorBloc filterBloc;
|
||||
|
||||
setUp(() async {
|
||||
context = await gridTest.makeDefaultTestGrid();
|
||||
filterBloc = FilterEditorBloc(
|
||||
viewId: context.view.id,
|
||||
fieldController: context.fieldController,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
});
|
||||
|
||||
FieldInfo getFirstFieldByType(FieldType fieldType) {
|
||||
return context.fieldController.fieldInfos
|
||||
.firstWhere((field) => field.fieldType == fieldType);
|
||||
}
|
||||
|
||||
test('create filter', () async {
|
||||
expect(filterBloc.state.filters.length, equals(0));
|
||||
expect(filterBloc.state.fields.length, equals(3));
|
||||
|
||||
// through domain directly
|
||||
final textField = context.getTextField();
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final textField = getFirstFieldByType(FieldType.RichText);
|
||||
final service = FilterBackendService(viewId: context.view.id);
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
@ -37,7 +49,7 @@ void main() {
|
||||
expect(filterBloc.state.fields.length, equals(3));
|
||||
|
||||
// through bloc event
|
||||
final selectOptionField = context.getSelectOptionField();
|
||||
final selectOptionField = getFirstFieldByType(FieldType.SingleSelect);
|
||||
filterBloc.add(FilterEditorEvent.createFilter(selectOptionField));
|
||||
await gridResponseFuture();
|
||||
expect(filterBloc.state.filters.length, equals(2));
|
||||
@ -53,15 +65,33 @@ void main() {
|
||||
expect(filterBloc.state.fields.length, equals(3));
|
||||
});
|
||||
|
||||
test('delete filter', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final filterBloc = FilterEditorBloc(
|
||||
viewId: context.gridView.id,
|
||||
fieldController: context.fieldController,
|
||||
test('change filtering field', () async {
|
||||
final textField = getFirstFieldByType(FieldType.RichText);
|
||||
final selectField = getFirstFieldByType(FieldType.Checkbox);
|
||||
filterBloc.add(FilterEditorEvent.createFilter(textField));
|
||||
await gridResponseFuture();
|
||||
expect(filterBloc.state.filters.length, equals(1));
|
||||
expect(filterBloc.state.fields.length, equals(3));
|
||||
expect(
|
||||
filterBloc.state.filters.first.fieldType,
|
||||
equals(FieldType.RichText),
|
||||
);
|
||||
|
||||
final filter = filterBloc.state.filters.first;
|
||||
filterBloc.add(
|
||||
FilterEditorEvent.changeFilteringField(filter.filterId, selectField),
|
||||
);
|
||||
await gridResponseFuture();
|
||||
expect(filterBloc.state.filters.length, equals(1));
|
||||
expect(
|
||||
filterBloc.state.filters.first.fieldType,
|
||||
equals(FieldType.Checkbox),
|
||||
);
|
||||
expect(filterBloc.state.fields.length, equals(3));
|
||||
});
|
||||
|
||||
final textField = context.getTextField();
|
||||
test('delete filter', () async {
|
||||
final textField = getFirstFieldByType(FieldType.RichText);
|
||||
filterBloc.add(FilterEditorEvent.createFilter(textField));
|
||||
await gridResponseFuture();
|
||||
expect(filterBloc.state.filters.length, equals(1));
|
||||
@ -75,15 +105,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('update filter', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final filterBloc = FilterEditorBloc(
|
||||
viewId: context.gridView.id,
|
||||
fieldController: context.fieldController,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final textField = context.getTextField();
|
||||
final service = FilterBackendService(viewId: context.view.id);
|
||||
final textField = getFirstFieldByType(FieldType.RichText);
|
||||
|
||||
// Create filter
|
||||
await service.insertTextFilter(
|
||||
@ -96,6 +119,7 @@ void main() {
|
||||
expect(filter.condition, equals(TextFilterConditionPB.TextIsEmpty));
|
||||
|
||||
final textFilter = context.fieldController.filters.first;
|
||||
|
||||
// Update the existing filter
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
@ -109,15 +133,8 @@ void main() {
|
||||
expect(filter.content, equals("ABC"));
|
||||
});
|
||||
|
||||
test('update field', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final filterBloc = FilterEditorBloc(
|
||||
viewId: context.gridView.id,
|
||||
fieldController: context.fieldController,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
final textField = context.getTextField();
|
||||
test('update filtering field\'s name', () async {
|
||||
final textField = getFirstFieldByType(FieldType.RichText);
|
||||
filterBloc.add(FilterEditorEvent.createFilter(textField));
|
||||
await gridResponseFuture();
|
||||
expect(filterBloc.state.filters.length, equals(1));
|
||||
@ -127,7 +144,7 @@ void main() {
|
||||
|
||||
// edit field
|
||||
await FieldBackendService(
|
||||
viewId: context.gridView.id,
|
||||
viewId: context.view.id,
|
||||
fieldId: textField.id,
|
||||
).updateField(name: "New Name");
|
||||
await gridResponseFuture();
|
||||
@ -136,28 +153,40 @@ void main() {
|
||||
});
|
||||
|
||||
test('update field type', () async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final filterBloc = FilterEditorBloc(
|
||||
viewId: context.gridView.id,
|
||||
fieldController: context.fieldController,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
final checkboxField = context.getCheckboxField();
|
||||
final checkboxField = getFirstFieldByType(FieldType.Checkbox);
|
||||
filterBloc.add(FilterEditorEvent.createFilter(checkboxField));
|
||||
await gridResponseFuture();
|
||||
expect(filterBloc.state.filters.length, equals(1));
|
||||
|
||||
// edit field
|
||||
await FieldBackendService(
|
||||
viewId: context.gridView.id,
|
||||
viewId: context.view.id,
|
||||
fieldId: checkboxField.id,
|
||||
).updateType(fieldType: FieldType.DateTime);
|
||||
await gridResponseFuture();
|
||||
expect(filterBloc.state.filters.length, equals(0));
|
||||
|
||||
// filter is removed
|
||||
expect(filterBloc.state.filters.length, equals(0));
|
||||
expect(filterBloc.state.fields.length, equals(3));
|
||||
expect(filterBloc.state.fields[2].fieldType, FieldType.DateTime);
|
||||
});
|
||||
|
||||
test('update filter field', () async {
|
||||
final checkboxField = getFirstFieldByType(FieldType.Checkbox);
|
||||
filterBloc.add(FilterEditorEvent.createFilter(checkboxField));
|
||||
await gridResponseFuture();
|
||||
expect(filterBloc.state.filters.length, equals(1));
|
||||
|
||||
// edit field
|
||||
await FieldBackendService(
|
||||
viewId: context.view.id,
|
||||
fieldId: checkboxField.id,
|
||||
).updateField(name: "HERRO");
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(filterBloc.state.filters.length, equals(1));
|
||||
expect(filterBloc.state.fields.length, equals(3));
|
||||
expect(filterBloc.state.fields[2].name, "HERRO");
|
||||
});
|
||||
});
|
||||
}
|
@ -0,0 +1,623 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:appflowy/plugins/database/application/field/filter_entities.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('parsing filter entities:', () {
|
||||
FilterPB createFilterPB(
|
||||
FieldType fieldType,
|
||||
Uint8List data,
|
||||
) {
|
||||
return FilterPB(
|
||||
id: "FT",
|
||||
filterType: FilterType.Data,
|
||||
data: FilterDataPB(
|
||||
fieldId: "FD",
|
||||
fieldType: fieldType,
|
||||
data: data,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
test('text', () async {
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.RichText,
|
||||
TextFilterPB(
|
||||
condition: TextFilterConditionPB.TextContains,
|
||||
content: "c",
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
TextFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.RichText,
|
||||
condition: TextFilterConditionPB.TextContains,
|
||||
content: "c",
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.RichText,
|
||||
TextFilterPB(
|
||||
condition: TextFilterConditionPB.TextContains,
|
||||
content: "",
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
TextFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.RichText,
|
||||
condition: TextFilterConditionPB.TextContains,
|
||||
content: "",
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.RichText,
|
||||
TextFilterPB(
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "",
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
TextFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.RichText,
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "",
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.RichText,
|
||||
TextFilterPB(
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "",
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
TextFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.RichText,
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "c",
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('number', () async {
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.Number,
|
||||
NumberFilterPB(
|
||||
condition: NumberFilterConditionPB.GreaterThan,
|
||||
content: "",
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
NumberFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.Number,
|
||||
condition: NumberFilterConditionPB.GreaterThan,
|
||||
content: "",
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.Number,
|
||||
NumberFilterPB(
|
||||
condition: NumberFilterConditionPB.GreaterThan,
|
||||
content: "123",
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
NumberFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.Number,
|
||||
condition: NumberFilterConditionPB.GreaterThan,
|
||||
content: "123",
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.Number,
|
||||
NumberFilterPB(
|
||||
condition: NumberFilterConditionPB.NumberIsEmpty,
|
||||
content: "",
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
NumberFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.Number,
|
||||
condition: NumberFilterConditionPB.NumberIsEmpty,
|
||||
content: "",
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.Number,
|
||||
NumberFilterPB(
|
||||
condition: NumberFilterConditionPB.NumberIsEmpty,
|
||||
content: "",
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
NumberFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.Number,
|
||||
condition: NumberFilterConditionPB.NumberIsEmpty,
|
||||
content: "123",
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('checkbox', () async {
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.Checkbox,
|
||||
CheckboxFilterPB(
|
||||
condition: CheckboxFilterConditionPB.IsChecked,
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
const CheckboxFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.Checkbox,
|
||||
condition: CheckboxFilterConditionPB.IsChecked,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('checklist', () async {
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.Checklist,
|
||||
ChecklistFilterPB(
|
||||
condition: ChecklistFilterConditionPB.IsComplete,
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
const ChecklistFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.Checklist,
|
||||
condition: ChecklistFilterConditionPB.IsComplete,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('single select option', () async {
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.SingleSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: [],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.SingleSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: const [],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.SingleSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: ['a'],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.SingleSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: const ['a'],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.SingleSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: ['a', 'b'],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.SingleSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: const ['a', 'b'],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.SingleSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionIs,
|
||||
optionIds: ['a', 'b'],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.SingleSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionIs,
|
||||
optionIds: const ['a'],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.SingleSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionIsEmpty,
|
||||
optionIds: [],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.SingleSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionIsEmpty,
|
||||
optionIds: const [],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.SingleSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionIsEmpty,
|
||||
optionIds: ['a'],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.SingleSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionIsEmpty,
|
||||
optionIds: const [],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('multi select option', () async {
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.MultiSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: [],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.MultiSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: const [],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.MultiSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: ['a'],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.MultiSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: const ['a'],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.MultiSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: ['a', 'b'],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.MultiSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionContains,
|
||||
optionIds: const ['a', 'b'],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.MultiSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionIs,
|
||||
optionIds: ['a', 'b'],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.MultiSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionIs,
|
||||
optionIds: const ['a', 'b'],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.MultiSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionIsEmpty,
|
||||
optionIds: [],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.MultiSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionIsEmpty,
|
||||
optionIds: const [],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.MultiSelect,
|
||||
SelectOptionFilterPB(
|
||||
condition: SelectOptionFilterConditionPB.OptionIsEmpty,
|
||||
optionIds: ['a'],
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
SelectOptionFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.MultiSelect,
|
||||
condition: SelectOptionFilterConditionPB.OptionIsEmpty,
|
||||
optionIds: const [],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('date time', () {
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.DateTime,
|
||||
DateFilterPB(
|
||||
condition: DateFilterConditionPB.DateStartsOn,
|
||||
timestamp: Int64(5),
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
DateTimeFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.DateTime,
|
||||
condition: DateFilterConditionPB.DateStartsOn,
|
||||
timestamp: DateTime.fromMillisecondsSinceEpoch(5 * 1000),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.DateTime,
|
||||
DateFilterPB(
|
||||
condition: DateFilterConditionPB.DateStartsOn,
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
DateTimeFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.DateTime,
|
||||
condition: DateFilterConditionPB.DateStartsOn,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.DateTime,
|
||||
DateFilterPB(
|
||||
condition: DateFilterConditionPB.DateStartsOn,
|
||||
start: Int64(5),
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
DateTimeFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.DateTime,
|
||||
condition: DateFilterConditionPB.DateStartsOn,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.DateTime,
|
||||
DateFilterPB(
|
||||
condition: DateFilterConditionPB.DateEndsBetween,
|
||||
start: Int64(5),
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
DateTimeFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.DateTime,
|
||||
condition: DateFilterConditionPB.DateEndsBetween,
|
||||
start: DateTime.fromMillisecondsSinceEpoch(5 * 1000),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.DateTime,
|
||||
DateFilterPB(
|
||||
condition: DateFilterConditionPB.DateEndIsNotEmpty,
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
DateTimeFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.DateTime,
|
||||
condition: DateFilterConditionPB.DateEndIsNotEmpty,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
DatabaseFilter.fromPB(
|
||||
createFilterPB(
|
||||
FieldType.DateTime,
|
||||
DateFilterPB(
|
||||
condition: DateFilterConditionPB.DateEndIsNotEmpty,
|
||||
start: Int64(5),
|
||||
end: Int64(5),
|
||||
timestamp: Int64(5),
|
||||
).writeToBuffer(),
|
||||
),
|
||||
),
|
||||
equals(
|
||||
DateTimeFilter(
|
||||
filterId: "FT",
|
||||
fieldId: "FD",
|
||||
fieldType: FieldType.DateTime,
|
||||
condition: DateFilterConditionPB.DateEndIsNotEmpty,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// group('write to buffer', () {
|
||||
// test('text', () {});
|
||||
// });
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
import 'package:appflowy/plugins/database/domain/filter_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/checkbox_filter.pbenum.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../util.dart';
|
||||
import 'filter_util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest gridTest;
|
||||
setUpAll(() async {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
test('filter rows by checkbox is check condition)', () async {
|
||||
final context = await createTestFilterGrid(gridTest);
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
|
||||
final controller = context.makeCheckboxCellController(0);
|
||||
await controller.saveCellData("Yes");
|
||||
await gridResponseFuture();
|
||||
|
||||
// create a new filter
|
||||
final checkboxField = context.getCheckboxField();
|
||||
await service.insertCheckboxFilter(
|
||||
fieldId: checkboxField.id,
|
||||
condition: CheckboxFilterConditionPB.IsChecked,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(
|
||||
context.rowInfos.length == 1,
|
||||
"expect 1 but receive ${context.rowInfos.length}",
|
||||
);
|
||||
});
|
||||
|
||||
test('filter rows by checkbox is uncheck condition)', () async {
|
||||
final context = await createTestFilterGrid(gridTest);
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
|
||||
final controller = context.makeCheckboxCellController(0);
|
||||
await controller.saveCellData("Yes");
|
||||
await gridResponseFuture();
|
||||
|
||||
// create a new filter
|
||||
final checkboxField = context.getCheckboxField();
|
||||
await service.insertCheckboxFilter(
|
||||
fieldId: checkboxField.id,
|
||||
condition: CheckboxFilterConditionPB.IsUnChecked,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(
|
||||
context.rowInfos.length == 2,
|
||||
"expect 2 but receive ${context.rowInfos.length}",
|
||||
);
|
||||
});
|
||||
}
|
@ -1,165 +0,0 @@
|
||||
import 'package:appflowy/plugins/database/domain/filter_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/text_filter.pb.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../util.dart';
|
||||
import 'filter_util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest gridTest;
|
||||
setUpAll(() async {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
test('filter rows by text is empty condition)', () async {
|
||||
final context = await createTestFilterGrid(gridTest);
|
||||
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final textField = context.getTextField();
|
||||
// create a new filter
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(
|
||||
context.fieldController.filters.length == 1,
|
||||
"expect 1 but receive ${context.fieldController.filters.length}",
|
||||
);
|
||||
assert(
|
||||
context.rowInfos.length == 1,
|
||||
"expect 1 but receive ${context.rowInfos.length}",
|
||||
);
|
||||
|
||||
// delete the filter
|
||||
final textFilter = context.fieldController.filters.first;
|
||||
await service.deleteFilter(
|
||||
filterId: textFilter.filterId,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(context.rowInfos.length == 3);
|
||||
});
|
||||
|
||||
test('filter rows by text is not empty condition)', () async {
|
||||
final context = await createTestFilterGrid(gridTest);
|
||||
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final textField = context.getTextField();
|
||||
// create a new filter
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIsNotEmpty,
|
||||
content: "",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(
|
||||
context.rowInfos.length == 2,
|
||||
"expect 2 but receive ${context.rowInfos.length}",
|
||||
);
|
||||
|
||||
// delete the filter
|
||||
final textFilter = context.fieldController.filters.first;
|
||||
await service.deleteFilter(
|
||||
filterId: textFilter.filterId,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(context.rowInfos.length == 3);
|
||||
});
|
||||
|
||||
test('filter rows by text is empty or is not empty condition)', () async {
|
||||
final context = await createTestFilterGrid(gridTest);
|
||||
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final textField = context.getTextField();
|
||||
// create a new filter
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIsEmpty,
|
||||
content: "",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(
|
||||
context.fieldController.filters.length == 1,
|
||||
"expect 1 but receive ${context.fieldController.filters.length}",
|
||||
);
|
||||
assert(
|
||||
context.rowInfos.length == 1,
|
||||
"expect 1 but receive ${context.rowInfos.length}",
|
||||
);
|
||||
|
||||
// Update the existing filter
|
||||
final textFilter = context.fieldController.filters.first;
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
filterId: textFilter.filterId,
|
||||
condition: TextFilterConditionPB.TextIsNotEmpty,
|
||||
content: "",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(context.rowInfos.length == 2);
|
||||
|
||||
// delete the filter
|
||||
await service.deleteFilter(
|
||||
filterId: textFilter.filterId,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(context.rowInfos.length == 3);
|
||||
});
|
||||
|
||||
test('filter rows by text is condition)', () async {
|
||||
final context = await createTestFilterGrid(gridTest);
|
||||
|
||||
final service = FilterBackendService(viewId: context.gridView.id);
|
||||
final textField = context.getTextField();
|
||||
// create a new filter
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
condition: TextFilterConditionPB.TextIs,
|
||||
content: "A",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(
|
||||
context.rowInfos.length == 1,
|
||||
"expect 1 but receive ${context.rowInfos.length}",
|
||||
);
|
||||
|
||||
// Update the existing filter's content from 'A' to 'B'
|
||||
final textFilter = context.fieldController.filters.first;
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
filterId: textFilter.filterId,
|
||||
condition: TextFilterConditionPB.TextIs,
|
||||
content: "B",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(context.rowInfos.length == 1);
|
||||
|
||||
// Update the existing filter's content from 'B' to 'b'
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
filterId: textFilter.filterId,
|
||||
condition: TextFilterConditionPB.TextIs,
|
||||
content: "b",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(context.rowInfos.length == 1);
|
||||
|
||||
// Update the existing filter with content 'C'
|
||||
await service.insertTextFilter(
|
||||
fieldId: textField.id,
|
||||
filterId: textFilter.filterId,
|
||||
condition: TextFilterConditionPB.TextIs,
|
||||
content: "C",
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(context.rowInfos.isEmpty);
|
||||
|
||||
// delete the filter
|
||||
await service.deleteFilter(
|
||||
filterId: textFilter.filterId,
|
||||
);
|
||||
await gridResponseFuture();
|
||||
assert(context.rowInfos.length == 3);
|
||||
});
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
import 'package:appflowy/plugins/database/application/database_controller.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart';
|
||||
|
||||
import '../util.dart';
|
||||
|
||||
Future<GridTestContext> createTestFilterGrid(AppFlowyGridTest gridTest) async {
|
||||
final app = await gridTest.unitTest.createWorkspace();
|
||||
final context = await ViewBackendService.createView(
|
||||
parentViewId: app.id,
|
||||
name: "Filter Grid",
|
||||
layoutType: ViewLayoutPB.Grid,
|
||||
openAfterCreate: true,
|
||||
).then((result) {
|
||||
return result.fold(
|
||||
(view) async {
|
||||
final context = GridTestContext(
|
||||
view,
|
||||
DatabaseController(view: view),
|
||||
);
|
||||
final result = await context.gridController.open();
|
||||
|
||||
await editCells(context);
|
||||
result.fold((l) => null, (r) => throw Exception(r));
|
||||
return context;
|
||||
},
|
||||
(error) => throw Exception(),
|
||||
);
|
||||
});
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
Future<void> editCells(GridTestContext context) async {
|
||||
final controller0 = context.makeTextCellController(0);
|
||||
final controller1 = context.makeTextCellController(1);
|
||||
|
||||
await controller0.saveCellData('A');
|
||||
await gridResponseFuture();
|
||||
await controller1.saveCellData('B');
|
||||
await gridResponseFuture();
|
||||
}
|
@ -7,6 +7,7 @@ import 'util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest gridTest;
|
||||
|
||||
setUpAll(() async {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
@ -15,7 +16,7 @@ void main() {
|
||||
late GridTestContext context;
|
||||
|
||||
setUp(() async {
|
||||
context = await gridTest.createTestGrid();
|
||||
context = await gridTest.makeDefaultTestGrid();
|
||||
});
|
||||
|
||||
// The initial number of rows is 3 for each grid
|
||||
@ -23,32 +24,29 @@ void main() {
|
||||
blocTest<GridBloc, GridState>(
|
||||
"create a row",
|
||||
build: () => GridBloc(
|
||||
view: context.gridView,
|
||||
databaseController: DatabaseController(view: context.gridView),
|
||||
view: context.view,
|
||||
databaseController: DatabaseController(view: context.view),
|
||||
)..add(const GridEvent.initial()),
|
||||
act: (bloc) => bloc.add(const GridEvent.createRow()),
|
||||
wait: const Duration(milliseconds: 300),
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
assert(bloc.state.rowInfos.length == 4);
|
||||
expect(bloc.state.rowInfos.length, equals(4));
|
||||
},
|
||||
);
|
||||
|
||||
blocTest<GridBloc, GridState>(
|
||||
"delete the last row",
|
||||
build: () => GridBloc(
|
||||
view: context.gridView,
|
||||
databaseController: DatabaseController(view: context.gridView),
|
||||
view: context.view,
|
||||
databaseController: DatabaseController(view: context.view),
|
||||
)..add(const GridEvent.initial()),
|
||||
act: (bloc) async {
|
||||
await gridResponseFuture();
|
||||
bloc.add(GridEvent.deleteRow(bloc.state.rowInfos.last));
|
||||
},
|
||||
wait: const Duration(milliseconds: 300),
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
assert(
|
||||
bloc.state.rowInfos.length == 2,
|
||||
"Expected 2, but receive ${bloc.state.rowInfos.length}",
|
||||
);
|
||||
expect(bloc.state.rowInfos.length, equals(2));
|
||||
},
|
||||
);
|
||||
|
||||
@ -59,8 +57,8 @@ void main() {
|
||||
blocTest(
|
||||
'reorder rows',
|
||||
build: () => GridBloc(
|
||||
view: context.gridView,
|
||||
databaseController: DatabaseController(view: context.gridView),
|
||||
view: context.view,
|
||||
databaseController: DatabaseController(view: context.view),
|
||||
)..add(const GridEvent.initial()),
|
||||
act: (bloc) async {
|
||||
await gridResponseFuture();
|
||||
@ -71,10 +69,11 @@ void main() {
|
||||
|
||||
bloc.add(const GridEvent.moveRow(0, 2));
|
||||
},
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
expect(secondId, bloc.state.rowInfos[0].rowId);
|
||||
expect(thirdId, bloc.state.rowInfos[1].rowId);
|
||||
expect(firstId, bloc.state.rowInfos[2].rowId);
|
||||
expect(secondId, equals(bloc.state.rowInfos[0].rowId));
|
||||
expect(thirdId, equals(bloc.state.rowInfos[1].rowId));
|
||||
expect(firstId, equals(bloc.state.rowInfos[2].rowId));
|
||||
},
|
||||
);
|
||||
});
|
||||
|
@ -0,0 +1,204 @@
|
||||
import 'package:appflowy/plugins/database/application/field/field_info.dart';
|
||||
import 'package:appflowy/plugins/database/domain/field_service.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/sort/sort_editor_bloc.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../util.dart';
|
||||
|
||||
void main() {
|
||||
late AppFlowyGridTest gridTest;
|
||||
|
||||
setUpAll(() async {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
group('sort editor bloc:', () {
|
||||
late GridTestContext context;
|
||||
late SortEditorBloc sortBloc;
|
||||
|
||||
setUp(() async {
|
||||
context = await gridTest.makeDefaultTestGrid();
|
||||
sortBloc = SortEditorBloc(
|
||||
viewId: context.view.id,
|
||||
fieldController: context.fieldController,
|
||||
);
|
||||
});
|
||||
|
||||
FieldInfo getFirstFieldByType(FieldType fieldType) {
|
||||
return context.fieldController.fieldInfos
|
||||
.firstWhere((field) => field.fieldType == fieldType);
|
||||
}
|
||||
|
||||
test('create sort', () async {
|
||||
expect(sortBloc.state.sorts.length, equals(0));
|
||||
expect(sortBloc.state.creatableFields.length, equals(3));
|
||||
expect(sortBloc.state.allFields.length, equals(3));
|
||||
|
||||
final selectOptionField = getFirstFieldByType(FieldType.SingleSelect);
|
||||
sortBloc.add(SortEditorEvent.createSort(fieldId: selectOptionField.id));
|
||||
await gridResponseFuture();
|
||||
expect(sortBloc.state.sorts.length, 1);
|
||||
expect(sortBloc.state.sorts.first.fieldId, selectOptionField.id);
|
||||
expect(
|
||||
sortBloc.state.sorts.first.condition,
|
||||
SortConditionPB.Ascending,
|
||||
);
|
||||
expect(sortBloc.state.creatableFields.length, equals(2));
|
||||
expect(sortBloc.state.allFields.length, equals(3));
|
||||
});
|
||||
|
||||
test('change sort field', () async {
|
||||
final selectOptionField = getFirstFieldByType(FieldType.SingleSelect);
|
||||
sortBloc.add(SortEditorEvent.createSort(fieldId: selectOptionField.id));
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(
|
||||
sortBloc.state.creatableFields
|
||||
.map((e) => e.id)
|
||||
.contains(selectOptionField.id),
|
||||
false,
|
||||
);
|
||||
|
||||
final checkboxField = getFirstFieldByType(FieldType.Checkbox);
|
||||
sortBloc.add(
|
||||
SortEditorEvent.editSort(
|
||||
sortId: sortBloc.state.sorts.first.sortId,
|
||||
fieldId: checkboxField.id,
|
||||
),
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.creatableFields.length, equals(2));
|
||||
expect(
|
||||
sortBloc.state.creatableFields
|
||||
.map((e) => e.id)
|
||||
.contains(checkboxField.id),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test('update sort direction', () async {
|
||||
final selectOptionField = getFirstFieldByType(FieldType.SingleSelect);
|
||||
sortBloc.add(SortEditorEvent.createSort(fieldId: selectOptionField.id));
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(
|
||||
sortBloc.state.sorts.first.condition,
|
||||
SortConditionPB.Ascending,
|
||||
);
|
||||
|
||||
sortBloc.add(
|
||||
SortEditorEvent.editSort(
|
||||
sortId: sortBloc.state.sorts.first.sortId,
|
||||
condition: SortConditionPB.Descending,
|
||||
),
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(
|
||||
sortBloc.state.sorts.first.condition,
|
||||
SortConditionPB.Descending,
|
||||
);
|
||||
});
|
||||
|
||||
test('reorder sorts', () async {
|
||||
final selectOptionField = getFirstFieldByType(FieldType.SingleSelect);
|
||||
final checkboxField = getFirstFieldByType(FieldType.Checkbox);
|
||||
sortBloc
|
||||
..add(SortEditorEvent.createSort(fieldId: selectOptionField.id))
|
||||
..add(SortEditorEvent.createSort(fieldId: checkboxField.id));
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts[0].fieldId, selectOptionField.id);
|
||||
expect(sortBloc.state.sorts[1].fieldId, checkboxField.id);
|
||||
expect(sortBloc.state.creatableFields.length, equals(1));
|
||||
expect(sortBloc.state.allFields.length, equals(3));
|
||||
|
||||
sortBloc.add(
|
||||
const SortEditorEvent.reorderSort(0, 2),
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts[0].fieldId, checkboxField.id);
|
||||
expect(sortBloc.state.sorts[1].fieldId, selectOptionField.id);
|
||||
expect(sortBloc.state.creatableFields.length, equals(1));
|
||||
expect(sortBloc.state.allFields.length, equals(3));
|
||||
});
|
||||
|
||||
test('delete sort', () async {
|
||||
final selectOptionField = getFirstFieldByType(FieldType.SingleSelect);
|
||||
sortBloc.add(SortEditorEvent.createSort(fieldId: selectOptionField.id));
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts.length, 1);
|
||||
|
||||
sortBloc.add(
|
||||
SortEditorEvent.deleteSort(sortBloc.state.sorts.first.sortId),
|
||||
);
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts.length, 0);
|
||||
expect(sortBloc.state.creatableFields.length, equals(3));
|
||||
expect(sortBloc.state.allFields.length, equals(3));
|
||||
});
|
||||
|
||||
test('delete all sorts', () async {
|
||||
final selectOptionField = getFirstFieldByType(FieldType.SingleSelect);
|
||||
final checkboxField = getFirstFieldByType(FieldType.Checkbox);
|
||||
sortBloc
|
||||
..add(SortEditorEvent.createSort(fieldId: selectOptionField.id))
|
||||
..add(SortEditorEvent.createSort(fieldId: checkboxField.id));
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts.length, 2);
|
||||
|
||||
sortBloc.add(const SortEditorEvent.deleteAllSorts());
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts.length, 0);
|
||||
expect(sortBloc.state.creatableFields.length, equals(3));
|
||||
expect(sortBloc.state.allFields.length, equals(3));
|
||||
});
|
||||
|
||||
test('update sort field', () async {
|
||||
final selectOptionField = getFirstFieldByType(FieldType.SingleSelect);
|
||||
sortBloc.add(SortEditorEvent.createSort(fieldId: selectOptionField.id));
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts.length, equals(1));
|
||||
|
||||
// edit field
|
||||
await FieldBackendService(
|
||||
viewId: context.view.id,
|
||||
fieldId: selectOptionField.id,
|
||||
).updateField(name: "HERRO");
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts.length, equals(1));
|
||||
expect(sortBloc.state.allFields[1].name, "HERRO");
|
||||
|
||||
expect(sortBloc.state.creatableFields.length, equals(2));
|
||||
expect(sortBloc.state.allFields.length, equals(3));
|
||||
});
|
||||
|
||||
test('delete sorting field', () async {
|
||||
final selectOptionField = getFirstFieldByType(FieldType.SingleSelect);
|
||||
sortBloc.add(SortEditorEvent.createSort(fieldId: selectOptionField.id));
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts.length, equals(1));
|
||||
|
||||
// edit field
|
||||
await FieldBackendService(
|
||||
viewId: context.view.id,
|
||||
fieldId: selectOptionField.id,
|
||||
).delete();
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(sortBloc.state.sorts.length, equals(0));
|
||||
expect(sortBloc.state.creatableFields.length, equals(2));
|
||||
expect(sortBloc.state.allFields.length, equals(2));
|
||||
});
|
||||
});
|
||||
}
|
@ -1,91 +1,52 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
|
||||
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_editor_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_info.dart';
|
||||
import 'package:appflowy/plugins/database/domain/field_service.dart';
|
||||
import 'package:appflowy/plugins/database/application/row/row_cache.dart';
|
||||
import 'package:appflowy/plugins/database/application/database_controller.dart';
|
||||
import 'package:appflowy/plugins/database/application/row/row_service.dart';
|
||||
import 'package:appflowy/workspace/application/settings/share/import_service.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../../util.dart';
|
||||
|
||||
class GridTestContext {
|
||||
GridTestContext(this.gridView, this.gridController);
|
||||
const v020GridFileName = "v020.afdb";
|
||||
const v069GridFileName = "v069.afdb";
|
||||
|
||||
final ViewPB gridView;
|
||||
final DatabaseController gridController;
|
||||
class GridTestContext {
|
||||
GridTestContext(this.view, this.databaseController);
|
||||
|
||||
final ViewPB view;
|
||||
final DatabaseController databaseController;
|
||||
|
||||
List<RowInfo> get rowInfos {
|
||||
return gridController.rowCache.rowInfos;
|
||||
return databaseController.rowCache.rowInfos;
|
||||
}
|
||||
|
||||
List<FieldInfo> get fieldInfos => fieldController.fieldInfos;
|
||||
|
||||
FieldController get fieldController {
|
||||
return gridController.fieldController;
|
||||
}
|
||||
FieldController get fieldController => databaseController.fieldController;
|
||||
|
||||
Future<FieldEditorBloc> createField(FieldType fieldType) async {
|
||||
final editorBloc =
|
||||
await createFieldEditor(databaseController: gridController);
|
||||
await createFieldEditor(databaseController: databaseController);
|
||||
await gridResponseFuture();
|
||||
editorBloc.add(FieldEditorEvent.switchFieldType(fieldType));
|
||||
await gridResponseFuture();
|
||||
return Future(() => editorBloc);
|
||||
return editorBloc;
|
||||
}
|
||||
|
||||
FieldInfo getSelectOptionField() {
|
||||
final fieldInfo = fieldInfos
|
||||
.firstWhere((element) => element.fieldType == FieldType.SingleSelect);
|
||||
return fieldInfo;
|
||||
}
|
||||
|
||||
FieldInfo getTextField() {
|
||||
final fieldInfo = fieldInfos
|
||||
.firstWhere((element) => element.fieldType == FieldType.RichText);
|
||||
return fieldInfo;
|
||||
}
|
||||
|
||||
FieldInfo getCheckboxField() {
|
||||
final fieldInfo = fieldInfos
|
||||
.firstWhere((element) => element.fieldType == FieldType.Checkbox);
|
||||
return fieldInfo;
|
||||
}
|
||||
|
||||
SelectOptionCellController makeSelectOptionCellController(
|
||||
FieldType fieldType,
|
||||
int rowIndex,
|
||||
) {
|
||||
assert(
|
||||
fieldType == FieldType.SingleSelect || fieldType == FieldType.MultiSelect,
|
||||
);
|
||||
final field =
|
||||
fieldInfos.firstWhere((fieldInfo) => fieldInfo.fieldType == fieldType);
|
||||
CellController makeGridCellController(int fieldIndex, int rowIndex) {
|
||||
return makeCellController(
|
||||
gridController,
|
||||
CellContext(fieldId: field.id, rowId: rowInfos[rowIndex].rowId),
|
||||
).as();
|
||||
}
|
||||
|
||||
TextCellController makeTextCellController(int rowIndex) {
|
||||
final field = fieldInfos
|
||||
.firstWhere((element) => element.fieldType == FieldType.RichText);
|
||||
return makeCellController(
|
||||
gridController,
|
||||
CellContext(fieldId: field.id, rowId: rowInfos[rowIndex].rowId),
|
||||
).as();
|
||||
}
|
||||
|
||||
CheckboxCellController makeCheckboxCellController(int rowIndex) {
|
||||
final field = fieldInfos
|
||||
.firstWhere((element) => element.fieldType == FieldType.Checkbox);
|
||||
return makeCellController(
|
||||
gridController,
|
||||
CellContext(fieldId: field.id, rowId: rowInfos[rowIndex].rowId),
|
||||
databaseController,
|
||||
CellContext(
|
||||
fieldId: fieldController.fieldInfos[fieldIndex].id,
|
||||
rowId: rowInfos[rowIndex].rowId,
|
||||
),
|
||||
).as();
|
||||
}
|
||||
}
|
||||
@ -121,65 +82,74 @@ class AppFlowyGridTest {
|
||||
return AppFlowyGridTest(unitTest: inner);
|
||||
}
|
||||
|
||||
Future<GridTestContext> createTestGrid() async {
|
||||
final app = await unitTest.createWorkspace();
|
||||
Future<GridTestContext> makeDefaultTestGrid() async {
|
||||
final workspace = await unitTest.createWorkspace();
|
||||
final context = await ViewBackendService.createView(
|
||||
parentViewId: app.id,
|
||||
parentViewId: workspace.id,
|
||||
name: "Test Grid",
|
||||
layoutType: ViewLayoutPB.Grid,
|
||||
openAfterCreate: true,
|
||||
).then((result) {
|
||||
return result.fold(
|
||||
(view) async {
|
||||
final context = GridTestContext(
|
||||
view,
|
||||
DatabaseController(view: view),
|
||||
);
|
||||
final result = await context.gridController.open();
|
||||
result.fold((l) => null, (r) => throw Exception(r));
|
||||
return context;
|
||||
},
|
||||
(error) {
|
||||
throw Exception();
|
||||
},
|
||||
);
|
||||
});
|
||||
).fold(
|
||||
(view) async {
|
||||
final databaseController = DatabaseController(view: view);
|
||||
await databaseController
|
||||
.open()
|
||||
.fold((l) => null, (r) => throw Exception(r));
|
||||
return GridTestContext(
|
||||
view,
|
||||
databaseController,
|
||||
);
|
||||
},
|
||||
(error) => throw Exception(),
|
||||
);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
Future<GridTestContext> makeTestGridFromImportedData(
|
||||
String fileName,
|
||||
) async {
|
||||
final workspace = await unitTest.createWorkspace();
|
||||
|
||||
// Don't use the p.join to build the path that used in loadString. It
|
||||
// is not working on windows.
|
||||
final data = await rootBundle
|
||||
.loadString("assets/test/workspaces/database/$fileName");
|
||||
|
||||
final context = await ImportBackendService.importPages(
|
||||
workspace.id,
|
||||
[
|
||||
ImportValuePayloadPB()
|
||||
..name = fileName
|
||||
..data = utf8.encode(data)
|
||||
..viewLayout = ViewLayoutPB.Grid
|
||||
..importType = ImportTypePB.RawDatabase,
|
||||
],
|
||||
).fold(
|
||||
(views) async {
|
||||
final view = views.items.first;
|
||||
final databaseController = DatabaseController(view: view);
|
||||
await databaseController
|
||||
.open()
|
||||
.fold((l) => null, (r) => throw Exception(r));
|
||||
return GridTestContext(
|
||||
view,
|
||||
databaseController,
|
||||
);
|
||||
},
|
||||
(err) => throw Exception(),
|
||||
);
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new Grid for cell test
|
||||
class AppFlowyGridCellTest {
|
||||
AppFlowyGridCellTest({required this.gridTest});
|
||||
|
||||
late GridTestContext context;
|
||||
final AppFlowyGridTest gridTest;
|
||||
|
||||
static Future<AppFlowyGridCellTest> ensureInitialized() async {
|
||||
final gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
return AppFlowyGridCellTest(gridTest: gridTest);
|
||||
}
|
||||
|
||||
Future<void> createTestGrid() async {
|
||||
context = await gridTest.createTestGrid();
|
||||
}
|
||||
|
||||
Future<void> createTestRow() async {
|
||||
await RowBackendService.createRow(viewId: context.gridView.id);
|
||||
}
|
||||
|
||||
SelectOptionCellController makeSelectOptionCellController(
|
||||
FieldType fieldType,
|
||||
int rowIndex,
|
||||
) =>
|
||||
context.makeSelectOptionCellController(fieldType, rowIndex);
|
||||
Future<void> gridResponseFuture({int milliseconds = 300}) {
|
||||
return Future.delayed(
|
||||
gridResponseDuration(milliseconds: milliseconds),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> gridResponseFuture({int milliseconds = 400}) {
|
||||
return Future.delayed(gridResponseDuration(milliseconds: milliseconds));
|
||||
}
|
||||
|
||||
Duration gridResponseDuration({int milliseconds = 400}) {
|
||||
Duration gridResponseDuration({int milliseconds = 300}) {
|
||||
return Duration(milliseconds: milliseconds);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ class AppFlowyUnitTest {
|
||||
_pathProviderInitialized();
|
||||
|
||||
await FlowyRunner.run(
|
||||
AppFlowyApplicationUniTest(),
|
||||
AppFlowyApplicationUnitTest(),
|
||||
IntegrationMode.unitTest,
|
||||
);
|
||||
|
||||
@ -93,7 +93,7 @@ void _pathProviderInitialized() {
|
||||
});
|
||||
}
|
||||
|
||||
class AppFlowyApplicationUniTest implements EntryPoint {
|
||||
class AppFlowyApplicationUnitTest implements EntryPoint {
|
||||
@override
|
||||
Widget create(LaunchConfiguration config) {
|
||||
return const SizedBox.shrink();
|
||||
|
Loading…
x
Reference in New Issue
Block a user