diff --git a/docs/ui-kit.md b/docs/ui-kit.md index b8a17493..6664729c 100644 --- a/docs/ui-kit.md +++ b/docs/ui-kit.md @@ -270,6 +270,7 @@ workbench keys fall back as described in [theme.md](theme.md). | `no_raw_material_dialogs_test.dart` | `AlertDialog` | `QueryaModalDialog`, `QueryaConfirmDialog` | | `no_material_dropdowns_test.dart` | `DropdownButton(FormField)`, `PopupMenuButton`, `showMenu` | `QueryaDropdown`, `QueryaActionMenu` | | `no_raw_progress_indicators_test.dart` | `CircularProgressIndicator` outside `QueryaSpinner` | `QueryaSpinner` | +| `shared_does_not_import_shadcn_test.dart` | a new `package:shadcn_flutter` import in `lib/shared/` (ratchet: the allow-list only shrinks) | Flutter primitives and the kit tokens | When adding a new shared component that replaces a Material one, add a guard test in the same style and mention it here. diff --git a/test/guards/shared_does_not_import_shadcn_test.dart b/test/guards/shared_does_not_import_shadcn_test.dart new file mode 100644 index 00000000..ba5afc60 --- /dev/null +++ b/test/guards/shared_does_not_import_shadcn_test.dart @@ -0,0 +1,68 @@ +import 'dart:io'; + +import 'package:flutter_test/flutter_test.dart'; + +/// Epic #1365: the Querya UI kit (`lib/shared/`) is moving off +/// `package:shadcn_flutter`. This guard is a ratchet: the files below still +/// import it and are allowed to, nothing else may start to, and an entry has +/// to be removed from the list in the same change that removes its import. +/// +/// `widgets.dart` is the barrel that re-exports shadcn for the rest of the app +/// until the migration is done; it goes last. +void main() { + const allowed = { + 'lib/shared/widgets/app_toast.dart', + 'lib/shared/widgets/connection_tree_loading_row.dart', + 'lib/shared/widgets/export_menu_button.dart', + 'lib/shared/widgets/querya_action_button.dart', + 'lib/shared/widgets/querya_action_menu.dart', + 'lib/shared/widgets/querya_badge.dart', + 'lib/shared/widgets/querya_dialog_card.dart', + 'lib/shared/widgets/querya_dropdown.dart', + 'lib/shared/widgets/querya_empty_state.dart', + 'lib/shared/widgets/querya_icon_button.dart', + 'lib/shared/widgets/querya_modal_dialog.dart', + 'lib/shared/widgets/querya_search_field.dart', + 'lib/shared/widgets/querya_spinner.dart', + 'lib/shared/widgets/querya_tab_strip.dart', + 'lib/shared/widgets/widgets.dart', + }; + + final importsShadcn = RegExp('package:shadcn_flutter/'); + + Set filesImportingShadcn() { + final found = {}; + for (final entity in Directory('lib/shared').listSync(recursive: true)) { + if (entity is! File || !entity.path.endsWith('.dart')) continue; + final path = entity.path.replaceAll(r'\', '/'); + if (importsShadcn.hasMatch(entity.readAsStringSync())) { + found.add(path); + } + } + return found; + } + + test('lib/shared does not start importing shadcn_flutter', () { + final offenders = filesImportingShadcn().difference(allowed).toList() + ..sort(); + + expect( + offenders, + isEmpty, + reason: 'These files in lib/shared import shadcn_flutter: $offenders. ' + 'The UI kit is moving off it (#1365): use Flutter primitives and the ' + 'kit tokens instead.', + ); + }); + + test('the allow-list only names files that still import shadcn_flutter', () { + final stale = allowed.difference(filesImportingShadcn()).toList()..sort(); + + expect( + stale, + isEmpty, + reason: 'These files no longer import shadcn_flutter (or are gone): ' + '$stale. Remove them from the allow-list in this test.', + ); + }); +}