Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/src/manager/pluto_change_notifier_filter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ abstract class PlutoChangeNotifierFilterResolver {

/// grid_state
stateManager.resetCurrentState.hashCode: 'resetCurrentState',
stateManager.setConfiguration.hashCode: 'setConfiguration',

/// layout_state
stateManager.setShowColumnTitle.hashCode: 'setShowColumnTitle',
Expand All @@ -115,6 +116,7 @@ abstract class PlutoChangeNotifierFilterResolver {
stateManager.setShowLoading.hashCode: 'setShowLoading',
stateManager.notifyChangedShowFrozenColumn.hashCode:
'notifyChangedShowFrozenColumn',
stateManager.setTextDirection.hashCode: 'setTextDirection',

/// pagination_state
stateManager.setPageSize.hashCode: 'setPageSize',
Expand Down
4 changes: 4 additions & 0 deletions lib/src/manager/state/grid_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ abstract class IGridState {
PlutoGridConfiguration configuration, {
bool updateLocale = true,
bool applyColumnFilter = true,
bool notify = true,
});

void setGridMode(PlutoGridMode mode);
Expand Down Expand Up @@ -134,6 +135,7 @@ mixin GridState implements IPlutoGridState {
PlutoGridConfiguration configuration, {
bool updateLocale = true,
bool applyColumnFilter = true,
bool notify = true,
}) {
if (_state._configuration == configuration) return;

Expand All @@ -146,6 +148,8 @@ mixin GridState implements IPlutoGridState {
if (applyColumnFilter) {
_state._configuration!.applyColumnFilter(refColumns.originalList);
}

notifyListeners(notify, setConfiguration.hashCode);
Comment thread
menna3lwan marked this conversation as resolved.
Outdated
}

@override
Expand Down
14 changes: 12 additions & 2 deletions lib/src/manager/state/layout_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ abstract class ILayoutState {

void notifyChangedShowFrozenColumn();

void setTextDirection(TextDirection textDirection);
void setTextDirection(TextDirection textDirection, {bool notify = true});

@visibleForTesting
void setGridGlobalOffset(Offset offset);
Expand Down Expand Up @@ -503,8 +503,18 @@ mixin LayoutState implements IPlutoGridState {
}

@override
void setTextDirection(TextDirection textDirection) {
void setTextDirection(TextDirection textDirection, {bool notify = true}) {
if (_state._textDirection == textDirection) return;

_state._textDirection = textDirection;

// setTextDirection is invoked from PlutoGridLayoutDelegate's constructor,
// which is created while PlutoGrid itself is building (inside
// LayoutBuilder). Notifying synchronously at that point would ask
// dependent widgets to rebuild while the widget tree above them is still
// being built, which Flutter disallows. Defer to the next frame instead,
// matching the pattern already used by setKeepFocus.
notifyListenersOnPostFrame(notify, setTextDirection.hashCode);
Comment thread
menna3lwan marked this conversation as resolved.
Outdated
}

@override
Expand Down
9 changes: 8 additions & 1 deletion test/mock/shared_mocks.mocks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2427,6 +2427,7 @@ class MockPlutoGridStateManager extends _i1.Mock
_i2.PlutoGridConfiguration? configuration, {
bool? updateLocale = true,
bool? applyColumnFilter = true,
bool? notify = true,
}) =>
super.noSuchMethod(
Invocation.method(
Expand All @@ -2435,6 +2436,7 @@ class MockPlutoGridStateManager extends _i1.Mock
{
#updateLocale: updateLocale,
#applyColumnFilter: applyColumnFilter,
#notify: notify,
},
),
returnValueForMissingStub: null,
Expand Down Expand Up @@ -2774,10 +2776,15 @@ class MockPlutoGridStateManager extends _i1.Mock
);

@override
void setTextDirection(_i5.TextDirection? textDirection) => super.noSuchMethod(
void setTextDirection(
_i5.TextDirection? textDirection, {
bool? notify = true,
}) =>
super.noSuchMethod(
Invocation.method(
#setTextDirection,
[textDirection],
{#notify: notify},
),
returnValueForMissingStub: null,
);
Expand Down
119 changes: 119 additions & 0 deletions test/src/manager/state/grid_state_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:pluto_grid/pluto_grid.dart';

import '../../../helper/column_helper.dart';
import '../../../helper/row_helper.dart';
import '../../../mock/mock_methods.dart';
import '../../../mock/shared_mocks.mocks.dart';

void main() {
PlutoGridStateManager createStateManager({
required List<PlutoColumn> columns,
required List<PlutoRow> rows,
FocusNode? gridFocusNode,
PlutoGridScrollController? scroll,
PlutoGridConfiguration configuration = const PlutoGridConfiguration(),
}) {
final stateManager = PlutoGridStateManager(
columns: columns,
rows: rows,
gridFocusNode: gridFocusNode ?? MockFocusNode(),
scroll: scroll ?? MockPlutoGridScrollController(),
configuration: configuration,
);

stateManager.setEventManager(MockPlutoGridEventManager());

return stateManager;
}

group('setConfiguration', () {
testWidgets(
'When the configuration is changed, listeners should be notified.',
(WidgetTester tester) async {
// given
List<PlutoColumn> columns = ColumnHelper.textColumn('body', count: 3);
List<PlutoRow> rows = RowHelper.count(3, columns);

PlutoGridStateManager stateManager = createStateManager(
columns: columns,
rows: rows,
);

final listener = MockMethods();

stateManager.addListener(listener.noParamReturnVoid);

// when
stateManager.setConfiguration(
const PlutoGridConfiguration(
style: PlutoGridStyleConfig(enableGridBorderShadow: true),
),
);

// then
verify(listener.noParamReturnVoid()).called(1);
},
);

testWidgets(
'When the configuration is set to an equal value, '
'listeners should not be notified.',
(WidgetTester tester) async {
// given
List<PlutoColumn> columns = ColumnHelper.textColumn('body', count: 3);
List<PlutoRow> rows = RowHelper.count(3, columns);

const configuration = PlutoGridConfiguration();

PlutoGridStateManager stateManager = createStateManager(
columns: columns,
rows: rows,
configuration: configuration,
);

final listener = MockMethods();

stateManager.addListener(listener.noParamReturnVoid);

// when
stateManager.setConfiguration(configuration);

// then
verifyNever(listener.noParamReturnVoid());
},
);

testWidgets(
'When notify is false, listeners should not be notified '
'even though the configuration changed.',
(WidgetTester tester) async {
// given
List<PlutoColumn> columns = ColumnHelper.textColumn('body', count: 3);
List<PlutoRow> rows = RowHelper.count(3, columns);

PlutoGridStateManager stateManager = createStateManager(
columns: columns,
rows: rows,
);

final listener = MockMethods();

stateManager.addListener(listener.noParamReturnVoid);

// when
stateManager.setConfiguration(
const PlutoGridConfiguration(
style: PlutoGridStyleConfig(enableGridBorderShadow: true),
),
notify: false,
);

// then
verifyNever(listener.noParamReturnVoid());
},
);
});
}
87 changes: 87 additions & 0 deletions test/src/manager/state/layout_state_test.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:pluto_grid/pluto_grid.dart';

import '../../../helper/column_helper.dart';
import '../../../helper/pluto_widget_test_helper.dart';
import '../../../helper/row_helper.dart';
import '../../../mock/mock_methods.dart';
import '../../../mock/shared_mocks.mocks.dart';

void main() {
Expand Down Expand Up @@ -158,4 +160,89 @@ void main() {
},
);
});

group('setTextDirection', () {
late PlutoGridStateManager stateManager;

setUp(() {
List<PlutoColumn> columns = ColumnHelper.textColumn('body', count: 3);
List<PlutoRow> rows = RowHelper.count(3, columns);

stateManager = PlutoGridStateManager(
columns: columns,
rows: rows,
gridFocusNode: MockFocusNode(),
scroll: MockPlutoGridScrollController(),
);

stateManager.setEventManager(MockPlutoGridEventManager());
});

testWidgets(
'When the text direction is changed, '
'listeners should be notified on the next frame.',
(WidgetTester tester) async {
// given
expect(stateManager.isLTR, isTrue);

final listener = MockMethods();

stateManager.addListener(listener.noParamReturnVoid);

// when
stateManager.setTextDirection(TextDirection.rtl);

// notifyListenersOnPostFrame defers the notification, so listeners
// must not have been called synchronously yet.
verifyNever(listener.noParamReturnVoid());

await tester.pump();

// then
expect(stateManager.isRTL, isTrue);
verify(listener.noParamReturnVoid()).called(1);
},
);

testWidgets(
'When the text direction is set to the same value, '
'listeners should not be notified.',
(WidgetTester tester) async {
// given
expect(stateManager.isLTR, isTrue);

final listener = MockMethods();

stateManager.addListener(listener.noParamReturnVoid);

// when
stateManager.setTextDirection(TextDirection.ltr);

await tester.pump();

// then
verifyNever(listener.noParamReturnVoid());
},
);

testWidgets(
'When notify is false, listeners should not be notified '
'even though the text direction changed.',
(WidgetTester tester) async {
// given
final listener = MockMethods();

stateManager.addListener(listener.noParamReturnVoid);

// when
stateManager.setTextDirection(TextDirection.rtl, notify: false);

await tester.pump();

// then
expect(stateManager.isRTL, isTrue);
verifyNever(listener.noParamReturnVoid());
},
);
});
}