import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:tatlock_ui/shared/components/data_grid/data_grid_column.dart'; import 'package:tatlock_ui/shared/components/data_grid/data_grid_config.dart'; import 'package:tatlock_ui/shared/components/data_grid/data_grid_state.dart'; import '../../../harness/test_harness.dart'; /// Test data class for DataGrid tests. class TestItem { const TestItem({ required this.id, required this.name, required this.value, this.isActive = true, }); final String id; final String name; final int value; final bool isActive; } void main() { final harness = TestHarness(); setUp(() => harness.setUp()); tearDown(() => harness.tearDown()); group('DataGridColumn', () { test('creates column with required fields', () { final column = DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, ); expect(column.id, 'name'); expect(column.header, 'Name'); expect(column.sortable, isFalse); expect(column.searchable, isFalse); }); test('creates sortable column', () { final column = DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, sortable: true, ); expect(column.sortable, isTrue); }); test('creates searchable column', () { final column = DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, searchable: true, ); expect(column.searchable, isTrue); }); test('valueBuilder extracts correct value', () { final column = DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, ); final item = TestItem(id: '1', name: 'Test Item', value: 42); expect(column.valueBuilder(item), 'Test Item'); }); test('supports fixed width', () { final column = DataGridColumn( id: 'id', header: 'ID', valueBuilder: (item) => item.id, width: const DataGridColumnWidth.fixed(100), ); expect(column.width, isA()); expect((column.width as GridFixedWidth).width, 100); }); test('supports flex width', () { final column = DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, width: const DataGridColumnWidth.flex(2), ); expect(column.width, isA()); expect((column.width as GridFlexWidth).flex, 2); }); test('default width is flex(1)', () { final column = DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, ); expect(column.width, isA()); expect((column.width as GridFlexWidth).flex, 1); }); test('supports custom alignment', () { final column = DataGridColumn( id: 'value', header: 'Value', valueBuilder: (item) => item.value.toString(), alignment: DataGridColumnAlignment.end, ); expect(column.alignment, DataGridColumnAlignment.end); expect(column.textAlign, TextAlign.end); expect(column.crossAxisAlignment, CrossAxisAlignment.end); }); test('effectiveSortField defaults to lowercase header', () { final column = DataGridColumn( id: 'name', header: 'Full Name', valueBuilder: (item) => item.name, ); expect(column.effectiveSortField, 'full name'); }); test('effectiveSortField uses sortField when provided', () { final column = DataGridColumn( id: 'name', header: 'Full Name', valueBuilder: (item) => item.name, sortField: 'name', ); expect(column.effectiveSortField, 'name'); }); }); group('DataGridConfig', () { test('creates config with columns', () { final config = DataGridConfig( columns: [ DataGridColumn( id: 'id', header: 'ID', valueBuilder: (item) => item.id, ), DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, ), ], ); expect(config.columns.length, 2); }); test('enableSearch defaults to false', () { final config = DataGridConfig( columns: [], ); expect(config.enableSearch, isFalse); }); test('enables search when specified', () { final config = DataGridConfig( columns: [ DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, searchable: true, ), ], enableSearch: true, ); expect(config.enableSearch, isTrue); }); test('supports custom search hint', () { final config = DataGridConfig( columns: [], enableSearch: true, searchHint: 'Search items...', ); expect(config.searchHint, 'Search items...'); }); test('supports row selection mode', () { final config = DataGridConfig( columns: [], rowsSelectable: true, ); expect(config.rowsSelectable, isTrue); }); test('visibleColumns filters hidden columns', () { final config = DataGridConfig( columns: [ DataGridColumn( id: 'id', header: 'ID', valueBuilder: (item) => item.id, visible: false, ), DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, ), ], ); expect(config.visibleColumns.length, 1); expect(config.visibleColumns.first.id, 'name'); }); test('searchableColumnIndices returns correct indices', () { final config = DataGridConfig( columns: [ DataGridColumn( id: 'id', header: 'ID', valueBuilder: (item) => item.id, ), DataGridColumn( id: 'name', header: 'Name', valueBuilder: (item) => item.name, searchable: true, ), DataGridColumn( id: 'value', header: 'Value', valueBuilder: (item) => item.value.toString(), searchable: true, ), ], ); expect(config.searchableColumnIndices, [1, 2]); }); }); group('DataGridState', () { test('creates initial state with defaults', () { const state = DataGridState(); expect(state.items, isEmpty); expect(state.isLoading, isFalse); expect(state.selectedIds, isEmpty); expect(state.searchQuery, isEmpty); expect(state.isInitialLoad, isTrue); }); test('creates loading state', () { const state = DataGridState( isLoading: true, ); expect(state.isLoading, isTrue); }); test('stores items', () { final items = [ const TestItem(id: '1', name: 'Item 1', value: 10), const TestItem(id: '2', name: 'Item 2', value: 20), ]; final state = DataGridState( items: items, isLoading: false, ); expect(state.items.length, 2); expect(state.items[0].name, 'Item 1'); }); test('stores selected IDs', () { const state = DataGridState( selectedIds: {'1', '2', '3'}, ); expect(state.selectedIds.length, 3); expect(state.selectedIds.contains('1'), isTrue); }); test('stores search query', () { const state = DataGridState( searchQuery: 'test query', ); expect(state.searchQuery, 'test query'); }); test('stores sort column index', () { const state = DataGridState( sortColumnIndex: 1, sortDescending: true, ); expect(state.sortColumnIndex, 1); expect(state.sortDescending, isTrue); }); test('stores error', () { const state = DataGridState( error: 'Something went wrong', ); expect(state.error, 'Something went wrong'); }); test('stores pagination info', () { const state = DataGridState( currentPage: 2, totalCount: 100, ); expect(state.currentPage, 2); expect(state.totalCount, 100); }); }); group('DataGridColumnWidth', () { test('fixed width creates GridFixedWidth', () { const width = DataGridColumnWidth.fixed(150); expect(width, isA()); expect((width as GridFixedWidth).width, 150); }); test('flex width creates GridFlexWidth', () { const width = DataGridColumnWidth.flex(2); expect(width, isA()); expect((width as GridFlexWidth).flex, 2); }); test('default flex is 1', () { const width = DataGridColumnWidth.flex(); expect((width as GridFlexWidth).flex, 1); }); test('fraction width creates GridFractionWidth', () { const width = DataGridColumnWidth.fraction(0.5); expect(width, isA()); expect((width as GridFractionWidth).fraction, 0.5); }); }); group('DataGridColumnAlignment', () { test('has start alignment', () { expect(DataGridColumnAlignment.start, isNotNull); }); test('has center alignment', () { expect(DataGridColumnAlignment.center, isNotNull); }); test('has end alignment', () { expect(DataGridColumnAlignment.end, isNotNull); }); }); group('DataGridDataMode', () { test('all mode', () { const mode = DataGridDataMode.all(); expect(mode, isA()); }); test('paginated mode with default page size', () { const mode = DataGridDataMode.paginated(); expect(mode, isA()); expect((mode as PaginatedDataMode).pageSize, 25); }); test('paginated mode with custom page size', () { const mode = DataGridDataMode.paginated(pageSize: 50); expect((mode as PaginatedDataMode).pageSize, 50); }); test('infinite mode with defaults', () { const mode = DataGridDataMode.infinite(); expect(mode, isA()); expect((mode as InfiniteDataMode).initialLoad, 50); expect((mode as InfiniteDataMode).loadMoreThreshold, 10); }); test('infinite mode with custom values', () { const mode = DataGridDataMode.infinite( initialLoad: 100, loadMoreThreshold: 20, ); expect((mode as InfiniteDataMode).initialLoad, 100); expect((mode as InfiniteDataMode).loadMoreThreshold, 20); }); }); }