From c412ee4dbc941d46b5a97df6e486f9ee71e969dc Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Thu, 3 Oct 2024 00:20:26 +0200 Subject: [PATCH 01/28] feature: removed not needed configs, added unit tests and github actions --- bin/build.dart | 8 +- bin/preview.dart | 8 +- bin/screenshots.dart | 8 +- bin/tasks/base/base_task.dart | 3 - example/assets/preview_config.json | 107 +++++++------- example/lib/catalog/catalog_component.dart | 133 +++++++++++------- .../widgets/body_widget/body_widget.dart | 12 +- .../counter_widget/counter_widget.dart | 12 +- .../widgets/fab_widget/fab_widget.dart | 22 --- example/lib/catalog/widgets/main_screen.dart | 22 +++ .../main_screen_widget/main_screen.dart | 22 --- .../catalog/widgets/screen/fab_widget.dart | 22 +++ .../widgets/widgets_preview_page_dummy.dart | 77 ---------- example/lib/main.dart | 2 +- .../dummy/main_screen.dummy.dart | 0 .../preview/main_screen.preview.dart | 35 ++--- example/lib/widgets/main_screen.dart | 9 +- .../widgets/preview/fab_widget.preview.dart | 34 ----- .../lib/widgets/{ => screen}/body_widget.dart | 3 +- .../catalog}/dummy/body_widget.dummy.dart | 0 .../catalog}/dummy/counter_widget.dummy.dart | 0 .../catalog/dummy/fab_widget.dummy.dart | 19 +++ .../catalog}/preview/body_widget.preview.dart | 33 +++-- .../preview/counter_widget.preview.dart | 32 ++--- .../catalog/preview/fab_widget.preview.dart | 114 +++++++++++++++ .../widgets/{ => screen}/counter_widget.dart | 3 +- .../lib/widgets/{ => screen}/fab_widget.dart | 6 +- lib/src/annotations/preview.dart | 37 ++--- .../bin}/catalog_builder/catalog_builder.dart | 30 ++-- .../bin}/preview_builder/dummy_builder.dart | 6 +- .../bin}/preview_builder/preview_builder.dart | 92 +----------- lib/src/bin/tasks/base/base_task.dart | 3 + {bin => lib/src/bin}/tasks/main_task.dart | 4 +- {bin => lib/src/bin}/tasks/preview_task.dart | 4 +- .../src/bin}/tasks/tasks/catalog_task.dart | 29 ++-- .../src/bin}/tasks/tasks/format_task.dart | 2 +- .../src/bin}/tasks/tasks/preview_task.dart | 25 ++-- .../src/bin}/tasks/tasks/server_task.dart | 2 +- .../utils/communicator/service_worker.dart | 3 +- .../communicator/service_worker_impl.dart | 0 {bin => lib/src/bin}/utils/configuration.dart | 77 ++++++---- {bin => lib/src/bin}/utils/exceptions.dart | 0 lib/src/builders/catalog/component_node.dart | 54 +++++-- lib/src/builders/catalog/tree_element.dart | 8 ++ lib/src/builders/dummy/dummy.dart | 5 - pubspec.yaml | 8 +- test/catalog_test.dart | 18 +++ 47 files changed, 609 insertions(+), 544 deletions(-) delete mode 100644 bin/tasks/base/base_task.dart delete mode 100644 example/lib/catalog/widgets/fab_widget/fab_widget.dart create mode 100644 example/lib/catalog/widgets/main_screen.dart delete mode 100644 example/lib/catalog/widgets/main_screen_widget/main_screen.dart create mode 100644 example/lib/catalog/widgets/screen/fab_widget.dart delete mode 100644 example/lib/catalog/widgets/widgets_preview_page_dummy.dart rename example/lib/widgets/{preview => catalog}/dummy/main_screen.dummy.dart (100%) rename example/lib/widgets/{ => catalog}/preview/main_screen.preview.dart (82%) delete mode 100644 example/lib/widgets/preview/fab_widget.preview.dart rename example/lib/widgets/{ => screen}/body_widget.dart (94%) rename example/lib/widgets/{preview => screen/catalog}/dummy/body_widget.dummy.dart (100%) rename example/lib/widgets/{preview => screen/catalog}/dummy/counter_widget.dummy.dart (100%) create mode 100644 example/lib/widgets/screen/catalog/dummy/fab_widget.dummy.dart rename example/lib/widgets/{ => screen/catalog}/preview/body_widget.preview.dart (85%) rename example/lib/widgets/{ => screen/catalog}/preview/counter_widget.preview.dart (87%) create mode 100644 example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart rename example/lib/widgets/{ => screen}/counter_widget.dart (92%) rename example/lib/widgets/{ => screen}/fab_widget.dart (79%) rename {bin => lib/src/bin}/catalog_builder/catalog_builder.dart (87%) rename {bin => lib/src/bin}/preview_builder/dummy_builder.dart (83%) rename {bin => lib/src/bin}/preview_builder/preview_builder.dart (68%) create mode 100644 lib/src/bin/tasks/base/base_task.dart rename {bin => lib/src/bin}/tasks/main_task.dart (85%) rename {bin => lib/src/bin}/tasks/preview_task.dart (84%) rename {bin => lib/src/bin}/tasks/tasks/catalog_task.dart (86%) rename {bin => lib/src/bin}/tasks/tasks/format_task.dart (86%) rename {bin => lib/src/bin}/tasks/tasks/preview_task.dart (77%) rename {bin => lib/src/bin}/tasks/tasks/server_task.dart (79%) rename {bin => lib/src/bin}/utils/communicator/service_worker.dart (93%) rename {bin => lib/src/bin}/utils/communicator/service_worker_impl.dart (100%) rename {bin => lib/src/bin}/utils/configuration.dart (69%) rename {bin => lib/src/bin}/utils/exceptions.dart (100%) create mode 100644 lib/src/builders/catalog/tree_element.dart diff --git a/bin/build.dart b/bin/build.dart index 6e78b3b..a5a2113 100644 --- a/bin/build.dart +++ b/bin/build.dart @@ -1,10 +1,10 @@ -import 'tasks/main_task.dart'; -import 'utils/configuration.dart'; +import 'package:catalog/src/bin/tasks/main_task.dart'; +import 'package:catalog/src/bin/utils/configuration.dart'; const kDebugMode = true; void main(List arguments) async { - var dependencies = loadDependenciesFile(); + var dependencies = loadDependenciesFile(''); print(introMessage(dependencies['catalog'].toString())); - await MainTask().work(); + await MainTask().work([]); } diff --git a/bin/preview.dart b/bin/preview.dart index 229ea40..f9981e0 100644 --- a/bin/preview.dart +++ b/bin/preview.dart @@ -1,8 +1,8 @@ -import 'tasks/preview_task.dart'; -import 'utils/configuration.dart'; +import 'package:catalog/src/bin/tasks/preview_task.dart'; +import 'package:catalog/src/bin/utils/configuration.dart'; void main(List arguments) async { - var dependencies = loadDependenciesFile(); + var dependencies = loadDependenciesFile(''); print(introMessage(dependencies['catalog'].toString())); - await PreviewTask().work(); + await PreviewTask().work([]); } diff --git a/bin/screenshots.dart b/bin/screenshots.dart index 2528bae..eb2a5df 100644 --- a/bin/screenshots.dart +++ b/bin/screenshots.dart @@ -1,8 +1,8 @@ -import 'tasks/tasks/server_task.dart'; -import 'utils/configuration.dart'; +import 'package:catalog/src/bin/tasks/tasks/server_task.dart'; +import 'package:catalog/src/bin/utils/configuration.dart'; void main(List arguments) async { - var dependencies = loadDependenciesFile(); + var dependencies = loadDependenciesFile(''); print(introMessage(dependencies['catalog'].toString())); - await ServerTask().work(); + await ServerTask().work([]); } diff --git a/bin/tasks/base/base_task.dart b/bin/tasks/base/base_task.dart deleted file mode 100644 index fefd2f0..0000000 --- a/bin/tasks/base/base_task.dart +++ /dev/null @@ -1,3 +0,0 @@ -abstract class BaseTask { - Future work(); -} diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index 06c2657..4b7b408 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -8,23 +8,53 @@ "clazzName": "CatalogComponent", "preview": null }, + "builtComponents": {}, "children": { "widgets": { "id": "widgets", "route": "/widgets", "builtComponent": { - "path": "./lib/catalog/widgets/widgets_preview_page_dummy.dart", + "path": "./example/lib/catalog/widgets/main_screen.dart", "route": "widgets", - "package": "package:example/catalog/widgets/widgets_preview_page_dummy.dart", - "clazzName": "WidgetsPreviewPageDummy", - "preview": null + "package": "package:example/catalog/widgets/main_screen.dart", + "clazzName": "MainScreenPreviewPreviewPageDummy", + "preview": { + "id": "main_screen", + "path": "widgets", + "description": "", + "parameters": [ + "title", + "infoText", + "counter", + "incrementCounter" + ] + } + }, + "builtComponents": { + "/main_screen.dart": { + "path": "./example/lib/catalog/widgets/main_screen.dart", + "route": "widgets", + "package": "package:example/catalog/widgets/main_screen.dart", + "clazzName": "MainScreenPreviewPreviewPageDummy", + "preview": { + "id": "main_screen", + "path": "widgets", + "description": "", + "parameters": [ + "title", + "infoText", + "counter", + "incrementCounter" + ] + } + } }, "children": { "body_widget": { "id": "body_widget", "route": "/body_widget", "builtComponent": { - "path": "./lib/catalog/widgets/body_widget/body_widget.dart", + "path": "./example/lib/catalog/widgets/body_widget/body_widget.dart", "route": "widgets/body_widget", "package": "package:example/catalog/widgets/body_widget/body_widget.dart", "clazzName": "BodyWidgetPreviewPreviewPageDummy", @@ -32,69 +62,40 @@ "id": "BodyWidgetPreview", "path": "widgets/body_widget", "description": "", - "usesDummies": true, - "listParameters": [], - "dummyParameters": [ + "parameters": [ "infoText", "counter" - ], - "parameters": {} + ] } }, + "builtComponents": {}, "children": {} }, - "fab_widget": { - "id": "fab_widget", - "route": "/fab_widget", + "screen": { + "id": "screen", + "route": "/screen", "builtComponent": { - "path": "./lib/catalog/widgets/fab_widget/fab_widget.dart", - "route": "widgets/fab_widget", - "package": "package:example/catalog/widgets/fab_widget/fab_widget.dart", + "path": "./example/lib/catalog/widgets/screen/fab_widget.dart", + "route": "widgets/screen", + "package": "package:example/catalog/widgets/screen/fab_widget.dart", "clazzName": "FabWidgetPreviewPreviewPageDummy", "preview": { - "id": "FabWidgetPreview", - "path": "widgets/fab_widget", + "id": "fab_widget", + "path": "widgets/screen", "description": "Basic fab widget", - "usesDummies": false, - "listParameters": [], - "dummyParameters": [], - "parameters": { - "incrementCounter": "void_function_snackbar" - } - } - }, - "children": {} - }, - "main_screen_widget": { - "id": "main_screen_widget", - "route": "/main_screen_widget", - "builtComponent": { - "path": "./lib/catalog/widgets/main_screen_widget/main_screen.dart", - "route": "widgets/main_screen_widget", - "package": "package:example/catalog/widgets/main_screen_widget/main_screen.dart", - "clazzName": "MainScreenPreviewPreviewPageDummy", - "preview": { - "id": "MainScreenPreview", - "path": "widgets/main_screen_widget", - "description": "", - "usesDummies": true, - "listParameters": [], - "dummyParameters": [ - "title", - "infoText", - "counter", + "parameters": [ "incrementCounter" - ], - "parameters": {} + ] } }, + "builtComponents": {}, "children": {} }, "counter_widget": { "id": "counter_widget", "route": "/counter_widget", "builtComponent": { - "path": "./lib/catalog/widgets/counter_widget/counter_widget.dart", + "path": "./example/lib/catalog/widgets/counter_widget/counter_widget.dart", "route": "widgets/counter_widget", "package": "package:example/catalog/widgets/counter_widget/counter_widget.dart", "clazzName": "CounterWidgetPreviewPreviewPageDummy", @@ -102,14 +103,12 @@ "id": "CounterWidgetPreview", "path": "widgets/counter_widget", "description": "Basic counter widget", - "usesDummies": true, - "listParameters": [], - "dummyParameters": [ + "parameters": [ "counter" - ], - "parameters": {} + ] } }, + "builtComponents": {}, "children": {} } } diff --git a/example/lib/catalog/catalog_component.dart b/example/lib/catalog/catalog_component.dart index a5c0cc3..a35f840 100644 --- a/example/lib/catalog/catalog_component.dart +++ b/example/lib/catalog/catalog_component.dart @@ -2,64 +2,89 @@ import 'package:flutter/material.dart'; import 'package:catalog/catalog.dart'; -import 'package:example/catalog/widgets/widgets_preview_page_dummy.dart'; +import 'package:example/catalog/widgets/main_screen.dart'; import 'package:example/catalog/widgets/body_widget/body_widget.dart'; -import 'package:example/catalog/widgets/fab_widget/fab_widget.dart'; -import 'package:example/catalog/widgets/main_screen_widget/main_screen.dart'; +import 'package:example/catalog/widgets/screen/fab_widget.dart'; import 'package:example/catalog/widgets/counter_widget/counter_widget.dart'; + + +import 'package:example/catalog/widgets/main_screen.dart'; + + + class CatalogComponent extends StatefulWidget { static String routeName = '/catalog'; - static GoRoute route = GoRoute( - path: CatalogComponent.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CatalogComponent(), - ), - routes: [ - GoRoute( - path: WidgetsPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const WidgetsPreviewPageDummy(), - ), - routes: [ - GoRoute( - path: BodyWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const BodyWidgetPreviewPreviewPageDummy(), - ), - routes: const [], + static GoRoute route = GoRoute( + path: CatalogComponent.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CatalogComponent(), + ), + routes: [ + + GoRoute( + path: MainScreenPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const MainScreenPreviewPreviewPageDummy(), + ), + routes: [ + + GoRoute( + path: MainScreenPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const MainScreenPreviewPreviewPageDummy(), ), - GoRoute( - path: FabWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const FabWidgetPreviewPreviewPageDummy(), - ), - routes: const [], - ), - GoRoute( - path: MainScreenPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const MainScreenPreviewPreviewPageDummy(), - ), - routes: const [], - ), - GoRoute( - path: CounterWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CounterWidgetPreviewPreviewPageDummy(), - ), - routes: const [], - ) - ], - ) - ], - ); + ), + + + GoRoute( + path: BodyWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const BodyWidgetPreviewPreviewPageDummy(), + ), + routes: [ + + + + ], + ) + , GoRoute( + path: FabWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const FabWidgetPreviewPreviewPageDummy(), + ), + routes: [ + + + + ], + ) + , GoRoute( + path: CounterWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CounterWidgetPreviewPreviewPageDummy(), + ), + routes: [ + + + + ], + ) + + + ], + ) + + + ], + ) + ; const CatalogComponent({super.key}); @override @@ -67,7 +92,9 @@ class CatalogComponent extends StatefulWidget { } class CatalogComponentState extends State { + TreeController? treeController; + @override Widget build(BuildContext context) { @@ -140,3 +167,5 @@ class CatalogComponentState extends State { } } } + + \ No newline at end of file diff --git a/example/lib/catalog/widgets/body_widget/body_widget.dart b/example/lib/catalog/widgets/body_widget/body_widget.dart index 05e08ce..54eb25b 100644 --- a/example/lib/catalog/widgets/body_widget/body_widget.dart +++ b/example/lib/catalog/widgets/body_widget/body_widget.dart @@ -1,22 +1,22 @@ /// AUTOGENERATED FILE. DO NOT EDIT import 'package:flutter/material.dart'; -import 'package:example/widgets/preview/body_widget.preview.dart'; +import 'package:example/widgets/screen/catalog/preview/body_widget.preview.dart'; class BodyWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'body_widget'; + static String routeName = 'body_widget'; + const BodyWidgetPreviewPreviewPageDummy({super.key}); @override - BodyWidgetPreviewPreviewPageDummyState createState() => - BodyWidgetPreviewPreviewPageDummyState(); + BodyWidgetPreviewPreviewPageDummyState createState() => BodyWidgetPreviewPreviewPageDummyState(); } -class BodyWidgetPreviewPreviewPageDummyState - extends State { +class BodyWidgetPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const BodyWidgetPreview(); } } + \ No newline at end of file diff --git a/example/lib/catalog/widgets/counter_widget/counter_widget.dart b/example/lib/catalog/widgets/counter_widget/counter_widget.dart index 59e6b7a..0d5e240 100644 --- a/example/lib/catalog/widgets/counter_widget/counter_widget.dart +++ b/example/lib/catalog/widgets/counter_widget/counter_widget.dart @@ -1,22 +1,22 @@ /// AUTOGENERATED FILE. DO NOT EDIT import 'package:flutter/material.dart'; -import 'package:example/widgets/preview/counter_widget.preview.dart'; +import 'package:example/widgets/screen/catalog/preview/counter_widget.preview.dart'; class CounterWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'counter_widget'; + static String routeName = 'counter_widget'; + const CounterWidgetPreviewPreviewPageDummy({super.key}); @override - CounterWidgetPreviewPreviewPageDummyState createState() => - CounterWidgetPreviewPreviewPageDummyState(); + CounterWidgetPreviewPreviewPageDummyState createState() => CounterWidgetPreviewPreviewPageDummyState(); } -class CounterWidgetPreviewPreviewPageDummyState - extends State { +class CounterWidgetPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const CounterWidgetPreview(); } } + \ No newline at end of file diff --git a/example/lib/catalog/widgets/fab_widget/fab_widget.dart b/example/lib/catalog/widgets/fab_widget/fab_widget.dart deleted file mode 100644 index 20974b6..0000000 --- a/example/lib/catalog/widgets/fab_widget/fab_widget.dart +++ /dev/null @@ -1,22 +0,0 @@ -/// AUTOGENERATED FILE. DO NOT EDIT - -import 'package:flutter/material.dart'; -import 'package:example/widgets/preview/fab_widget.preview.dart'; - -class FabWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'fab_widget'; - - const FabWidgetPreviewPreviewPageDummy({super.key}); - - @override - FabWidgetPreviewPreviewPageDummyState createState() => - FabWidgetPreviewPreviewPageDummyState(); -} - -class FabWidgetPreviewPreviewPageDummyState - extends State { - @override - Widget build(BuildContext context) { - return const FabWidgetPreview(); - } -} diff --git a/example/lib/catalog/widgets/main_screen.dart b/example/lib/catalog/widgets/main_screen.dart new file mode 100644 index 0000000..8478f34 --- /dev/null +++ b/example/lib/catalog/widgets/main_screen.dart @@ -0,0 +1,22 @@ +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:flutter/material.dart'; +import 'package:example/widgets/catalog/preview/main_screen.preview.dart'; + +class MainScreenPreviewPreviewPageDummy extends StatefulWidget { + + static String routeName = 'main_screen'; + + const MainScreenPreviewPreviewPageDummy({super.key}); + + @override + MainScreenPreviewPreviewPageDummyState createState() => MainScreenPreviewPreviewPageDummyState(); +} + +class MainScreenPreviewPreviewPageDummyState extends State { + @override + Widget build(BuildContext context) { + return const MainScreenPreview(); + } +} + \ No newline at end of file diff --git a/example/lib/catalog/widgets/main_screen_widget/main_screen.dart b/example/lib/catalog/widgets/main_screen_widget/main_screen.dart deleted file mode 100644 index fe3df1d..0000000 --- a/example/lib/catalog/widgets/main_screen_widget/main_screen.dart +++ /dev/null @@ -1,22 +0,0 @@ -/// AUTOGENERATED FILE. DO NOT EDIT - -import 'package:flutter/material.dart'; -import 'package:example/widgets/preview/main_screen.preview.dart'; - -class MainScreenPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'main_screen_widget'; - - const MainScreenPreviewPreviewPageDummy({super.key}); - - @override - MainScreenPreviewPreviewPageDummyState createState() => - MainScreenPreviewPreviewPageDummyState(); -} - -class MainScreenPreviewPreviewPageDummyState - extends State { - @override - Widget build(BuildContext context) { - return const MainScreenPreview(); - } -} diff --git a/example/lib/catalog/widgets/screen/fab_widget.dart b/example/lib/catalog/widgets/screen/fab_widget.dart new file mode 100644 index 0000000..0ec2cc0 --- /dev/null +++ b/example/lib/catalog/widgets/screen/fab_widget.dart @@ -0,0 +1,22 @@ +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:flutter/material.dart'; +import 'package:example/widgets/screen/catalog/preview/fab_widget.preview.dart'; + +class FabWidgetPreviewPreviewPageDummy extends StatefulWidget { + + static String routeName = 'screen'; + + const FabWidgetPreviewPreviewPageDummy({super.key}); + + @override + FabWidgetPreviewPreviewPageDummyState createState() => FabWidgetPreviewPreviewPageDummyState(); +} + +class FabWidgetPreviewPreviewPageDummyState extends State { + @override + Widget build(BuildContext context) { + return const FabWidgetPreview(); + } +} + \ No newline at end of file diff --git a/example/lib/catalog/widgets/widgets_preview_page_dummy.dart b/example/lib/catalog/widgets/widgets_preview_page_dummy.dart deleted file mode 100644 index 0655749..0000000 --- a/example/lib/catalog/widgets/widgets_preview_page_dummy.dart +++ /dev/null @@ -1,77 +0,0 @@ -/// AUTOGENERATED FILE. DO NOT EDIT - -import 'package:catalog/catalog.dart'; -import 'package:flutter/material.dart'; - -class WidgetsPreviewPageDummy extends StatefulWidget { - static String routeName = 'widgets'; - - const WidgetsPreviewPageDummy({super.key}); - - @override - WidgetsPreviewPageDummyState createState() => WidgetsPreviewPageDummyState(); -} - -class WidgetsPreviewPageDummyState extends State { - @override - Widget build(BuildContext context) { - return PreviewScaffold( - child: ListView( - children: [ - ListTile( - title: const Text( - 'body_widget', - style: TextStyle( - color: Colors.black, - fontSize: 16, - letterSpacing: .3, - ), - ), - onTap: () { - context.go('/catalog/widgets/body_widget'); - }, - ), - ListTile( - title: const Text( - 'fab_widget', - style: TextStyle( - color: Colors.black, - fontSize: 16, - letterSpacing: .3, - ), - ), - onTap: () { - context.go('/catalog/widgets/fab_widget'); - }, - ), - ListTile( - title: const Text( - 'main_screen_widget', - style: TextStyle( - color: Colors.black, - fontSize: 16, - letterSpacing: .3, - ), - ), - onTap: () { - context.go('/catalog/widgets/main_screen_widget'); - }, - ), - ListTile( - title: const Text( - 'counter_widget', - style: TextStyle( - color: Colors.black, - fontSize: 16, - letterSpacing: .3, - ), - ), - onTap: () { - context.go('/catalog/widgets/counter_widget'); - }, - ), - ], - ), - ); - } -} diff --git a/example/lib/main.dart b/example/lib/main.dart index c467a08..1d073ee 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -36,7 +36,7 @@ void main() { */ runApp( CatalogRunner( - enabled: false, + enabled: true, application: const MyApp(), route: CatalogComponent.route, supportedLocales: Stringcare().locales, diff --git a/example/lib/widgets/preview/dummy/main_screen.dummy.dart b/example/lib/widgets/catalog/dummy/main_screen.dummy.dart similarity index 100% rename from example/lib/widgets/preview/dummy/main_screen.dummy.dart rename to example/lib/widgets/catalog/dummy/main_screen.dummy.dart diff --git a/example/lib/widgets/preview/main_screen.preview.dart b/example/lib/widgets/catalog/preview/main_screen.preview.dart similarity index 82% rename from example/lib/widgets/preview/main_screen.preview.dart rename to example/lib/widgets/catalog/preview/main_screen.preview.dart index fd3de6d..93cff45 100644 --- a/example/lib/widgets/preview/main_screen.preview.dart +++ b/example/lib/widgets/catalog/preview/main_screen.preview.dart @@ -3,22 +3,18 @@ import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; import 'package:example/widgets/main_screen.dart'; -import 'dummy/main_screen.dummy.dart'; +import '../dummy/main_screen.dummy.dart'; @Preview( - id: 'MainScreenPreview', - path: 'widgets/main_screen_widget', - usesDummies: true, - dummyParameters: [ + parameters: [ 'title', 'infoText', 'counter', 'incrementCounter', - ], -) + ],) class MainScreenPreview extends ParentPreviewWidget { const MainScreenPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -103,21 +99,20 @@ class MainScreenPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < MainScreenDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => MainScreenDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return MainScreen( - title: dummy.parameters['title'], - infoText: dummy.parameters['infoText'], - counter: dummy.parameters['counter'], - incrementCounter: dummy.parameters['incrementCounter'], - ); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => MainScreenDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return MainScreen(title: dummy.parameters['title'],infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],incrementCounter: dummy.parameters['incrementCounter'],); + }, + ), + ], ) ], ); } + + } + \ No newline at end of file diff --git a/example/lib/widgets/main_screen.dart b/example/lib/widgets/main_screen.dart index 14f7f7e..bd4f88e 100644 --- a/example/lib/widgets/main_screen.dart +++ b/example/lib/widgets/main_screen.dart @@ -1,14 +1,11 @@ import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; -import 'body_widget.dart'; -import 'fab_widget.dart'; +import 'screen/body_widget.dart'; +import 'screen/fab_widget.dart'; @Preview( - id: 'MainScreenPreview', - path: 'widgets/main_screen_widget', - usesDummies: true, - dummyParameters: [ + parameters: [ 'title', 'infoText', 'counter', diff --git a/example/lib/widgets/preview/fab_widget.preview.dart b/example/lib/widgets/preview/fab_widget.preview.dart deleted file mode 100644 index 8e342b7..0000000 --- a/example/lib/widgets/preview/fab_widget.preview.dart +++ /dev/null @@ -1,34 +0,0 @@ -/// AUTOGENERATED FILE. DO NOT EDIT - -import 'package:catalog/catalog.dart'; -import 'package:flutter/material.dart'; -import 'package:example/widgets/fab_widget.dart'; - -@Preview( - id: 'FabWidgetPreview', - path: 'widgets/fab_widget', - description: 'Basic fab widget', - parameters: { - 'incrementCounter': 'void_function_snackbar', - }, -) -class FabWidgetPreview extends ParentPreviewWidget { - const FabWidgetPreview({super.key}); - - @override - Widget preview(BuildContext context) => Container( - constraints: const BoxConstraints(maxWidth: 700), - child: FabWidget( - incrementCounter: () { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - duration: Duration(seconds: 2), - content: Text( - 'incrementCounter event', - ), - ), - ); - }, - ), - ); -} diff --git a/example/lib/widgets/body_widget.dart b/example/lib/widgets/screen/body_widget.dart similarity index 94% rename from example/lib/widgets/body_widget.dart rename to example/lib/widgets/screen/body_widget.dart index 83ee5f4..4236a59 100644 --- a/example/lib/widgets/body_widget.dart +++ b/example/lib/widgets/screen/body_widget.dart @@ -6,8 +6,7 @@ import 'counter_widget.dart'; @Preview( id: 'BodyWidgetPreview', path: 'widgets/body_widget', - usesDummies: true, - dummyParameters: [ + parameters: [ 'infoText', 'counter', ], diff --git a/example/lib/widgets/preview/dummy/body_widget.dummy.dart b/example/lib/widgets/screen/catalog/dummy/body_widget.dummy.dart similarity index 100% rename from example/lib/widgets/preview/dummy/body_widget.dummy.dart rename to example/lib/widgets/screen/catalog/dummy/body_widget.dummy.dart diff --git a/example/lib/widgets/preview/dummy/counter_widget.dummy.dart b/example/lib/widgets/screen/catalog/dummy/counter_widget.dummy.dart similarity index 100% rename from example/lib/widgets/preview/dummy/counter_widget.dummy.dart rename to example/lib/widgets/screen/catalog/dummy/counter_widget.dummy.dart diff --git a/example/lib/widgets/screen/catalog/dummy/fab_widget.dummy.dart b/example/lib/widgets/screen/catalog/dummy/fab_widget.dummy.dart new file mode 100644 index 0000000..d845f27 --- /dev/null +++ b/example/lib/widgets/screen/catalog/dummy/fab_widget.dummy.dart @@ -0,0 +1,19 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file for modify the preview of FabWidgetPreview +/// + +import 'package:catalog/catalog.dart'; + +class FabWidgetDummy extends PreviewDummy { + @override + List get dummies => [ + Dummy( + parameters: { + 'incrementCounter': () { + // TODO show snackbar + }, + }, + ), + ]; +} diff --git a/example/lib/widgets/preview/body_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart similarity index 85% rename from example/lib/widgets/preview/body_widget.preview.dart rename to example/lib/widgets/screen/catalog/preview/body_widget.preview.dart index 288f102..a95d74b 100644 --- a/example/lib/widgets/preview/body_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart @@ -2,21 +2,19 @@ import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; -import 'package:example/widgets/body_widget.dart'; -import 'dummy/body_widget.dummy.dart'; +import 'package:example/widgets/screen/body_widget.dart'; +import '../dummy/body_widget.dummy.dart'; @Preview( id: 'BodyWidgetPreview', path: 'widgets/body_widget', - usesDummies: true, - dummyParameters: [ + parameters: [ 'infoText', 'counter', - ], -) + ],) class BodyWidgetPreview extends ParentPreviewWidget { const BodyWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -101,19 +99,20 @@ class BodyWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < BodyWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => BodyWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return BodyWidget( - infoText: dummy.parameters['infoText'], - counter: dummy.parameters['counter'], - ); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => BodyWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return BodyWidget(infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],); + }, + ), + ], ) ], ); } + + } + \ No newline at end of file diff --git a/example/lib/widgets/preview/counter_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart similarity index 87% rename from example/lib/widgets/preview/counter_widget.preview.dart rename to example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart index 6848bf1..cedd38f 100644 --- a/example/lib/widgets/preview/counter_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart @@ -2,21 +2,19 @@ import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; -import 'package:example/widgets/counter_widget.dart'; -import 'dummy/counter_widget.dummy.dart'; +import 'package:example/widgets/screen/counter_widget.dart'; +import '../dummy/counter_widget.dummy.dart'; @Preview( id: 'CounterWidgetPreview', path: 'widgets/counter_widget', description: 'Basic counter widget', - usesDummies: true, - dummyParameters: [ + parameters: [ 'counter', - ], -) + ],) class CounterWidgetPreview extends ParentPreviewWidget { const CounterWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -101,18 +99,20 @@ class CounterWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < CounterWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => CounterWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return CounterWidget( - counter: dummy.parameters['counter'], - ); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => CounterWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return CounterWidget(counter: dummy.parameters['counter'],); + }, + ), + ], ) ], ); } + + } + \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart new file mode 100644 index 0000000..02b2700 --- /dev/null +++ b/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart @@ -0,0 +1,114 @@ +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:catalog/catalog.dart'; +import 'package:flutter/material.dart'; +import 'package:example/widgets/screen/fab_widget.dart'; +import '../dummy/fab_widget.dummy.dart'; + +@Preview( + description: 'Basic fab widget', + parameters: ['incrementCounter'],) +class FabWidgetPreview extends ParentPreviewWidget { + const FabWidgetPreview({super.key}); + + @override + Widget preview(BuildContext context) { + Catalog().widgetBasicPreviewMap.clear(); + Catalog().widgetDevicePreviewMap.clear(); + + if (FabWidgetDummy().dummies.isEmpty) { + return Container(); + } + + final deviceScreenshotsAvailable = + FabWidgetDummy().deviceScreenshotsAvailable; + final screenshotsAvailable = FabWidgetDummy().screenshotsAvailable; + + int basicScreenshots = screenshotsAvailable - deviceScreenshotsAvailable; + + return ListView( + children: [ + Column( + children: [ + if (basicScreenshots > 0) + Center( + child: Container( + constraints: const BoxConstraints( + maxWidth: 400, + ), + child: Card( + clipBehavior: Clip.hardEdge, + child: Container( + padding: const EdgeInsets.all(15), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Center( + child: Text( + '$basicScreenshots basic screenshots available', + ), + ), + ), + const IconButton( + onPressed: processBasicScreenshots, + icon: Icon( + Icons.screenshot, + ), + ) + ], + ), + ), + ), + ), + ), + if (deviceScreenshotsAvailable > 0) + Center( + child: Container( + constraints: const BoxConstraints( + maxWidth: 400, + ), + child: Card( + clipBehavior: Clip.hardEdge, + child: Container( + padding: const EdgeInsets.all(15), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Center( + child: Text( + '$deviceScreenshotsAvailable device screenshots available', + ), + ), + ), + const IconButton( + onPressed: processDeviceScreenshots, + icon: Icon( + Icons.screenshot, + ), + ) + ], + ), + ), + ), + ), + ), + for (int i = 0; i < FabWidgetDummy().dummies.length; i++) + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => FabWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return FabWidget(incrementCounter: dummy.parameters['incrementCounter'],); + }, + ), + + ], + ) + ], + ); + } + + +} + \ No newline at end of file diff --git a/example/lib/widgets/counter_widget.dart b/example/lib/widgets/screen/counter_widget.dart similarity index 92% rename from example/lib/widgets/counter_widget.dart rename to example/lib/widgets/screen/counter_widget.dart index 2f02523..635e869 100644 --- a/example/lib/widgets/counter_widget.dart +++ b/example/lib/widgets/screen/counter_widget.dart @@ -5,8 +5,7 @@ import 'package:flutter/material.dart'; id: 'CounterWidgetPreview', path: 'widgets/counter_widget', description: 'Basic counter widget', - usesDummies: true, - dummyParameters: [ + parameters: [ 'counter', ], ) diff --git a/example/lib/widgets/fab_widget.dart b/example/lib/widgets/screen/fab_widget.dart similarity index 79% rename from example/lib/widgets/fab_widget.dart rename to example/lib/widgets/screen/fab_widget.dart index 67b6f0a..0d05523 100644 --- a/example/lib/widgets/fab_widget.dart +++ b/example/lib/widgets/screen/fab_widget.dart @@ -2,12 +2,8 @@ import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; @Preview( - id: 'FabWidgetPreview', - path: 'widgets/fab_widget', description: 'Basic fab widget', - parameters: { - 'incrementCounter': 'void_function_snackbar', - }, + parameters: ['incrementCounter'], ) class FabWidget extends StatelessWidget { final Function() incrementCounter; diff --git a/lib/src/annotations/preview.dart b/lib/src/annotations/preview.dart index 89bd98e..3f2c657 100644 --- a/lib/src/annotations/preview.dart +++ b/lib/src/annotations/preview.dart @@ -6,19 +6,13 @@ class Preview implements Serial { final String id; final String path; final String description; - final bool usesDummies; - final List dummyParameters; - final List listParameters; - final Map parameters; + final List parameters; const Preview({ - required this.id, - required this.path, + this.id = '', + this.path = '', this.description = '', - this.usesDummies = false, - this.parameters = const {}, - this.listParameters = const [], - this.dummyParameters = const [], + this.parameters = const [], }); @override @@ -26,12 +20,9 @@ class Preview implements Serial { id: json['id'] ?? '', path: json['path'] ?? '', description: json['description'] ?? '', - usesDummies: json['usesDummies'] ?? false, - dummyParameters: Serial.listObjectFromBasicType( - json['dummyParameters'] ?? [], + parameters: Serial.listObjectFromBasicType( + json['parameters'] ?? [], ), - listParameters: json['listParameters'] ?? [], - parameters: json['parameters'] ?? {}, ); @override @@ -45,9 +36,6 @@ class Preview implements Serial { 'id': id, 'path': path, 'description': description, - 'usesDummies': usesDummies, - 'listParameters': listParameters, - 'dummyParameters': dummyParameters, 'parameters': parameters, }; @@ -62,4 +50,17 @@ class Preview implements Serial { var map = toJson(); return jsonEncode(map); } + + Preview copyWith({ + String? id, + String? path, + String? description, + List? parameters, + }) => + Preview( + id: id ?? this.id, + path: path ?? this.path, + description: description ?? this.description, + parameters: parameters ?? this.parameters, + ); } diff --git a/bin/catalog_builder/catalog_builder.dart b/lib/src/bin/catalog_builder/catalog_builder.dart similarity index 87% rename from bin/catalog_builder/catalog_builder.dart rename to lib/src/bin/catalog_builder/catalog_builder.dart index db7484c..bb7ce20 100644 --- a/bin/catalog_builder/catalog_builder.dart +++ b/lib/src/bin/catalog_builder/catalog_builder.dart @@ -29,9 +29,8 @@ Future createPage( try { var directory = Directory(outputPath); await directory.create(recursive: true); - var id = preview.path.contains('/') - ? preview.path.split('/').last - : preview.path; + var id = + preview.path.contains('/') ? preview.path.split('/').last : preview.id; File file = File(outputPath + outputFile.replaceAll('.$prefix.', '.')); final clazzName = name.replaceAll('()', ''); @@ -68,6 +67,8 @@ class ${pageClass}State extends State<$pageClass> { var p = file.path.split(base)[1]; var package = 'package:$appId$p'; + print('route added: ${preview.path}'); + return BuiltComponent( path: file.path, route: preview.path, @@ -97,7 +98,8 @@ Future buildMiddlePages( await directory.create(recursive: true); File file = File('$outputPath/$outputFile'); - final clazz = name.replaceAll('()', '').split('_').map((e) => e.capitalize()).join(); + final clazz = + name.replaceAll('()', '').split('_').map((e) => e.capitalize()).join(); final clazzName = '${clazz}PreviewPageDummy'; var content = ''' @@ -168,6 +170,7 @@ class ${clazzName}State extends State<$clazzName> { } Future buildChildrenPages( + String basePath, dynamic config, String appId, ComponentNode node, @@ -185,12 +188,13 @@ Future buildChildrenPages( n.builtComponent!.route = ''; n.builtComponent!.clazzName = 'CatalogComponent'; - final File file = File(n.builtComponent!.path); + final File file = File(basePath + n.builtComponent!.path); var fp = file.path.split(config['base'])[1]; n.builtComponent!.package = 'package:$appId$fp'; for (var entry in n.children.entries) { var f = await buildChildrenPages( + basePath, config, appId, entry.value, @@ -217,7 +221,7 @@ Future buildChildrenPages( } // print('Generating middle page: $current'); - var middleFolder = './${config['base']}/${config['output']}/$p'; + var middleFolder = './$basePath${config['base']}/${config['output']}/$p'; n.builtComponent = await buildMiddlePages( appId, config['base'], @@ -233,7 +237,9 @@ Future buildChildrenPages( n.builtComponent!.route = p; for (var entry in n.children.entries) { + print('build children page: ${entry.key}'); var f = await buildChildrenPages( + basePath, config, appId, entry.value, @@ -257,6 +263,8 @@ ComponentNode getNodesFrom( var firstNode = ComponentNode(id: pageRoute, route: '/'); for (var entity in components.values.toList()) { + print('======================================================='); + print('route: ${entity.route}'); var parts = entity.route.split('/'); if (parts.first == '.') { parts.removeAt(0); @@ -285,17 +293,21 @@ void addNode( } if (no == null) { + print('parts: ${parts.join(', ')}'); no = ComponentNode( id: parts[index], route: '/${parts[index]}', builtComponent: parts.length - 1 == index ? component : null, ); - // print('adding: ${no.id}'); - // print(' ${no.builtComponent?.preview?.path}'); + print('adding: ${no.id}'); + print(' ${no.builtComponent?.preview?.path}'); node.children[no.id] = no; } - if (index < parts.length) { + if (no.route == '/${component.route}') { + final a = '/${component.package.split('/').last}'; + node.children[no.id]?.builtComponents[a] = component; + } else if (index < parts.length) { addNode(no, parts, index + 1, component); } } diff --git a/bin/preview_builder/dummy_builder.dart b/lib/src/bin/preview_builder/dummy_builder.dart similarity index 83% rename from bin/preview_builder/dummy_builder.dart rename to lib/src/bin/preview_builder/dummy_builder.dart index b34e5f7..ea5c5ee 100644 --- a/bin/preview_builder/dummy_builder.dart +++ b/lib/src/bin/preview_builder/dummy_builder.dart @@ -9,11 +9,11 @@ Future generateDummy( String fileName = srcPath.split('/').last; String name = fileName.split('.').first; String dirPath = srcPath.replaceAll(fileName, ''); - String previewPath = '${dirPath}preview/dummy/'; + String dummyPath = '${dirPath}catalog/dummy/'; - await Directory(previewPath).create(recursive: true); + await Directory(dummyPath).create(recursive: true); - String dummyFile = '$previewPath$name.dummy.dart'; + String dummyFile = '$dummyPath$name.dummy.dart'; File file = File(dummyFile); if (await file.exists()) { diff --git a/bin/preview_builder/preview_builder.dart b/lib/src/bin/preview_builder/preview_builder.dart similarity index 68% rename from bin/preview_builder/preview_builder.dart rename to lib/src/bin/preview_builder/preview_builder.dart index 70b47c7..716fc76 100644 --- a/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/preview_builder/preview_builder.dart @@ -23,13 +23,7 @@ Future generatePreview( ) async { var clazz = className.replaceAll('()', ''); - var widgetCompose = ''; - - if (preview.usesDummies) { - widgetCompose = dummyWidgetContent(className, preview); - } else { - widgetCompose = basicWidgetContent(className, preview); - } + var widgetCompose = dummyWidgetContent(className, preview); String fileName = srcPath.split('/').last; String name = fileName.split('.').first; @@ -40,22 +34,12 @@ Future generatePreview( import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; import '$classImport'; -${preview.usesDummies ? '''import 'dummy/$name.dummy.dart';''' : ''} +import '../dummy/$name.dummy.dart'; $previewAnnotation class ${clazz}Preview extends ParentPreviewWidget { const ${clazz}Preview({super.key}); - - ${!preview.usesDummies ? ''' - @override - Widget preview(BuildContext context) => Container( - constraints: const BoxConstraints(maxWidth: 700), - child: ${(preview.parameters.containsKey('child') || preview.parameters.isEmpty) ? 'const' : ''} $widgetCompose, - ); - ''' : ''} - - ${preview.usesDummies ? ''' - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -147,12 +131,12 @@ class ${clazz}Preview extends ParentPreviewWidget { ); } - ''' : ''} + } '''; String dirPath = srcPath.replaceAll(fileName, ''); - String previewPath = '${dirPath}preview/'; + String previewPath = '${dirPath}catalog/preview/'; await Directory(previewPath).create(recursive: true); @@ -176,78 +160,16 @@ String dummyWidgetBuilder(String clazz, String widgetCompose) { '''; } -String basicWidgetContent(String className, Preview preview) { - var clazz = className.replaceAll('()', ''); - - var widgetCompose = '$clazz('; - - for (dynamic element in preview.listParameters) { - if (element is String) { - widgetCompose += '\'$element\','; - } - } - var params = preview.parameters.entries.toList(); - if (params.isNotEmpty) { - widgetCompose += ''; - for (MapEntry entry in params) { - if (entry.value is String) { - if (entry.value == 'void_function_snackbar') { - widgetCompose += '''${entry.key}: () { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - duration: Duration(seconds: 2), - content: Text( - '${entry.key} event', - ), - ), - ); - },'''; - } else if (entry.value == 'dummy_text_small') { - widgetCompose += '''child: DummyText(),'''; - } else { - widgetCompose += '${entry.key}: \'${entry.value}\','; - } - } - } - widgetCompose += ''; - } - - widgetCompose += ')'; - - return widgetCompose; -} - String dummyWidgetContent(String className, Preview preview) { var clazz = className.replaceAll('()', ''); var widgetCompose = '$clazz('; - /* - for (dynamic element in preview.listParameters) { - if (element is String) { - widgetCompose += '\'$element\','; - } - }*/ - var params = preview.dummyParameters; + var params = preview.parameters; if (params.isNotEmpty) { widgetCompose += ''; for (String key in params) { - if (key == 'void_function_snackbar') { - widgetCompose += '''$key: () { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - duration: Duration(seconds: 2), - content: Text( - 'callback $key', - ), - ), - ); - },'''; - } else if (key == 'dummy_text_small') { - widgetCompose += '''child: const DummyText(),'''; - } else { - widgetCompose += '''$key: dummy.parameters['$key'],'''; - } + widgetCompose += '''$key: dummy.parameters['$key'],'''; } widgetCompose += ''; } diff --git a/lib/src/bin/tasks/base/base_task.dart b/lib/src/bin/tasks/base/base_task.dart new file mode 100644 index 0000000..4c5e2d4 --- /dev/null +++ b/lib/src/bin/tasks/base/base_task.dart @@ -0,0 +1,3 @@ +abstract class BaseTask { + Future work(List args); +} diff --git a/bin/tasks/main_task.dart b/lib/src/bin/tasks/main_task.dart similarity index 85% rename from bin/tasks/main_task.dart rename to lib/src/bin/tasks/main_task.dart index 8fcf816..b20ea2e 100644 --- a/bin/tasks/main_task.dart +++ b/lib/src/bin/tasks/main_task.dart @@ -11,11 +11,11 @@ class MainTask extends BaseTask { ]; @override - Future work() async { + Future work(List args) async { for (BaseTask task in tasks) { try { print('\n - Running ${task.runtimeType.toString()} \n'); - await task.work(); + await task.work(args); } catch (e) { print(e); } diff --git a/bin/tasks/preview_task.dart b/lib/src/bin/tasks/preview_task.dart similarity index 84% rename from bin/tasks/preview_task.dart rename to lib/src/bin/tasks/preview_task.dart index c4db964..674c0e3 100644 --- a/bin/tasks/preview_task.dart +++ b/lib/src/bin/tasks/preview_task.dart @@ -9,11 +9,11 @@ class PreviewTask extends BaseTask { ]; @override - Future work() async { + Future work(List args) async { for (BaseTask task in tasks) { try { print('\n - Running ${task.runtimeType.toString()} \n'); - await task.work(); + await task.work(args); } catch (e) { print(e); } diff --git a/bin/tasks/tasks/catalog_task.dart b/lib/src/bin/tasks/tasks/catalog_task.dart similarity index 86% rename from bin/tasks/tasks/catalog_task.dart rename to lib/src/bin/tasks/tasks/catalog_task.dart index 5fd0f6e..6287d56 100644 --- a/bin/tasks/tasks/catalog_task.dart +++ b/lib/src/bin/tasks/tasks/catalog_task.dart @@ -10,19 +10,21 @@ import '../base/base_task.dart'; class CatalogTask extends BaseTask { @override - Future work() async { - var appId = loadId(); - var config = loadConfigFile(); + Future work(List args) async { + final base = args.isEmpty ? '' : '${args.first}/'; + + var appId = loadId(base); + var config = loadConfigFile(base); final page = config['pageFile'] ?? 'catalog_component.dart'; final pageName = config['pageName'] ?? 'CatalogComponent'; final pageRoute = config['pageRoute'] ?? 'catalog'; final prefixValue = config['prefix'] ?? 'preview'; - final dir = Directory('./${config['base']}'); + final dir = Directory('./$base${config['base']}'); await dir.create(recursive: true); - final dirOutPut = Directory('./${config['base']}/${config['output']}'); + final dirOutPut = Directory('./$base${config['base']}/${config['output']}'); await dirOutPut.create(recursive: true); final List entities = @@ -51,6 +53,7 @@ class CatalogTask extends BaseTask { //print('- Building preview of $className in $package'); var preview = await previewOnFile( + base, config, file.path, ); @@ -63,7 +66,9 @@ class CatalogTask extends BaseTask { // print('Preview: ${jsonEncode(preview.toJson())}'); var outputFolder = - './${config['base']}/${config['output']}/${preview.path}/'; + './$base${config['base']}/${config['output']}/${preview.path}/'; + + print('Catalog page destination: $outputFolder'); var build = await createPage( appId, @@ -82,12 +87,16 @@ class CatalogTask extends BaseTask { } // print('Built: ${jsonEncode(build!.toJson())}'); + print('${build!.preview!.path} with classname ${className}'); map[build!.preview!.path] = build; } ComponentNode? node = getNodesFrom(pageRoute, map); + print('node: ${node.childrenList.map((e) => e.id).join(', ')}'); + node = await buildChildrenPages( + base, config, appId, node, @@ -100,13 +109,15 @@ class CatalogTask extends BaseTask { return; } + print('node 2: ${node.childrenList.map((e) => e.id).join(', ')}'); + // print(node.toJson().toPrettyString()); - final File assetsConfig = File('./${config['runtimeConfigHolder']}'); + final File assetsConfig = File('./$base${config['runtimeConfigHolder']}'); assetsConfig.writeAsStringSync(node.toJson().toPrettyString()); final File catalogFile = - File('./${config['base']}/${config['output']}/$page'); + File('./$base${config['base']}/${config['output']}/$page'); // print(node.routerBuilder); @@ -210,7 +221,7 @@ class ${pageName}State extends State<$pageName> { catalogFile.writeAsStringSync(catalogContent); final File file = - File('./${config['base']}/${config['output']}/process.dart'); + File('./$base${config['base']}/${config['output']}/process.dart'); if (file.existsSync()) await file.delete(); } } diff --git a/bin/tasks/tasks/format_task.dart b/lib/src/bin/tasks/tasks/format_task.dart similarity index 86% rename from bin/tasks/tasks/format_task.dart rename to lib/src/bin/tasks/tasks/format_task.dart index 4ea7563..4a8c817 100644 --- a/bin/tasks/tasks/format_task.dart +++ b/lib/src/bin/tasks/tasks/format_task.dart @@ -4,7 +4,7 @@ import '../base/base_task.dart'; class FormatTask extends BaseTask { @override - Future work() async { + Future work(List args) async { var result = await Process.run( 'dart', ['format', 'lib/'], diff --git a/bin/tasks/tasks/preview_task.dart b/lib/src/bin/tasks/tasks/preview_task.dart similarity index 77% rename from bin/tasks/tasks/preview_task.dart rename to lib/src/bin/tasks/tasks/preview_task.dart index fdbf655..cbc5a66 100644 --- a/bin/tasks/tasks/preview_task.dart +++ b/lib/src/bin/tasks/tasks/preview_task.dart @@ -7,16 +7,18 @@ import '../base/base_task.dart'; class PreviewTask extends BaseTask { @override - Future work() async { - var appId = loadId(); - var config = loadConfigFile(); + Future work(List args) async { + final base = args.isEmpty ? '' : '${args.first}/'; + + var appId = loadId(base); + var config = loadConfigFile(base); final prefixValue = config['prefix'] ?? 'preview'; - final dir = Directory('./${config['base']}'); + final dir = Directory('./$base${config['base']}'); await dir.create(recursive: true); - final dirOutPut = Directory('./${config['base']}/${config['output']}'); + final dirOutPut = Directory('./$base${config['base']}/${config['output']}'); await dirOutPut.create(recursive: true); final List entities = @@ -43,7 +45,8 @@ class PreviewTask extends BaseTask { final File file = File(fileSystemEntity.path); var p = file.path.split(config['base'])[1]; var classImport = 'package:$appId$p'; - var preview = await previewOnFile(config, file.path); + print('preview on file: ${file.path}'); + var preview = await previewOnFile(base, config, file.path); var previewAnnotation = await findPreviewAnnotation(file.path); if (previewAnnotation == null) continue; var className = await findClassName(file.path); @@ -59,12 +62,10 @@ class PreviewTask extends BaseTask { preview, ); - if (preview.usesDummies) { - await generateDummy( - file.path, - className, - ); - } + await generateDummy( + file.path, + className, + ); } } } diff --git a/bin/tasks/tasks/server_task.dart b/lib/src/bin/tasks/tasks/server_task.dart similarity index 79% rename from bin/tasks/tasks/server_task.dart rename to lib/src/bin/tasks/tasks/server_task.dart index efd9ebc..ab82f2b 100644 --- a/bin/tasks/tasks/server_task.dart +++ b/lib/src/bin/tasks/tasks/server_task.dart @@ -3,7 +3,7 @@ import '../base/base_task.dart'; class ServerTask extends BaseTask { @override - Future work() async { + Future work(List args) async { await ServiceWorkerImpl().start(); } } diff --git a/bin/utils/communicator/service_worker.dart b/lib/src/bin/utils/communicator/service_worker.dart similarity index 93% rename from bin/utils/communicator/service_worker.dart rename to lib/src/bin/utils/communicator/service_worker.dart index 72fc2ae..0e2dae0 100644 --- a/bin/utils/communicator/service_worker.dart +++ b/lib/src/bin/utils/communicator/service_worker.dart @@ -21,8 +21,7 @@ abstract class ServiceWorker { serviceStarted = true; - final handler = const Pipeline() - .addHandler(_echoRequest); + final handler = const Pipeline().addHandler(_echoRequest); final server = await shelf_io.serve(handler, ip, port); closeServer = () async { diff --git a/bin/utils/communicator/service_worker_impl.dart b/lib/src/bin/utils/communicator/service_worker_impl.dart similarity index 100% rename from bin/utils/communicator/service_worker_impl.dart rename to lib/src/bin/utils/communicator/service_worker_impl.dart diff --git a/bin/utils/configuration.dart b/lib/src/bin/utils/configuration.dart similarity index 69% rename from bin/utils/configuration.dart rename to lib/src/bin/utils/configuration.dart index 9d1a3dd..73f8c69 100644 --- a/bin/utils/configuration.dart +++ b/lib/src/bin/utils/configuration.dart @@ -19,8 +19,8 @@ String introMessage(String version) => ''' ════════════════════════════════════════════ '''; -Map loadConfigFile() { - final File file = File("pubspec.yaml"); +Map loadConfigFile(String basePath) { + final File file = File("${basePath}pubspec.yaml"); final String yamlString = file.readAsStringSync(); // ignore: always_specify_types final Map yamlMap = loadYaml(yamlString); @@ -42,8 +42,8 @@ Map loadConfigFile() { return config; } -Map loadDependenciesFile() { - final File file = File("pubspec.yaml"); +Map loadDependenciesFile(String basePath) { + final File file = File("${basePath}pubspec.yaml"); final String yamlString = file.readAsStringSync(); // ignore: always_specify_types final Map yamlMap = loadYaml(yamlString); @@ -65,8 +65,8 @@ Map loadDependenciesFile() { return config; } -String loadId() { - final File file = File("pubspec.yaml"); +String loadId(String basePath) { + final File file = File("${basePath}pubspec.yaml"); final String yamlString = file.readAsStringSync(); // ignore: always_specify_types final Map yamlMap = loadYaml(yamlString); @@ -75,13 +75,17 @@ String loadId() { } Future previewOnFile( + String basePath, dynamic config, String originalFilePath, ) async { try { - var output = './${config['base']}/${config['output']}/'; + var output = './$basePath${config['base']}/${config['output']}/'; var fileName = 'process.dart'; + print('\n==========================================================\n'); + print('Original file: $originalFilePath'); + File originalFile = File(originalFilePath); var originalContent = originalFile.readAsStringSync(); @@ -89,6 +93,7 @@ Future previewOnFile( 'Preview${originalContent.split('@Preview')[1].split(')').first});'; var dir = Directory(output); await dir.create(recursive: true); + File file = File('$output/$fileName'); var content = ''' import 'dart:convert'; @@ -99,19 +104,13 @@ class Preview implements Serial { final String id; final String path; final String description; - final bool usesDummies; - final List dummyParameters; - final List listParameters; - final Map parameters; + final List parameters; const Preview({ - required this.id, - required this.path, + this.id = '', + this.path = '', this.description = '', - this.usesDummies = false, - this.parameters = const {}, - this.listParameters = const [], - this.dummyParameters = const [], + this.parameters = const [], }); @override @@ -119,12 +118,9 @@ class Preview implements Serial { id: json['id'] ?? '', path: json['path'] ?? '', description: json['description'] ?? '', - usesDummies: json['usesDummies'] ?? false, - dummyParameters: Serial.listObjectFromBasicType( - json['dummyParameters'] ?? [], + parameters: Serial.listObjectFromBasicType( + json['parameters'] ?? [], ), - listParameters: json['listParameters'] ?? [], - parameters: json['parameters'] ?? {}, ); @override @@ -138,9 +134,6 @@ class Preview implements Serial { 'id': id, 'path': path, 'description': description, - 'usesDummies': usesDummies, - 'listParameters': listParameters, - 'dummyParameters': dummyParameters, 'parameters': parameters, }; @@ -155,6 +148,19 @@ class Preview implements Serial { var map = toJson(); return jsonEncode(map); } + + Preview copyWith({ + String? id, + String? path, + String? description, + List? parameters, + }) => + Preview( + id: id ?? this.id, + path: path ?? this.path, + description: description ?? this.description, + parameters: parameters ?? this.parameters, + ); } void main(List arguments) async { @@ -168,6 +174,27 @@ void main(List arguments) async { var result = await Process.run('dart', ['run', path]); var preview = const Preview(id: '', path: '').fromJson(jsonDecode(result.stdout)); + + if (preview.id.isEmpty) { + preview = preview.copyWith( + id: originalFilePath.split('/').last.split('.').first, + ); + } + + if (preview.path.isEmpty) { + if (originalFilePath.contains('/catalog')) { + preview = preview.copyWith( + path: originalFilePath.split('/lib/').last.split('/catalog').first, + ); + } else { + var parts = originalFilePath.split('/lib/').last.split('/'); + preview = preview.copyWith( + path: parts.sublist(0, parts.length - 1).join('/'), + ); + } + } + + print('########### GENERATED PREVIEW: ${preview.id} ${preview.path}'); return preview; } catch (e) { print(e); diff --git a/bin/utils/exceptions.dart b/lib/src/bin/utils/exceptions.dart similarity index 100% rename from bin/utils/exceptions.dart rename to lib/src/bin/utils/exceptions.dart diff --git a/lib/src/builders/catalog/component_node.dart b/lib/src/builders/catalog/component_node.dart index ec2a1d0..abba075 100644 --- a/lib/src/builders/catalog/component_node.dart +++ b/lib/src/builders/catalog/component_node.dart @@ -1,12 +1,19 @@ +import 'dart:convert'; + import 'package:catalog/src/base/serial.dart'; import 'package:catalog/src/builders/catalog/built_component.dart'; +import 'package:catalog/src/builders/catalog/tree_element.dart'; class ComponentNode extends Serial { String id = ''; String route = ''; BuiltComponent? builtComponent; + Map builtComponents = {}; Map children = {}; + List get builtComponentList => + builtComponents.values.toList(); + List get childrenList => children.values.toList(); ComponentNode({ @@ -22,6 +29,8 @@ class ComponentNode extends Serial { if (json['builtComponent'] != null) { builtComponent = BuiltComponent().fromJson(json['builtComponent'] ?? {}); } + builtComponents = + Serial.fromComplexMap(json['builtComponents'] ?? {}); children = Serial.fromComplexMap(json['children'] ?? {}); return this; } @@ -37,19 +46,42 @@ class ComponentNode extends Serial { 'id': id, 'route': route, 'builtComponent': builtComponent?.toJson(), + 'builtComponents': + builtComponents.isEmpty ? {} : Serial.toMap(builtComponents), 'children': children.isEmpty ? {} : Serial.toMap(children), }; - String get routerBuilder => ''' + String get routerBuilder { + for (var o in childrenList) { + print('routes builder: ${jsonEncode(o.toJson())}'); + } + return ''' GoRoute( path: ${builtComponent?.clazzName}.routeName, pageBuilder: (context, state) => NoTransitionPage( key: state.pageKey, child: const ${builtComponent?.clazzName}(), ), - routes: [${childrenList.map((e) => e.routerBuilder).toList().join(',')}], + routes: [ + ${builtComponentList.map((e) { + return ''' + + GoRoute( + path: ${e.clazzName}.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const ${e.clazzName}(), + ), + ), + + '''; + }).toList().join(',')} + ${childrenList.map((e) => e.routerBuilder).toList().join(',')} + + ], ) '''; + } String get imports { String value = ''; @@ -57,16 +89,22 @@ class ComponentNode extends Serial { return value; } if (route == "/") { - value += '''${childrenList.map((e) => e.imports).toList().join('')} -'''; + value += '''${childrenList.map((e) => e.imports).toList().join('')}\n'''; } else { if (childrenList.isEmpty) { - value += '''import '${builtComponent!.package}'; -'''; + print('adding import (single): ${builtComponent!.package}'); + value += '''import '${builtComponent!.package}';\n'''; } else { value += '''import '${builtComponent!.package}'; -${childrenList.map((e) => e.imports).toList().join('')} -'''; +${childrenList.map((e) { + print('adding import: ${e.imports}'); + return e.imports; + }).toList().join('')}\n + +${builtComponentList.map((e) { + print('adding import: ${e.package}'); + return 'import \'${e.package}\';'; + }).toList().join('')}\n'''; } } return value; diff --git a/lib/src/builders/catalog/tree_element.dart b/lib/src/builders/catalog/tree_element.dart new file mode 100644 index 0000000..2e89ded --- /dev/null +++ b/lib/src/builders/catalog/tree_element.dart @@ -0,0 +1,8 @@ +import 'package:catalog/src/builders/catalog/built_component.dart'; + +class TreeElement { + BuiltComponent? component; + List children = []; + + TreeElement(); +} diff --git a/lib/src/builders/dummy/dummy.dart b/lib/src/builders/dummy/dummy.dart index 38acb39..3fc1bd8 100644 --- a/lib/src/builders/dummy/dummy.dart +++ b/lib/src/builders/dummy/dummy.dart @@ -14,8 +14,6 @@ class Dummy { final Screenshot screenshot; - final List listParameters; - final Map parameters; const Dummy({ @@ -23,7 +21,6 @@ class Dummy { this.parameters = const {}, this.device = const Device(), this.screenshot = const Screenshot(), - this.listParameters = const [], }); Dummy copyWith({ @@ -31,14 +28,12 @@ class Dummy { Map? parameters, Device? device, Screenshot? screenshot, - List? listParameters, }) => Dummy( description: description ?? this.description, parameters: parameters ?? this.parameters, device: device ?? this.device, screenshot: screenshot ?? this.screenshot, - listParameters: listParameters ?? this.listParameters, ); bool isDeviceDummy() => device.deviceInfo != null; diff --git a/pubspec.yaml b/pubspec.yaml index 068a10b..9855cef 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,8 +15,8 @@ dependencies: device_frame: ^1.2.0 # android ios linux macos web windows flutter_svg: ^2.0.10+1 # android ios linux macos windows global_refresh: ^1.0.0 # android ios linux macos web windows - go_router: ^14.2.0 # android ios linux macos web windows - http: ^1.2.1 # android ios linux macos web windows + go_router: ^14.2.8 # android ios linux macos web windows + http: ^1.2.2 # android ios linux macos web windows image: ^4.2.0 # android ios linux macos web windows shelf: ^1.4.1 # android ios linux macos web windows vector_graphics: ^1.1.11+1 # android ios linux macos web windows @@ -26,6 +26,4 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^4.0.0 - -flutter: + flutter_lints: ^5.0.0 diff --git a/test/catalog_test.dart b/test/catalog_test.dart index d6f2093..8c418c2 100644 --- a/test/catalog_test.dart +++ b/test/catalog_test.dart @@ -1,3 +1,5 @@ +import 'package:catalog/src/bin/tasks/main_task.dart'; +import 'package:catalog/src/bin/utils/configuration.dart'; import 'package:catalog/src/catalog_runner.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -13,4 +15,20 @@ void main() { ); expect(runner.enabled, false); }); + + test('Test Preview task (preview + format)', () async { + final exampleFolder = 'example'; + var dependencies = loadDependenciesFile('$exampleFolder/'); + print(introMessage(dependencies['catalog'].toString())); + await MainTask().work([exampleFolder]); + assert(true); + }); + + test('Test Main task (preview + catalog + format)', () async { + final exampleFolder = 'example'; + var dependencies = loadDependenciesFile('$exampleFolder/'); + print(introMessage(dependencies['catalog'].toString())); + await MainTask().work([exampleFolder]); + assert(true); + }); } From 21b225d674b633e8cf253f86dd519d251dcbe34f Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Thu, 3 Oct 2024 00:21:08 +0200 Subject: [PATCH 02/28] feature: removed not needed configs, added unit tests and github actions --- .github/workflows/push_check_analyze.yml | 67 +++++++++++++++++ .../workflows/push_check_publish_dry_run.yml | 67 +++++++++++++++++ .github/workflows/push_check_test.yml | 73 +++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 .github/workflows/push_check_analyze.yml create mode 100644 .github/workflows/push_check_publish_dry_run.yml create mode 100644 .github/workflows/push_check_test.yml diff --git a/.github/workflows/push_check_analyze.yml b/.github/workflows/push_check_analyze.yml new file mode 100644 index 0000000..abe74ab --- /dev/null +++ b/.github/workflows/push_check_analyze.yml @@ -0,0 +1,67 @@ +name: Push Analyze Check + +on: + push: + branches: + - '**' + +jobs: + push_check_analyze: + + runs-on: self-hosted + + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js 18 + uses: actions/setup-node@v4 + with: + node-version: '18.x' + + - name: Install Landa Messenger CLI + run: npm install @landamessenger/landa-messenger-api -g + + - uses: subosito/flutter-action@v1 + with: + channel: 'stable' + flutter-version: '3.24.3' + + - run: flutter pub get + + - run: flutter analyze + + - name: Handle job completion + if: always() + run: | + if [ "${{ job.status }}" == "failure" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🔴 Analysis Failed" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/push_check_analyze.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + elif [ "${{ job.status }}" == "cancelled" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟠 Analysis Canceled" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/push_check_analyze.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + else + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟢 Analysis Passed" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/push_check_analyze.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + fi + diff --git a/.github/workflows/push_check_publish_dry_run.yml b/.github/workflows/push_check_publish_dry_run.yml new file mode 100644 index 0000000..ac126fd --- /dev/null +++ b/.github/workflows/push_check_publish_dry_run.yml @@ -0,0 +1,67 @@ +name: Push Publish Dry Run Check + +on: + push: + branches: + - '**' + +jobs: + push_check_publish_dry_run: + + runs-on: self-hosted + + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js 18 + uses: actions/setup-node@v4 + with: + node-version: '18.x' + + - name: Install Landa Messenger CLI + run: npm install @landamessenger/landa-messenger-api -g + + - uses: subosito/flutter-action@v1 + with: + channel: 'stable' + flutter-version: '3.24.3' + + - run: flutter pub get + + - run: dart pub publish --dry-run + + - name: Handle job completion + if: always() + run: | + if [ "${{ job.status }}" == "failure" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🔴 Dry Publish Failed" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/push_check_publish_dry_run.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + elif [ "${{ job.status }}" == "cancelled" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟠 Dry Publish Canceled" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/push_check_publish_dry_run.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + else + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟢 Dry Publish Passed" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/push_check_publish_dry_run.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + fi + diff --git a/.github/workflows/push_check_test.yml b/.github/workflows/push_check_test.yml new file mode 100644 index 0000000..bb764c0 --- /dev/null +++ b/.github/workflows/push_check_test.yml @@ -0,0 +1,73 @@ +name: Push Test Check + +on: + push: + branches: + - '**' + +jobs: + push_check_test: + + runs-on: self-hosted + + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js 18 + uses: actions/setup-node@v4 + with: + node-version: '18.x' + + - name: Install Landa Messenger CLI + run: npm install @landamessenger/landa-messenger-api -g + + - uses: subosito/flutter-action@v1 + with: + channel: 'stable' + flutter-version: '3.24.3' + + - run: flutter pub get + + - run: flutter test --coverage + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: coverage/lcov.info + + - name: Handle job completion + if: always() + run: | + if [ "${{ job.status }}" == "failure" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🔴 Test Failed" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/push_check_test.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + elif [ "${{ job.status }}" == "cancelled" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟠 Test Canceled" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/push_check.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + else + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟢 Test Passed" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/push_check.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + fi + From 4c66901b08a6252b15975afc6a0c596de909d25d Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Thu, 3 Oct 2024 00:21:20 +0200 Subject: [PATCH 03/28] feature: removed not needed configs, added unit tests and github actions --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 970b7b4..ba89cf5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ *.lock .dart_tool .DS_Store -.idea/ \ No newline at end of file +.idea/ + +/build \ No newline at end of file From c087eafe2b610a43756993dc2d39443195b5d503 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Fri, 4 Oct 2024 00:35:34 +0200 Subject: [PATCH 04/28] feature: linter warnings and dart fix command --- analysis_options.yaml | 4 ++++ example/analysis_options.yaml | 3 +++ lib/catalog.dart | 2 +- lib/src/bin/tasks/tasks/catalog_task.dart | 4 ++-- lib/src/bin/tasks/tasks/format_task.dart | 8 ++++++++ lib/src/builders/catalog/component_node.dart | 1 - .../flutter_fanacy_tree_view/flutter_fancy_tree_view.dart | 2 +- .../embed/flutter_fanacy_tree_view/src/folder_button.dart | 4 ---- lib/src/utils/svg.dart | 2 +- test/catalog_test.dart | 1 + 10 files changed, 21 insertions(+), 10 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 9d8c40b..a5d702a 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,3 +1,7 @@ +analyzer: + errors: + dangling_library_doc_comments: ignore + include: package:flutter_lints/flutter.yaml linter: diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 0d29021..92bb9a7 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -7,6 +7,9 @@ # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. +analyzer: + errors: + dangling_library_doc_comments: ignore include: package:flutter_lints/flutter.yaml linter: diff --git a/lib/catalog.dart b/lib/catalog.dart index 67cdc1f..60f311b 100644 --- a/lib/catalog.dart +++ b/lib/catalog.dart @@ -1,4 +1,4 @@ -library catalog; +library; import 'dart:convert'; import 'dart:typed_data'; diff --git a/lib/src/bin/tasks/tasks/catalog_task.dart b/lib/src/bin/tasks/tasks/catalog_task.dart index 6287d56..e1ec6ff 100644 --- a/lib/src/bin/tasks/tasks/catalog_task.dart +++ b/lib/src/bin/tasks/tasks/catalog_task.dart @@ -87,8 +87,8 @@ class CatalogTask extends BaseTask { } // print('Built: ${jsonEncode(build!.toJson())}'); - print('${build!.preview!.path} with classname ${className}'); - map[build!.preview!.path] = build; + print('${build!.preview!.path} with classname $className'); + map[build.preview!.path] = build; } ComponentNode? node = getNodesFrom(pageRoute, map); diff --git a/lib/src/bin/tasks/tasks/format_task.dart b/lib/src/bin/tasks/tasks/format_task.dart index 4a8c817..d2a32b1 100644 --- a/lib/src/bin/tasks/tasks/format_task.dart +++ b/lib/src/bin/tasks/tasks/format_task.dart @@ -12,5 +12,13 @@ class FormatTask extends BaseTask { ); stdout.write(result.stdout); stderr.write(result.stderr); + + var resultFix = await Process.run( + 'dart', + ['fix', '--apply'], + workingDirectory: Directory.current.path, + ); + stdout.write(resultFix.stdout); + stderr.write(resultFix.stderr); } } diff --git a/lib/src/builders/catalog/component_node.dart b/lib/src/builders/catalog/component_node.dart index abba075..2b160e2 100644 --- a/lib/src/builders/catalog/component_node.dart +++ b/lib/src/builders/catalog/component_node.dart @@ -2,7 +2,6 @@ import 'dart:convert'; import 'package:catalog/src/base/serial.dart'; import 'package:catalog/src/builders/catalog/built_component.dart'; -import 'package:catalog/src/builders/catalog/tree_element.dart'; class ComponentNode extends Serial { String id = ''; diff --git a/lib/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_view.dart b/lib/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_view.dart index 0be7089..b1a30fc 100644 --- a/lib/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_view.dart +++ b/lib/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_view.dart @@ -1,6 +1,6 @@ /// A collection of widgets and slivers that helps bringing hierarchical data /// to life. -library flutter_fancy_tree_view; +library; export 'src/folder_button.dart'; export 'src/sliver_animated_tree.dart'; diff --git a/lib/src/embed/flutter_fanacy_tree_view/src/folder_button.dart b/lib/src/embed/flutter_fanacy_tree_view/src/folder_button.dart index a698e5e..acb9654 100644 --- a/lib/src/embed/flutter_fanacy_tree_view/src/folder_button.dart +++ b/lib/src/embed/flutter_fanacy_tree_view/src/folder_button.dart @@ -287,10 +287,6 @@ class FolderButton extends StatelessWidget { /// /// Non-null properties of this style override the corresponding /// properties in [_IconButtonM3.themeStyleOf] and [_IconButtonM3.defaultStyleOf]. - /// [MaterialStateProperty]s that resolve to non-null values will similarly - /// override the corresponding [MaterialStateProperty]s in [_IconButtonM3.themeStyleOf] - /// and [_IconButtonM3.defaultStyleOf]. - /// /// The [style] is only used for Material 3 [IconButton]. If [ThemeData.useMaterial3] /// is set to true, [style] is preferred for icon button customization, and any /// parameters defined in [style] will override the same parameters in [IconButton]. diff --git a/lib/src/utils/svg.dart b/lib/src/utils/svg.dart index 9aa52fb..0482f24 100644 --- a/lib/src/utils/svg.dart +++ b/lib/src/utils/svg.dart @@ -1,4 +1,4 @@ -library flutter_svg_provider; +library; import 'dart:async'; import 'dart:io'; diff --git a/test/catalog_test.dart b/test/catalog_test.dart index 8c418c2..053b1a9 100644 --- a/test/catalog_test.dart +++ b/test/catalog_test.dart @@ -11,6 +11,7 @@ void main() { application: Container(), route: GoRoute( path: '/catalog', + builder: (context, state) => Container() ), ); expect(runner.enabled, false); From 03df2e8d6f2c6a690b7ffd1acb2cb1671f62c7f4 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Fri, 4 Oct 2024 00:46:58 +0200 Subject: [PATCH 05/28] feature: fix formating --- .pubignore | 4 +- example/assets/preview_config.json | 10 +- example/lib/catalog/catalog_component.dart | 127 +++++++----------- .../widgets/body_widget/body_widget.dart | 10 +- .../counter_widget/counter_widget.dart | 10 +- example/lib/catalog/widgets/main_screen.dart | 10 +- .../catalog/widgets/screen/fab_widget.dart | 10 +- .../catalog/preview/main_screen.preview.dart | 28 ++-- .../catalog/preview/body_widget.preview.dart | 26 ++-- .../preview/counter_widget.preview.dart | 25 ++-- .../catalog/preview/fab_widget.preview.dart | 25 ++-- lib/src/bin/tasks/tasks/format_task.dart | 18 +-- 12 files changed, 137 insertions(+), 166 deletions(-) diff --git a/.pubignore b/.pubignore index d75cb98..f199644 100644 --- a/.pubignore +++ b/.pubignore @@ -3,4 +3,6 @@ widget_preview.iml *.lock .dart_tool .DS_Store -.idea/ \ No newline at end of file +lib/.DS_Store +lib/src/.DS_Store +.idea/ diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index 4b7b408..de912b8 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -14,7 +14,7 @@ "id": "widgets", "route": "/widgets", "builtComponent": { - "path": "./example/lib/catalog/widgets/main_screen.dart", + "path": "./lib/catalog/widgets/main_screen.dart", "route": "widgets", "package": "package:example/catalog/widgets/main_screen.dart", "clazzName": "MainScreenPreviewPreviewPageDummy", @@ -32,7 +32,7 @@ }, "builtComponents": { "/main_screen.dart": { - "path": "./example/lib/catalog/widgets/main_screen.dart", + "path": "./lib/catalog/widgets/main_screen.dart", "route": "widgets", "package": "package:example/catalog/widgets/main_screen.dart", "clazzName": "MainScreenPreviewPreviewPageDummy", @@ -54,7 +54,7 @@ "id": "body_widget", "route": "/body_widget", "builtComponent": { - "path": "./example/lib/catalog/widgets/body_widget/body_widget.dart", + "path": "./lib/catalog/widgets/body_widget/body_widget.dart", "route": "widgets/body_widget", "package": "package:example/catalog/widgets/body_widget/body_widget.dart", "clazzName": "BodyWidgetPreviewPreviewPageDummy", @@ -75,7 +75,7 @@ "id": "screen", "route": "/screen", "builtComponent": { - "path": "./example/lib/catalog/widgets/screen/fab_widget.dart", + "path": "./lib/catalog/widgets/screen/fab_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/fab_widget.dart", "clazzName": "FabWidgetPreviewPreviewPageDummy", @@ -95,7 +95,7 @@ "id": "counter_widget", "route": "/counter_widget", "builtComponent": { - "path": "./example/lib/catalog/widgets/counter_widget/counter_widget.dart", + "path": "./lib/catalog/widgets/counter_widget/counter_widget.dart", "route": "widgets/counter_widget", "package": "package:example/catalog/widgets/counter_widget/counter_widget.dart", "clazzName": "CounterWidgetPreviewPreviewPageDummy", diff --git a/example/lib/catalog/catalog_component.dart b/example/lib/catalog/catalog_component.dart index a35f840..5cd8b22 100644 --- a/example/lib/catalog/catalog_component.dart +++ b/example/lib/catalog/catalog_component.dart @@ -7,84 +7,57 @@ import 'package:example/catalog/widgets/body_widget/body_widget.dart'; import 'package:example/catalog/widgets/screen/fab_widget.dart'; import 'package:example/catalog/widgets/counter_widget/counter_widget.dart'; - - -import 'package:example/catalog/widgets/main_screen.dart'; - - - class CatalogComponent extends StatefulWidget { static String routeName = '/catalog'; - static GoRoute route = GoRoute( - path: CatalogComponent.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CatalogComponent(), - ), - routes: [ - - GoRoute( - path: MainScreenPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const MainScreenPreviewPreviewPageDummy(), - ), - routes: [ - - GoRoute( - path: MainScreenPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const MainScreenPreviewPreviewPageDummy(), - ), + static GoRoute route = GoRoute( + path: CatalogComponent.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CatalogComponent(), + ), + routes: [ + GoRoute( + path: MainScreenPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const MainScreenPreviewPreviewPageDummy(), ), - - - GoRoute( - path: BodyWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const BodyWidgetPreviewPreviewPageDummy(), - ), - routes: [ - - - - ], - ) - , GoRoute( - path: FabWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const FabWidgetPreviewPreviewPageDummy(), - ), - routes: [ - - - - ], - ) - , GoRoute( - path: CounterWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CounterWidgetPreviewPreviewPageDummy(), - ), - routes: [ - - - - ], - ) - - - ], - ) - - - ], - ) - ; + routes: [ + GoRoute( + path: MainScreenPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const MainScreenPreviewPreviewPageDummy(), + ), + ), + GoRoute( + path: BodyWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const BodyWidgetPreviewPreviewPageDummy(), + ), + routes: const [], + ), + GoRoute( + path: FabWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const FabWidgetPreviewPreviewPageDummy(), + ), + routes: const [], + ), + GoRoute( + path: CounterWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CounterWidgetPreviewPreviewPageDummy(), + ), + routes: const [], + ) + ], + ) + ], + ); const CatalogComponent({super.key}); @override @@ -92,9 +65,7 @@ class CatalogComponent extends StatefulWidget { } class CatalogComponentState extends State { - TreeController? treeController; - @override Widget build(BuildContext context) { @@ -167,5 +138,3 @@ class CatalogComponentState extends State { } } } - - \ No newline at end of file diff --git a/example/lib/catalog/widgets/body_widget/body_widget.dart b/example/lib/catalog/widgets/body_widget/body_widget.dart index 54eb25b..57f4c75 100644 --- a/example/lib/catalog/widgets/body_widget/body_widget.dart +++ b/example/lib/catalog/widgets/body_widget/body_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/body_widget.preview.dart'; class BodyWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'body_widget'; - + const BodyWidgetPreviewPreviewPageDummy({super.key}); @override - BodyWidgetPreviewPreviewPageDummyState createState() => BodyWidgetPreviewPreviewPageDummyState(); + BodyWidgetPreviewPreviewPageDummyState createState() => + BodyWidgetPreviewPreviewPageDummyState(); } -class BodyWidgetPreviewPreviewPageDummyState extends State { +class BodyWidgetPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const BodyWidgetPreview(); } } - \ No newline at end of file diff --git a/example/lib/catalog/widgets/counter_widget/counter_widget.dart b/example/lib/catalog/widgets/counter_widget/counter_widget.dart index 0d5e240..dc4cda2 100644 --- a/example/lib/catalog/widgets/counter_widget/counter_widget.dart +++ b/example/lib/catalog/widgets/counter_widget/counter_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/counter_widget.preview.dart'; class CounterWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'counter_widget'; - + const CounterWidgetPreviewPreviewPageDummy({super.key}); @override - CounterWidgetPreviewPreviewPageDummyState createState() => CounterWidgetPreviewPreviewPageDummyState(); + CounterWidgetPreviewPreviewPageDummyState createState() => + CounterWidgetPreviewPreviewPageDummyState(); } -class CounterWidgetPreviewPreviewPageDummyState extends State { +class CounterWidgetPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const CounterWidgetPreview(); } } - \ No newline at end of file diff --git a/example/lib/catalog/widgets/main_screen.dart b/example/lib/catalog/widgets/main_screen.dart index 8478f34..2435fa2 100644 --- a/example/lib/catalog/widgets/main_screen.dart +++ b/example/lib/catalog/widgets/main_screen.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/catalog/preview/main_screen.preview.dart'; class MainScreenPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'main_screen'; - + const MainScreenPreviewPreviewPageDummy({super.key}); @override - MainScreenPreviewPreviewPageDummyState createState() => MainScreenPreviewPreviewPageDummyState(); + MainScreenPreviewPreviewPageDummyState createState() => + MainScreenPreviewPreviewPageDummyState(); } -class MainScreenPreviewPreviewPageDummyState extends State { +class MainScreenPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const MainScreenPreview(); } } - \ No newline at end of file diff --git a/example/lib/catalog/widgets/screen/fab_widget.dart b/example/lib/catalog/widgets/screen/fab_widget.dart index 0ec2cc0..ec26c1d 100644 --- a/example/lib/catalog/widgets/screen/fab_widget.dart +++ b/example/lib/catalog/widgets/screen/fab_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/fab_widget.preview.dart'; class FabWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'screen'; - + const FabWidgetPreviewPreviewPageDummy({super.key}); @override - FabWidgetPreviewPreviewPageDummyState createState() => FabWidgetPreviewPreviewPageDummyState(); + FabWidgetPreviewPreviewPageDummyState createState() => + FabWidgetPreviewPreviewPageDummyState(); } -class FabWidgetPreviewPreviewPageDummyState extends State { +class FabWidgetPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const FabWidgetPreview(); } } - \ No newline at end of file diff --git a/example/lib/widgets/catalog/preview/main_screen.preview.dart b/example/lib/widgets/catalog/preview/main_screen.preview.dart index 93cff45..80e7116 100644 --- a/example/lib/widgets/catalog/preview/main_screen.preview.dart +++ b/example/lib/widgets/catalog/preview/main_screen.preview.dart @@ -11,10 +11,11 @@ import '../dummy/main_screen.dummy.dart'; 'infoText', 'counter', 'incrementCounter', - ],) + ], +) class MainScreenPreview extends ParentPreviewWidget { const MainScreenPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -99,20 +100,21 @@ class MainScreenPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < MainScreenDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => MainScreenDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return MainScreen(title: dummy.parameters['title'],infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],incrementCounter: dummy.parameters['incrementCounter'],); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => MainScreenDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return MainScreen( + title: dummy.parameters['title'], + infoText: dummy.parameters['infoText'], + counter: dummy.parameters['counter'], + incrementCounter: dummy.parameters['incrementCounter'], + ); + }, + ), ], ) ], ); } - - } - \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart index a95d74b..38de8a3 100644 --- a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart @@ -11,10 +11,11 @@ import '../dummy/body_widget.dummy.dart'; parameters: [ 'infoText', 'counter', - ],) + ], +) class BodyWidgetPreview extends ParentPreviewWidget { const BodyWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -99,20 +100,19 @@ class BodyWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < BodyWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => BodyWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return BodyWidget(infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => BodyWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return BodyWidget( + infoText: dummy.parameters['infoText'], + counter: dummy.parameters['counter'], + ); + }, + ), ], ) ], ); } - - } - \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart index cedd38f..8faac14 100644 --- a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart @@ -11,10 +11,11 @@ import '../dummy/counter_widget.dummy.dart'; description: 'Basic counter widget', parameters: [ 'counter', - ],) + ], +) class CounterWidgetPreview extends ParentPreviewWidget { const CounterWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -99,20 +100,18 @@ class CounterWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < CounterWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => CounterWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return CounterWidget(counter: dummy.parameters['counter'],); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => CounterWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return CounterWidget( + counter: dummy.parameters['counter'], + ); + }, + ), ], ) ], ); } - - } - \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart index 02b2700..0e863d0 100644 --- a/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart @@ -7,10 +7,11 @@ import '../dummy/fab_widget.dummy.dart'; @Preview( description: 'Basic fab widget', - parameters: ['incrementCounter'],) + parameters: ['incrementCounter'], +) class FabWidgetPreview extends ParentPreviewWidget { const FabWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -95,20 +96,18 @@ class FabWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < FabWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => FabWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return FabWidget(incrementCounter: dummy.parameters['incrementCounter'],); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => FabWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return FabWidget( + incrementCounter: dummy.parameters['incrementCounter'], + ); + }, + ), ], ) ], ); } - - } - \ No newline at end of file diff --git a/lib/src/bin/tasks/tasks/format_task.dart b/lib/src/bin/tasks/tasks/format_task.dart index d2a32b1..0e336c8 100644 --- a/lib/src/bin/tasks/tasks/format_task.dart +++ b/lib/src/bin/tasks/tasks/format_task.dart @@ -5,14 +5,6 @@ import '../base/base_task.dart'; class FormatTask extends BaseTask { @override Future work(List args) async { - var result = await Process.run( - 'dart', - ['format', 'lib/'], - workingDirectory: Directory.current.path, - ); - stdout.write(result.stdout); - stderr.write(result.stderr); - var resultFix = await Process.run( 'dart', ['fix', '--apply'], @@ -20,5 +12,13 @@ class FormatTask extends BaseTask { ); stdout.write(resultFix.stdout); stderr.write(resultFix.stderr); - } + + var result = await Process.run( + 'dart', + ['format', 'lib/'], + workingDirectory: Directory.current.path, + ); + stdout.write(result.stdout); + stderr.write(result.stderr); + } } From 6d20cf06605495e5a1cf06febac023f4cc275112 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Fri, 4 Oct 2024 01:04:43 +0200 Subject: [PATCH 06/28] Delete lib/src/.DS_Store --- lib/src/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 lib/src/.DS_Store diff --git a/lib/src/.DS_Store b/lib/src/.DS_Store deleted file mode 100644 index d94b6b045c5699432bd141a799c0cd175805d62f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHLJx{|h6nv&dgd!wH#&l-t3QItR5g`yeZBqeK(^Rxbh$$?rj4<&RSXkJZU}WOs zPawh0JwL0p+q8%UA>>!tm)PgL%ek?e5|LUvjw?h9L=>Pf7E7pdg8R9Q#FS}S1S)-v z9@VHvhm=x#gzX!=1KxqZ<^Vstb9ido_@sDt2hVS}wO`q3q)A647jDNhleAi`x6(Qo z!RBReqxN~fI*A?sfZaK;Rq#4RMXEz*mzu7^(u3V+Yg)P6T{;y_{jo_pP?6W4lQ%%# zW2|m1im6FQH003y74na8Y#qzjXX_WDBZoK8Gl}Qwijb0Kse!pmsH4~2CT6ndIx};V z&$6{WzrVbmi?*EW*=|i{y885dO~b7O-Zd$9bg4oax~yJXPc44>*cLqwW8hLg!^y9< z*q;(IpWwUA&UDT0G&FbgIF4s)D!)xfUD1?#P1~jKxQ z??B%HULQgf#>ikMsFw~@`V|0JM6(VY>op%3asx0jmqTn>*L@5-9i4$JK!DoR}QFR zb*H+9TQYm=$j$Ly8=~x?a4;_u)I(62?N}f1R?Pn^=s;h{2f)Z+CWsb<{~@4l@RfJq HR~`5QMQ`9u From b51e160d62b575af19a57f395597c2d90a59f3f3 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Fri, 4 Oct 2024 01:05:05 +0200 Subject: [PATCH 07/28] Delete lib/.DS_Store --- lib/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 lib/.DS_Store diff --git a/lib/.DS_Store b/lib/.DS_Store deleted file mode 100644 index 013242b1fc20da1c3fa2f024ff5b110a8ab8f1f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}N6?5Kh`^Q$*-NK|BS#D%M{VFKewnfGc`Xsa?0|;&xNItv!^&K7jf_p1t@2 z-o1L)tIi~;R;nJg$P7%rWG0iJZ$q-f7~{p3zra|YF(yC}Q#mNU5cH!CNXlA90XdEl z*S%1A(7N^N1HH*Gj11tnOS70Y*s0g<|9)W*Hw%Rao=Rs%MzbO-#>BCEuG((1(rm@W zO5+e)drE~~uU_%?gKE2+pV(4Svl2wrh7Jh)Ds(wI2qIs#i>ej*v5s|(L*zuRoS*J= z<`$RM3bS&xu+p8Co%KbiFE6cjyE!pAGrzH0z6fiPx-ukkIB#0UE%x9VDt15N*@Anj zYUU*Jou>~^O_fUaq>9J;m)D!;yUl*D|AV)F-ZyGWLRfFUOSch)Dmnv8Z*}M;AqI#6 zVqo|fu(y;L8@{E{iiiPX;Ex%=`$2*tIu;Xy`s#o}rvQK%Fl&K2<`NhqEjktxgWv(- zCKS+wa+_js6ApH1`#Ba9gC?ADn|yFPGq)KE*R#X;Qg>(EF-RpbKn#3lAZ?m?eE+w< z&;LIMQHvNL2L2TTJX3N@Mc9&kTL(6WZ> Date: Fri, 4 Oct 2024 01:06:27 +0200 Subject: [PATCH 08/28] feature: removed DS_Store --- .pubignore | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.pubignore b/.pubignore index f199644..3fe9667 100644 --- a/.pubignore +++ b/.pubignore @@ -3,6 +3,9 @@ widget_preview.iml *.lock .dart_tool .DS_Store -lib/.DS_Store -lib/src/.DS_Store .idea/ + +/lib/.DS_Store +/lib/src/.DS_Store +/example/lib/.DS_Store +/example/lib/src/.DS_Store From 771fb6c428a9f13e89c314e2eda1f30455674ded Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 00:42:05 +0200 Subject: [PATCH 09/28] feature: navigation over real locations working :rocket: --- example/assets/preview_config.json | 129 ++++------ example/lib/catalog/catalog_component.dart | 221 +++++++++--------- example/lib/catalog/widgets/main_screen.dart | 10 +- .../{body_widget => screen}/body_widget.dart | 10 +- .../counter_widget.dart | 10 +- .../catalog/widgets/screen/fab_widget.dart | 10 +- .../catalog/preview/main_screen.preview.dart | 35 +-- example/lib/widgets/screen/body_widget.dart | 2 - .../catalog/preview/body_widget.preview.dart | 35 +-- .../preview/counter_widget.preview.dart | 34 +-- .../catalog/preview/fab_widget.preview.dart | 32 ++- .../lib/widgets/screen/counter_widget.dart | 2 - lib/catalog.dart | 1 + .../bin/catalog_builder/catalog_builder.dart | 78 ++++++- .../bin/preview_builder/preview_builder.dart | 8 + lib/src/bin/tasks/tasks/catalog_task.dart | 132 +++-------- lib/src/bin/tasks/tasks/format_task.dart | 2 +- lib/src/bin/tasks/tasks/preview_task.dart | 1 + lib/src/builders/catalog/built_component.dart | 6 + lib/src/builders/catalog/component_node.dart | 101 ++++---- lib/src/builders/catalog/drawer_preview.dart | 67 ++---- .../builders/catalog/preview_scaffold.dart | 12 +- lib/src/builders/catalog/tree_element.dart | 8 - .../catalog/tree_elements_builder.dart | 59 +++++ .../preview/parent_preview_widget.dart | 7 +- 25 files changed, 516 insertions(+), 496 deletions(-) rename example/lib/catalog/widgets/{body_widget => screen}/body_widget.dart (67%) rename example/lib/catalog/widgets/{counter_widget => screen}/counter_widget.dart (67%) delete mode 100644 lib/src/builders/catalog/tree_element.dart create mode 100644 lib/src/builders/catalog/tree_elements_builder.dart diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index de912b8..5607fa4 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -1,38 +1,14 @@ { "id": "catalog", "route": "/", - "builtComponent": { - "path": "./lib/catalog/catalog_component.dart", - "route": "", - "package": "package:example/catalog/catalog_component.dart", - "clazzName": "CatalogComponent", - "preview": null - }, "builtComponents": {}, "children": { "widgets": { "id": "widgets", - "route": "/widgets", - "builtComponent": { - "path": "./lib/catalog/widgets/main_screen.dart", - "route": "widgets", - "package": "package:example/catalog/widgets/main_screen.dart", - "clazzName": "MainScreenPreviewPreviewPageDummy", - "preview": { - "id": "main_screen", - "path": "widgets", - "description": "", - "parameters": [ - "title", - "infoText", - "counter", - "incrementCounter" - ] - } - }, + "route": "widgets", "builtComponents": { - "/main_screen.dart": { - "path": "./lib/catalog/widgets/main_screen.dart", + "./example/lib/catalog/widgets/main_screen.dart": { + "path": "./example/lib/catalog/widgets/main_screen.dart", "route": "widgets", "package": "package:example/catalog/widgets/main_screen.dart", "clazzName": "MainScreenPreviewPreviewPageDummy", @@ -50,65 +26,54 @@ } }, "children": { - "body_widget": { - "id": "body_widget", - "route": "/body_widget", - "builtComponent": { - "path": "./lib/catalog/widgets/body_widget/body_widget.dart", - "route": "widgets/body_widget", - "package": "package:example/catalog/widgets/body_widget/body_widget.dart", - "clazzName": "BodyWidgetPreviewPreviewPageDummy", - "preview": { - "id": "BodyWidgetPreview", - "path": "widgets/body_widget", - "description": "", - "parameters": [ - "infoText", - "counter" - ] - } - }, - "builtComponents": {}, - "children": {} - }, "screen": { "id": "screen", - "route": "/screen", - "builtComponent": { - "path": "./lib/catalog/widgets/screen/fab_widget.dart", - "route": "widgets/screen", - "package": "package:example/catalog/widgets/screen/fab_widget.dart", - "clazzName": "FabWidgetPreviewPreviewPageDummy", - "preview": { - "id": "fab_widget", - "path": "widgets/screen", - "description": "Basic fab widget", - "parameters": [ - "incrementCounter" - ] - } - }, - "builtComponents": {}, - "children": {} - }, - "counter_widget": { - "id": "counter_widget", - "route": "/counter_widget", - "builtComponent": { - "path": "./lib/catalog/widgets/counter_widget/counter_widget.dart", - "route": "widgets/counter_widget", - "package": "package:example/catalog/widgets/counter_widget/counter_widget.dart", - "clazzName": "CounterWidgetPreviewPreviewPageDummy", - "preview": { - "id": "CounterWidgetPreview", - "path": "widgets/counter_widget", - "description": "Basic counter widget", - "parameters": [ - "counter" - ] + "route": "widgets/screen", + "builtComponents": { + "./example/lib/catalog/widgets/screen/body_widget.dart": { + "path": "./example/lib/catalog/widgets/screen/body_widget.dart", + "route": "widgets/screen", + "package": "package:example/catalog/widgets/screen/body_widget.dart", + "clazzName": "BodyWidgetPreviewPreviewPageDummy", + "preview": { + "id": "body_widget", + "path": "widgets/screen", + "description": "", + "parameters": [ + "infoText", + "counter" + ] + } + }, + "./example/lib/catalog/widgets/screen/fab_widget.dart": { + "path": "./example/lib/catalog/widgets/screen/fab_widget.dart", + "route": "widgets/screen", + "package": "package:example/catalog/widgets/screen/fab_widget.dart", + "clazzName": "FabWidgetPreviewPreviewPageDummy", + "preview": { + "id": "fab_widget", + "path": "widgets/screen", + "description": "Basic fab widget", + "parameters": [ + "incrementCounter" + ] + } + }, + "./example/lib/catalog/widgets/screen/counter_widget.dart": { + "path": "./example/lib/catalog/widgets/screen/counter_widget.dart", + "route": "widgets/screen", + "package": "package:example/catalog/widgets/screen/counter_widget.dart", + "clazzName": "CounterWidgetPreviewPreviewPageDummy", + "preview": { + "id": "counter_widget", + "path": "widgets/screen", + "description": "Basic counter widget", + "parameters": [ + "counter" + ] + } } }, - "builtComponents": {}, "children": {} } } diff --git a/example/lib/catalog/catalog_component.dart b/example/lib/catalog/catalog_component.dart index 5cd8b22..7911280 100644 --- a/example/lib/catalog/catalog_component.dart +++ b/example/lib/catalog/catalog_component.dart @@ -2,62 +2,95 @@ import 'package:flutter/material.dart'; import 'package:catalog/catalog.dart'; + + +import 'package:example/catalog/widgets/screen/body_widget.dart';import 'package:example/catalog/widgets/screen/fab_widget.dart';import 'package:example/catalog/widgets/screen/counter_widget.dart'; + + + import 'package:example/catalog/widgets/main_screen.dart'; -import 'package:example/catalog/widgets/body_widget/body_widget.dart'; -import 'package:example/catalog/widgets/screen/fab_widget.dart'; -import 'package:example/catalog/widgets/counter_widget/counter_widget.dart'; + + + + + + class CatalogComponent extends StatefulWidget { static String routeName = '/catalog'; - static GoRoute route = GoRoute( - path: CatalogComponent.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CatalogComponent(), - ), - routes: [ - GoRoute( - path: MainScreenPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const MainScreenPreviewPreviewPageDummy(), - ), - routes: [ - GoRoute( - path: MainScreenPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const MainScreenPreviewPreviewPageDummy(), - ), + + static GoRoute route = GoRoute( + path: CatalogComponent.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CatalogComponent(), + ), + routes: [ + GoRoute( + path: 'widgets', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + + GoRoute( + path: MainScreenPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const MainScreenPreviewPreviewPageDummy(), ), - GoRoute( - path: BodyWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const BodyWidgetPreviewPreviewPageDummy(), - ), - routes: const [], + ) + + + , + GoRoute( + path: 'screen', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + + GoRoute( + path: BodyWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const BodyWidgetPreviewPreviewPageDummy(), ), - GoRoute( - path: FabWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const FabWidgetPreviewPreviewPageDummy(), - ), - routes: const [], + ) + + , + GoRoute( + path: FabWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const FabWidgetPreviewPreviewPageDummy(), ), - GoRoute( - path: CounterWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CounterWidgetPreviewPreviewPageDummy(), - ), - routes: const [], - ) - ], + ) + + , + GoRoute( + path: CounterWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CounterWidgetPreviewPreviewPageDummy(), + ), + ) + + + , + + ], + ) + + ], + ) + + ], ) - ], - ); +; + const CatalogComponent({super.key}); @override @@ -65,76 +98,34 @@ class CatalogComponent extends StatefulWidget { } class CatalogComponentState extends State { - TreeController? treeController; @override Widget build(BuildContext context) { - return PreviewScaffold( - onBackPressed: Catalog().onBackPressed, - child: FutureBuilder( - initialData: null, - future: Catalog().get(context), - builder: (context, data) { - if (!data.hasData || data.data == null) { - return Container(); - } - final node = data.data as ComponentNode; - if (treeController == null) { - treeController = TreeController( - roots: [node], - childrenProvider: (ComponentNode node) => node.children.values, - ); - if (treeController!.isTreeCollapsed) { - treeController!.expandAll(); - } - } - return AnimatedTreeView( - treeController: treeController!, - nodeBuilder: - (BuildContext context, TreeEntry entry) { - return InkWell( - onTap: () { - // _nodePressed(node); - }, - child: TreeIndentation( - entry: entry, - child: Row( - children: [ - FolderButton( - color: Colors.black, - isOpen: entry.hasChildren ? entry.isExpanded : null, - onPressed: () => _nodePressed(entry), - ), - Text( - entry.node.id, - style: const TextStyle( - color: Colors.black, - fontSize: 16, - letterSpacing: .3, - ), - ), - ], - ), - ), - ); - }, - ); - }), + return FutureBuilder( + initialData: null, + future: Catalog().get(context), + builder: (context, data) { + if (!data.hasData || data.data == null) { + return Container(); + } + final node = data.data as ComponentNode; + return PreviewScaffold( + basePath: CatalogComponent.routeName, + onBackPressed: Catalog().onBackPressed, + child: ListView( + children: [ + buildTreeWidget( + context, + CatalogComponent.routeName, + node, + 0, + ) + ], + ), + ); + }, ); } - - void _nodePressed(TreeEntry entry) { - if (entry.node.children.isEmpty) { - if (entry.node.builtComponent?.preview?.path != null) { - context.go( - '${CatalogComponent.routeName}/${entry.node.builtComponent!.preview!.path}'); - } - } else { - if (!entry.isExpanded) { - treeController?.toggleExpansion(entry.node); - } else { - treeController?.collapse(entry.node); - } - } - } } + + \ No newline at end of file diff --git a/example/lib/catalog/widgets/main_screen.dart b/example/lib/catalog/widgets/main_screen.dart index 2435fa2..8478f34 100644 --- a/example/lib/catalog/widgets/main_screen.dart +++ b/example/lib/catalog/widgets/main_screen.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/catalog/preview/main_screen.preview.dart'; class MainScreenPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'main_screen'; + static String routeName = 'main_screen'; + const MainScreenPreviewPreviewPageDummy({super.key}); @override - MainScreenPreviewPreviewPageDummyState createState() => - MainScreenPreviewPreviewPageDummyState(); + MainScreenPreviewPreviewPageDummyState createState() => MainScreenPreviewPreviewPageDummyState(); } -class MainScreenPreviewPreviewPageDummyState - extends State { +class MainScreenPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const MainScreenPreview(); } } + \ No newline at end of file diff --git a/example/lib/catalog/widgets/body_widget/body_widget.dart b/example/lib/catalog/widgets/screen/body_widget.dart similarity index 67% rename from example/lib/catalog/widgets/body_widget/body_widget.dart rename to example/lib/catalog/widgets/screen/body_widget.dart index 57f4c75..54eb25b 100644 --- a/example/lib/catalog/widgets/body_widget/body_widget.dart +++ b/example/lib/catalog/widgets/screen/body_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/body_widget.preview.dart'; class BodyWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'body_widget'; + static String routeName = 'body_widget'; + const BodyWidgetPreviewPreviewPageDummy({super.key}); @override - BodyWidgetPreviewPreviewPageDummyState createState() => - BodyWidgetPreviewPreviewPageDummyState(); + BodyWidgetPreviewPreviewPageDummyState createState() => BodyWidgetPreviewPreviewPageDummyState(); } -class BodyWidgetPreviewPreviewPageDummyState - extends State { +class BodyWidgetPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const BodyWidgetPreview(); } } + \ No newline at end of file diff --git a/example/lib/catalog/widgets/counter_widget/counter_widget.dart b/example/lib/catalog/widgets/screen/counter_widget.dart similarity index 67% rename from example/lib/catalog/widgets/counter_widget/counter_widget.dart rename to example/lib/catalog/widgets/screen/counter_widget.dart index dc4cda2..0d5e240 100644 --- a/example/lib/catalog/widgets/counter_widget/counter_widget.dart +++ b/example/lib/catalog/widgets/screen/counter_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/counter_widget.preview.dart'; class CounterWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'counter_widget'; + static String routeName = 'counter_widget'; + const CounterWidgetPreviewPreviewPageDummy({super.key}); @override - CounterWidgetPreviewPreviewPageDummyState createState() => - CounterWidgetPreviewPreviewPageDummyState(); + CounterWidgetPreviewPreviewPageDummyState createState() => CounterWidgetPreviewPreviewPageDummyState(); } -class CounterWidgetPreviewPreviewPageDummyState - extends State { +class CounterWidgetPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const CounterWidgetPreview(); } } + \ No newline at end of file diff --git a/example/lib/catalog/widgets/screen/fab_widget.dart b/example/lib/catalog/widgets/screen/fab_widget.dart index ec26c1d..23f91ac 100644 --- a/example/lib/catalog/widgets/screen/fab_widget.dart +++ b/example/lib/catalog/widgets/screen/fab_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/fab_widget.preview.dart'; class FabWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'screen'; + static String routeName = 'fab_widget'; + const FabWidgetPreviewPreviewPageDummy({super.key}); @override - FabWidgetPreviewPreviewPageDummyState createState() => - FabWidgetPreviewPreviewPageDummyState(); + FabWidgetPreviewPreviewPageDummyState createState() => FabWidgetPreviewPreviewPageDummyState(); } -class FabWidgetPreviewPreviewPageDummyState - extends State { +class FabWidgetPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const FabWidgetPreview(); } } + \ No newline at end of file diff --git a/example/lib/widgets/catalog/preview/main_screen.preview.dart b/example/lib/widgets/catalog/preview/main_screen.preview.dart index 80e7116..f10f0ac 100644 --- a/example/lib/widgets/catalog/preview/main_screen.preview.dart +++ b/example/lib/widgets/catalog/preview/main_screen.preview.dart @@ -11,11 +11,17 @@ import '../dummy/main_screen.dummy.dart'; 'infoText', 'counter', 'incrementCounter', - ], -) + ],) class MainScreenPreview extends ParentPreviewWidget { + + @override + String get title => 'main_screen'; + + @override + String get basePath => '/catalog'; + const MainScreenPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -100,21 +106,20 @@ class MainScreenPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < MainScreenDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => MainScreenDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return MainScreen( - title: dummy.parameters['title'], - infoText: dummy.parameters['infoText'], - counter: dummy.parameters['counter'], - incrementCounter: dummy.parameters['incrementCounter'], - ); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => MainScreenDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return MainScreen(title: dummy.parameters['title'],infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],incrementCounter: dummy.parameters['incrementCounter'],); + }, + ), + ], ) ], ); } + + } + \ No newline at end of file diff --git a/example/lib/widgets/screen/body_widget.dart b/example/lib/widgets/screen/body_widget.dart index 4236a59..ce78232 100644 --- a/example/lib/widgets/screen/body_widget.dart +++ b/example/lib/widgets/screen/body_widget.dart @@ -4,8 +4,6 @@ import 'package:flutter/material.dart'; import 'counter_widget.dart'; @Preview( - id: 'BodyWidgetPreview', - path: 'widgets/body_widget', parameters: [ 'infoText', 'counter', diff --git a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart index 38de8a3..76d3689 100644 --- a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart @@ -6,16 +6,20 @@ import 'package:example/widgets/screen/body_widget.dart'; import '../dummy/body_widget.dummy.dart'; @Preview( - id: 'BodyWidgetPreview', - path: 'widgets/body_widget', parameters: [ 'infoText', 'counter', - ], -) + ],) class BodyWidgetPreview extends ParentPreviewWidget { + + @override + String get title => 'body_widget'; + + @override + String get basePath => '/catalog'; + const BodyWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -100,19 +104,20 @@ class BodyWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < BodyWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => BodyWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return BodyWidget( - infoText: dummy.parameters['infoText'], - counter: dummy.parameters['counter'], - ); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => BodyWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return BodyWidget(infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],); + }, + ), + ], ) ], ); } + + } + \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart index 8faac14..ef8888b 100644 --- a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart @@ -6,16 +6,20 @@ import 'package:example/widgets/screen/counter_widget.dart'; import '../dummy/counter_widget.dummy.dart'; @Preview( - id: 'CounterWidgetPreview', - path: 'widgets/counter_widget', description: 'Basic counter widget', parameters: [ 'counter', - ], -) + ],) class CounterWidgetPreview extends ParentPreviewWidget { + + @override + String get title => 'counter_widget'; + + @override + String get basePath => '/catalog'; + const CounterWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -100,18 +104,20 @@ class CounterWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < CounterWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => CounterWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return CounterWidget( - counter: dummy.parameters['counter'], - ); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => CounterWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return CounterWidget(counter: dummy.parameters['counter'],); + }, + ), + ], ) ], ); } + + } + \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart index 0e863d0..4b97fd2 100644 --- a/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart @@ -7,11 +7,17 @@ import '../dummy/fab_widget.dummy.dart'; @Preview( description: 'Basic fab widget', - parameters: ['incrementCounter'], -) + parameters: ['incrementCounter'],) class FabWidgetPreview extends ParentPreviewWidget { + + @override + String get title => 'fab_widget'; + + @override + String get basePath => '/catalog'; + const FabWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -96,18 +102,20 @@ class FabWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < FabWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => FabWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return FabWidget( - incrementCounter: dummy.parameters['incrementCounter'], - ); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => FabWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return FabWidget(incrementCounter: dummy.parameters['incrementCounter'],); + }, + ), + ], ) ], ); } + + } + \ No newline at end of file diff --git a/example/lib/widgets/screen/counter_widget.dart b/example/lib/widgets/screen/counter_widget.dart index 635e869..16ca3b3 100644 --- a/example/lib/widgets/screen/counter_widget.dart +++ b/example/lib/widgets/screen/counter_widget.dart @@ -2,8 +2,6 @@ import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; @Preview( - id: 'CounterWidgetPreview', - path: 'widgets/counter_widget', description: 'Basic counter widget', parameters: [ 'counter', diff --git a/lib/catalog.dart b/lib/catalog.dart index 60f311b..f493228 100644 --- a/lib/catalog.dart +++ b/lib/catalog.dart @@ -18,6 +18,7 @@ export 'package:catalog/src/builders/preview/parent_preview_widget.dart'; export 'package:catalog/src/builders/preview/preview_boundary.dart'; export 'package:catalog/src/builders/dummy/preview_dummy.dart'; export 'package:catalog/src/builders/catalog/preview_scaffold.dart'; +export 'package:catalog/src/builders/catalog/tree_elements_builder.dart'; export 'package:catalog/src/builders/screenshots/background.dart'; export 'package:catalog/src/builders/screenshots/op/screenshot_process.dart'; export 'package:catalog/src/builders/screenshots/screenshot.dart'; diff --git a/lib/src/bin/catalog_builder/catalog_builder.dart b/lib/src/bin/catalog_builder/catalog_builder.dart index bb7ce20..7854507 100644 --- a/lib/src/bin/catalog_builder/catalog_builder.dart +++ b/lib/src/bin/catalog_builder/catalog_builder.dart @@ -29,8 +29,7 @@ Future createPage( try { var directory = Directory(outputPath); await directory.create(recursive: true); - var id = - preview.path.contains('/') ? preview.path.split('/').last : preview.id; + var id = preview.id; File file = File(outputPath + outputFile.replaceAll('.$prefix.', '.')); final clazzName = name.replaceAll('()', ''); @@ -169,6 +168,7 @@ class ${clazzName}State extends State<$clazzName> { } } +/* Future buildChildrenPages( String basePath, dynamic config, @@ -255,21 +255,77 @@ Future buildChildrenPages( return null; } } +*/ +ComponentNode buildTreeFromMap( + String pageRoute, + Map> componentsMap, +) { + // Nodo raíz del árbol + ComponentNode root = ComponentNode(id: pageRoute, route: '/'); + + // Función auxiliar para crear o encontrar un nodo dentro del árbol + ComponentNode findOrCreateNode( + ComponentNode current, + List pathParts, + String fullPath, + ) { + if (pathParts.isEmpty) { + return current; + } + + // Obtener el primer segmento del path y crear el nodo hijo si no existe + String part = pathParts.removeAt(0); + if (!current.children.containsKey(part)) { + current.children[part] = ComponentNode( + id: part, + route: fullPath.substring(0, fullPath.indexOf(part) + part.length), + ); + } + + // Recursivamente buscar o crear el siguiente nodo hijo + return findOrCreateNode(current.children[part]!, pathParts, fullPath); + } + + // Recorrer cada entrada del mapa y asignarla a su nodo correspondiente + componentsMap.forEach((path, builtComponents) { + // Dividir el path en sus partes, excluyendo la raíz '/' + List pathParts = + path.split('/').where((part) => part.isNotEmpty).toList(); + // Encontrar o crear el nodo adecuado para este path + ComponentNode currentNode = findOrCreateNode(root, pathParts, path); + + // Agregar los componentes del directorio actual al nodo correspondiente + for (var component in builtComponents) { + currentNode.builtComponents[component.path] = component; + } + }); + + return root; +} + +/* ComponentNode getNodesFrom( String pageRoute, - Map components, + Map> components, ) { var firstNode = ComponentNode(id: pageRoute, route: '/'); - for (var entity in components.values.toList()) { - print('======================================================='); - print('route: ${entity.route}'); - var parts = entity.route.split('/'); - if (parts.first == '.') { - parts.removeAt(0); + final pathLevels = components.entries.toList(); + + for (var entity in pathLevels) { + final pathLevel = entity.key; + final pagesInThatLevel = entity.value.toList(); + + for (var page in pagesInThatLevel) { + print('======================================================='); + print('route: ${page.route}'); + var parts = page.route.split('/'); + if (parts.first == '.') { + parts.removeAt(0); + } + addNode(firstNode, parts, 0, page); } - addNode(firstNode, parts, 0, entity); } return firstNode; @@ -311,3 +367,5 @@ void addNode( addNode(no, parts, index + 1, component); } } + + */ diff --git a/lib/src/bin/preview_builder/preview_builder.dart b/lib/src/bin/preview_builder/preview_builder.dart index 716fc76..fb2dca8 100644 --- a/lib/src/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/preview_builder/preview_builder.dart @@ -14,6 +14,7 @@ Future findClassName(String path) async { } Future generatePreview( + dynamic config, String srcPath, String classImport, String previewAnnotation, @@ -38,6 +39,13 @@ import '../dummy/$name.dummy.dart'; $previewAnnotation class ${clazz}Preview extends ParentPreviewWidget { + + @override + String get title => '$name'; + + @override + String get basePath => '/${config['pageRoute']}'; + const ${clazz}Preview({super.key}); @override diff --git a/lib/src/bin/tasks/tasks/catalog_task.dart b/lib/src/bin/tasks/tasks/catalog_task.dart index e1ec6ff..b5e8811 100644 --- a/lib/src/bin/tasks/tasks/catalog_task.dart +++ b/lib/src/bin/tasks/tasks/catalog_task.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io'; import 'package:catalog/src/base/serial.dart'; @@ -38,7 +39,7 @@ class CatalogTask extends BaseTask { } } - var map = {}; + var map = >{}; for (FileSystemEntity fileSystemEntity in files) { final File file = File(fileSystemEntity.path); @@ -50,7 +51,6 @@ class CatalogTask extends BaseTask { print('No class name found ${file.path}'); continue; } - //print('- Building preview of $className in $package'); var preview = await previewOnFile( base, @@ -63,8 +63,6 @@ class CatalogTask extends BaseTask { continue; } - // print('Preview: ${jsonEncode(preview.toJson())}'); - var outputFolder = './$base${config['base']}/${config['output']}/${preview.path}/'; @@ -81,37 +79,21 @@ class CatalogTask extends BaseTask { className, ); - if (build?.preview == null) { + if (build == null) { print('No build for $className'); continue; } - // print('Built: ${jsonEncode(build!.toJson())}'); - - print('${build!.preview!.path} with classname $className'); - map[build.preview!.path] = build; - } - ComponentNode? node = getNodesFrom(pageRoute, map); + print('Built: ${jsonEncode(build.toJson())}'); - print('node: ${node.childrenList.map((e) => e.id).join(', ')}'); - - node = await buildChildrenPages( - base, - config, - appId, - node, - '', - pageRoute, - 0, - ); - - if (node == null) { - return; + print('${build.route} with classname $className'); + if (map[build.route] == null) { + map[build.route] = []; + } + (map[build.route] as List).add(build); } - print('node 2: ${node.childrenList.map((e) => e.id).join(', ')}'); - - // print(node.toJson().toPrettyString()); + ComponentNode node = buildTreeFromMap(pageRoute, map); final File assetsConfig = File('./$base${config['runtimeConfigHolder']}'); assetsConfig.writeAsStringSync(node.toJson().toPrettyString()); @@ -130,7 +112,9 @@ ${node.imports} class $pageName extends StatefulWidget { static String routeName = '/$pageRoute'; + static GoRoute route = ${node.routerBuilder}; + const $pageName({super.key}); @override @@ -139,79 +123,33 @@ class $pageName extends StatefulWidget { class ${pageName}State extends State<$pageName> { - TreeController? treeController; - - @override Widget build(BuildContext context) { - return PreviewScaffold( - onBackPressed: Catalog().onBackPressed, - child: FutureBuilder( - initialData: null, - future: Catalog().get(context), - builder: (context, data) { - if (!data.hasData || data.data == null) { - return Container(); - } - final node = data.data as ComponentNode; - if (treeController == null) { - treeController = TreeController( - roots: [node], - childrenProvider: (ComponentNode node) => node.children.values, - ); - if (treeController!.isTreeCollapsed) { - treeController!.expandAll(); - } - } - return AnimatedTreeView( - treeController: treeController!, - nodeBuilder: - (BuildContext context, TreeEntry entry) { - return InkWell( - onTap: () { - // _nodePressed(node); - }, - child: TreeIndentation( - entry: entry, - child: Row( - children: [ - FolderButton( - color: Colors.black, - isOpen: entry.hasChildren ? entry.isExpanded : null, - onPressed: () => _nodePressed(entry), - ), - Text( - entry.node.id, - style: const TextStyle( - color: Colors.black, - fontSize: 16, - letterSpacing: .3, - ), - ), - ], - ), - ), - ); - }, - ); - }), + return FutureBuilder( + initialData: null, + future: Catalog().get(context), + builder: (context, data) { + if (!data.hasData || data.data == null) { + return Container(); + } + final node = data.data as ComponentNode; + return PreviewScaffold( + basePath: CatalogComponent.routeName, + onBackPressed: Catalog().onBackPressed, + child: ListView( + children: [ + buildTreeWidget( + context, + CatalogComponent.routeName, + node, + 0, + ) + ], + ), + ); + }, ); } - - void _nodePressed(TreeEntry entry) { - if (entry.node.children.isEmpty) { - if (entry.node.builtComponent?.preview?.path != null) { - context.go( - '\${$pageName.routeName}/\${entry.node.builtComponent!.preview!.path}'); - } - } else { - if (!entry.isExpanded) { - treeController?.toggleExpansion(entry.node); - } else { - treeController?.collapse(entry.node); - } - } - } } ''' diff --git a/lib/src/bin/tasks/tasks/format_task.dart b/lib/src/bin/tasks/tasks/format_task.dart index 0e336c8..a9d0723 100644 --- a/lib/src/bin/tasks/tasks/format_task.dart +++ b/lib/src/bin/tasks/tasks/format_task.dart @@ -20,5 +20,5 @@ class FormatTask extends BaseTask { ); stdout.write(result.stdout); stderr.write(result.stderr); - } + } } diff --git a/lib/src/bin/tasks/tasks/preview_task.dart b/lib/src/bin/tasks/tasks/preview_task.dart index cbc5a66..76aad6a 100644 --- a/lib/src/bin/tasks/tasks/preview_task.dart +++ b/lib/src/bin/tasks/tasks/preview_task.dart @@ -54,6 +54,7 @@ class PreviewTask extends BaseTask { if (preview == null) continue; await generatePreview( + config, file.path, classImport, previewAnnotation, diff --git a/lib/src/builders/catalog/built_component.dart b/lib/src/builders/catalog/built_component.dart index 64c2a77..8cf9251 100644 --- a/lib/src/builders/catalog/built_component.dart +++ b/lib/src/builders/catalog/built_component.dart @@ -8,6 +8,12 @@ class BuiltComponent extends Serial { String clazzName = ''; Preview? preview; + String get name { + if (!path.contains('/')) return path; + var parts = path.split('/'); + return parts.last; + } + BuiltComponent({ this.path = '', this.route = '', diff --git a/lib/src/builders/catalog/component_node.dart b/lib/src/builders/catalog/component_node.dart index 2b160e2..fc82785 100644 --- a/lib/src/builders/catalog/component_node.dart +++ b/lib/src/builders/catalog/component_node.dart @@ -1,13 +1,18 @@ -import 'dart:convert'; - import 'package:catalog/src/base/serial.dart'; import 'package:catalog/src/builders/catalog/built_component.dart'; class ComponentNode extends Serial { String id = ''; String route = ''; - BuiltComponent? builtComponent; + + String get routePath { + if (!route.contains('/')) return route; + var parts = route.split('/'); + return parts.last; + } + Map builtComponents = {}; + Map children = {}; List get builtComponentList => @@ -18,16 +23,12 @@ class ComponentNode extends Serial { ComponentNode({ this.id = '', this.route = '', - this.builtComponent, }); @override ComponentNode fromJson(Map json) { id = json['id'] ?? ''; route = json['route'] ?? ''; - if (json['builtComponent'] != null) { - builtComponent = BuiltComponent().fromJson(json['builtComponent'] ?? {}); - } builtComponents = Serial.fromComplexMap(json['builtComponents'] ?? {}); children = Serial.fromComplexMap(json['children'] ?? {}); @@ -44,25 +45,35 @@ class ComponentNode extends Serial { Map toJson() => { 'id': id, 'route': route, - 'builtComponent': builtComponent?.toJson(), 'builtComponents': builtComponents.isEmpty ? {} : Serial.toMap(builtComponents), 'children': children.isEmpty ? {} : Serial.toMap(children), }; String get routerBuilder { - for (var o in childrenList) { - print('routes builder: ${jsonEncode(o.toJson())}'); + if (route == '/') { + return ''' + GoRoute( + path: CatalogComponent.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CatalogComponent(), + ), + routes: [ + ${childrenList.map((e) => e.routerBuilder).toList().join(',')} + ], + ) +'''; } return ''' - GoRoute( - path: ${builtComponent?.clazzName}.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const ${builtComponent?.clazzName}(), - ), - routes: [ - ${builtComponentList.map((e) { + GoRoute( + path: '$routePath', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + ${builtComponentList.map((e) { return ''' GoRoute( @@ -71,41 +82,41 @@ class ComponentNode extends Serial { key: state.pageKey, child: const ${e.clazzName}(), ), - ), + ) + + '''; + }).toList().join(',')} + ${builtComponentList.isNotEmpty ? ',' : ''} + ${childrenList.map((e) => e.routerBuilder).toList().join(',')} + ], + ) + '''; + } + + String get routerBuilderB { + return ''' + ${builtComponentList.map((e) { + return ''' + + GoRoute( + path: ${e.clazzName}.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const ${e.clazzName}(), + ), + ) '''; }).toList().join(',')} ${childrenList.map((e) => e.routerBuilder).toList().join(',')} - - ], - ) '''; } String get imports { - String value = ''; - if (builtComponent == null) { - return value; - } - if (route == "/") { - value += '''${childrenList.map((e) => e.imports).toList().join('')}\n'''; - } else { - if (childrenList.isEmpty) { - print('adding import (single): ${builtComponent!.package}'); - value += '''import '${builtComponent!.package}';\n'''; - } else { - value += '''import '${builtComponent!.package}'; -${childrenList.map((e) { - print('adding import: ${e.imports}'); - return e.imports; - }).toList().join('')}\n - -${builtComponentList.map((e) { - print('adding import: ${e.package}'); - return 'import \'${e.package}\';'; - }).toList().join('')}\n'''; - } - } + String value = ''' +${childrenList.map((e) => e.imports).toList().join('')}\n +${builtComponentList.map((e) => 'import \'${e.package}\';').toList().join('')}\n + '''; return value; } } diff --git a/lib/src/builders/catalog/drawer_preview.dart b/lib/src/builders/catalog/drawer_preview.dart index 81f4048..d2c4798 100644 --- a/lib/src/builders/catalog/drawer_preview.dart +++ b/lib/src/builders/catalog/drawer_preview.dart @@ -3,10 +3,12 @@ import 'package:flutter/material.dart'; class DrawerPreview extends StatefulWidget { final void Function()? onBackPressed; + final String basePath; const DrawerPreview({ super.key, this.onBackPressed, + required this.basePath, }); @override @@ -15,7 +17,6 @@ class DrawerPreview extends StatefulWidget { class DrawerPreviewState extends State { ComponentNode? node; - TreeController? treeController; @override void initState() { @@ -23,22 +24,14 @@ class DrawerPreviewState extends State { Catalog().get(context).then((value) { if (value == null) return; node = value; - if (treeController == null) { - treeController = TreeController( - roots: [value], - childrenProvider: (ComponentNode node) => node.children.values, - ); - if (treeController!.isTreeCollapsed) { - treeController!.expandAll(); - } - } setState(() {}); }); } @override Widget build(BuildContext context) { - if (node == null || treeController == null) { + final n = node; + if (n == null) { return Container(); } var height = MediaQuery.of(context).size.height; @@ -75,53 +68,19 @@ class DrawerPreviewState extends State { ), SizedBox( height: height - 200, - child: AnimatedTreeView( - treeController: treeController!, - nodeBuilder: - (BuildContext context, TreeEntry entry) { - return InkWell( - onTap: () { - // _nodePressed(node); - }, - child: TreeIndentation( - entry: entry, - child: Row( - children: [ - FolderButton( - isOpen: entry.hasChildren ? entry.isExpanded : null, - onPressed: () => _nodePressed(node!, entry), - ), - Text( - entry.node.id, - style: const TextStyle( - fontSize: 16, - letterSpacing: .3, - ), - ), - ], - ), - ), - ); - }, + child: ListView( + children: [ + buildTreeWidget( + context, + widget.basePath, + n, + 0, + ) + ], ), ), ], ), ); } - - void _nodePressed(ComponentNode baseNode, TreeEntry entry) { - if (entry.node.children.isEmpty) { - if (entry.node.builtComponent?.preview?.path != null) { - context - .go('/${baseNode.id}/${entry.node.builtComponent!.preview!.path}'); - } - } else { - if (!entry.isExpanded) { - treeController?.toggleExpansion(entry.node); - } else { - treeController?.collapse(entry.node); - } - } - } } diff --git a/lib/src/builders/catalog/preview_scaffold.dart b/lib/src/builders/catalog/preview_scaffold.dart index bb45bff..3950baa 100644 --- a/lib/src/builders/catalog/preview_scaffold.dart +++ b/lib/src/builders/catalog/preview_scaffold.dart @@ -9,6 +9,7 @@ class PreviewScaffold extends StatelessWidget { final Widget child; final String? title; final void Function()? onBackPressed; + final String basePath; const PreviewScaffold({ super.key, @@ -16,14 +17,19 @@ class PreviewScaffold extends StatelessWidget { this.title, this.drawer, this.onBackPressed, + required this.basePath, }); @override Widget build(BuildContext context) { return Scaffold( - drawer: Drawer( - child: DrawerPreview( - onBackPressed: onBackPressed ?? Catalog().onBackPressed, + drawer: SizedBox( + width: 600.0, + child: Drawer( + child: DrawerPreview( + basePath: basePath, + onBackPressed: onBackPressed ?? Catalog().onBackPressed, + ), ), ), appBar: AppBar( diff --git a/lib/src/builders/catalog/tree_element.dart b/lib/src/builders/catalog/tree_element.dart deleted file mode 100644 index 2e89ded..0000000 --- a/lib/src/builders/catalog/tree_element.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:catalog/src/builders/catalog/built_component.dart'; - -class TreeElement { - BuiltComponent? component; - List children = []; - - TreeElement(); -} diff --git a/lib/src/builders/catalog/tree_elements_builder.dart b/lib/src/builders/catalog/tree_elements_builder.dart new file mode 100644 index 0000000..1b90227 --- /dev/null +++ b/lib/src/builders/catalog/tree_elements_builder.dart @@ -0,0 +1,59 @@ +import 'package:catalog/src/builders/catalog/component_node.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +Widget buildTreeWidget( + BuildContext context, + String basePath, + ComponentNode node, + int level, +) { + var padding = 32.0; + return Stack( + children: [ + Padding( + padding: EdgeInsets.only(left: level == 0 ? 0 : padding), + child: Theme( + data: Theme.of(context).copyWith( + dividerColor: Colors.transparent, + ), + child: ExpansionTile( + key: PageStorageKey(node.route), + initiallyExpanded: true, + leading: const Icon(Icons.folder), + iconColor: Colors.teal, + collapsedIconColor: Colors.grey, + title: Text(node.id.isNotEmpty ? node.id : 'Root'), + children: [ + ...node.builtComponentList.map( + (builtComponent) => Padding( + padding: EdgeInsets.only(left: padding), + child: ListTile( + title: Text(builtComponent.name), + leading: const Icon( + Icons.insert_drive_file, + ), + onTap: () { + final id = builtComponent.preview?.id; + if (id != null) { + context.go('$basePath/${builtComponent.route}/$id'); + } + }, + ), + ), + ), + ...node.childrenList.map( + (childNode) => buildTreeWidget( + context, + basePath, + childNode, + level + 1, + ), + ), + ], + ), + ), + ), + ], + ); +} diff --git a/lib/src/builders/preview/parent_preview_widget.dart b/lib/src/builders/preview/parent_preview_widget.dart index 55aca93..de9b6f2 100644 --- a/lib/src/builders/preview/parent_preview_widget.dart +++ b/lib/src/builders/preview/parent_preview_widget.dart @@ -6,6 +6,10 @@ abstract class ParentPreviewWidget extends StatelessWidget { bool get center => true; + String get title => 'preview_page'; + + String get basePath => '/catalog'; + const ParentPreviewWidget({super.key}); Widget preview(BuildContext context); @@ -13,7 +17,8 @@ abstract class ParentPreviewWidget extends StatelessWidget { @override Widget build(BuildContext context) { return PreviewScaffold( - title: runtimeType.toString(), + basePath: basePath, + title: title, child: Center( child: preview(context), ), From cd43854d89084548eba1fa5d7df580a8405d3edb Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 00:51:46 +0200 Subject: [PATCH 10/28] feature: added internal preview class --- example/assets/preview_config.json | 42 ++++++++---- example/lib/catalog/catalog_component.dart | 46 +++++++++++-- .../{screen => utils/bottom}/fab_widget.dart | 2 +- example/lib/widgets/main_screen.dart | 2 +- .../catalog/dummy/fab_widget.dummy.dart | 0 .../catalog/preview/fab_widget.preview.dart | 2 +- .../{screen => utils/bottom}/fab_widget.dart | 0 lib/src/annotations/internal_preview.dart | 66 +++++++++++++++++++ lib/src/base/serial.dart | 2 + .../bin/catalog_builder/catalog_builder.dart | 4 +- .../bin/preview_builder/preview_builder.dart | 6 +- lib/src/bin/utils/configuration.dart | 12 ++-- lib/src/builders/catalog/built_component.dart | 7 +- 13 files changed, 155 insertions(+), 36 deletions(-) rename example/lib/catalog/widgets/{screen => utils/bottom}/fab_widget.dart (86%) rename example/lib/widgets/{screen => utils/bottom}/catalog/dummy/fab_widget.dummy.dart (100%) rename example/lib/widgets/{screen => utils/bottom}/catalog/preview/fab_widget.preview.dart (98%) rename example/lib/widgets/{screen => utils/bottom}/fab_widget.dart (100%) create mode 100644 lib/src/annotations/internal_preview.dart diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index 5607fa4..6894852 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -26,6 +26,34 @@ } }, "children": { + "utils": { + "id": "utils", + "route": "widgets/utils", + "builtComponents": {}, + "children": { + "bottom": { + "id": "bottom", + "route": "widgets/utils/bottom", + "builtComponents": { + "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart": { + "path": "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart", + "route": "widgets/utils/bottom", + "package": "package:example/catalog/widgets/utils/bottom/fab_widget.dart", + "clazzName": "FabWidgetPreviewPreviewPageDummy", + "preview": { + "id": "fab_widget", + "path": "widgets/utils/bottom", + "description": "Basic fab widget", + "parameters": [ + "incrementCounter" + ] + } + } + }, + "children": {} + } + } + }, "screen": { "id": "screen", "route": "widgets/screen", @@ -45,20 +73,6 @@ ] } }, - "./example/lib/catalog/widgets/screen/fab_widget.dart": { - "path": "./example/lib/catalog/widgets/screen/fab_widget.dart", - "route": "widgets/screen", - "package": "package:example/catalog/widgets/screen/fab_widget.dart", - "clazzName": "FabWidgetPreviewPreviewPageDummy", - "preview": { - "id": "fab_widget", - "path": "widgets/screen", - "description": "Basic fab widget", - "parameters": [ - "incrementCounter" - ] - } - }, "./example/lib/catalog/widgets/screen/counter_widget.dart": { "path": "./example/lib/catalog/widgets/screen/counter_widget.dart", "route": "widgets/screen", diff --git a/example/lib/catalog/catalog_component.dart b/example/lib/catalog/catalog_component.dart index 7911280..bbed7f9 100644 --- a/example/lib/catalog/catalog_component.dart +++ b/example/lib/catalog/catalog_component.dart @@ -4,7 +4,15 @@ import 'package:flutter/material.dart'; import 'package:catalog/catalog.dart'; -import 'package:example/catalog/widgets/screen/body_widget.dart';import 'package:example/catalog/widgets/screen/fab_widget.dart';import 'package:example/catalog/widgets/screen/counter_widget.dart'; +import 'package:example/catalog/widgets/utils/bottom/fab_widget.dart'; + + + + + + + +import 'package:example/catalog/widgets/screen/body_widget.dart';import 'package:example/catalog/widgets/screen/counter_widget.dart'; @@ -45,7 +53,16 @@ class CatalogComponent extends StatefulWidget { , GoRoute( - path: 'screen', + path: 'utils', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + + + GoRoute( + path: 'bottom', redirect: (context, state) { if (state.fullPath != state.matchedLocation) return null; return CatalogComponent.routeName; @@ -53,19 +70,34 @@ class CatalogComponent extends StatefulWidget { routes: [ GoRoute( - path: BodyWidgetPreviewPreviewPageDummy.routeName, + path: FabWidgetPreviewPreviewPageDummy.routeName, pageBuilder: (context, state) => NoTransitionPage( key: state.pageKey, - child: const BodyWidgetPreviewPreviewPageDummy(), + child: const FabWidgetPreviewPreviewPageDummy(), ), ) - , + + , + + ], + ) + + ], + ) + , GoRoute( + path: 'screen', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( - path: FabWidgetPreviewPreviewPageDummy.routeName, + path: BodyWidgetPreviewPreviewPageDummy.routeName, pageBuilder: (context, state) => NoTransitionPage( key: state.pageKey, - child: const FabWidgetPreviewPreviewPageDummy(), + child: const BodyWidgetPreviewPreviewPageDummy(), ), ) diff --git a/example/lib/catalog/widgets/screen/fab_widget.dart b/example/lib/catalog/widgets/utils/bottom/fab_widget.dart similarity index 86% rename from example/lib/catalog/widgets/screen/fab_widget.dart rename to example/lib/catalog/widgets/utils/bottom/fab_widget.dart index 23f91ac..0fc351c 100644 --- a/example/lib/catalog/widgets/screen/fab_widget.dart +++ b/example/lib/catalog/widgets/utils/bottom/fab_widget.dart @@ -1,7 +1,7 @@ /// AUTOGENERATED FILE. DO NOT EDIT import 'package:flutter/material.dart'; -import 'package:example/widgets/screen/catalog/preview/fab_widget.preview.dart'; +import 'package:example/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart'; class FabWidgetPreviewPreviewPageDummy extends StatefulWidget { diff --git a/example/lib/widgets/main_screen.dart b/example/lib/widgets/main_screen.dart index bd4f88e..9809d36 100644 --- a/example/lib/widgets/main_screen.dart +++ b/example/lib/widgets/main_screen.dart @@ -2,7 +2,7 @@ import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; import 'screen/body_widget.dart'; -import 'screen/fab_widget.dart'; +import 'utils/bottom/fab_widget.dart'; @Preview( parameters: [ diff --git a/example/lib/widgets/screen/catalog/dummy/fab_widget.dummy.dart b/example/lib/widgets/utils/bottom/catalog/dummy/fab_widget.dummy.dart similarity index 100% rename from example/lib/widgets/screen/catalog/dummy/fab_widget.dummy.dart rename to example/lib/widgets/utils/bottom/catalog/dummy/fab_widget.dummy.dart diff --git a/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart similarity index 98% rename from example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart rename to example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart index 4b97fd2..d18edaa 100644 --- a/example/lib/widgets/screen/catalog/preview/fab_widget.preview.dart +++ b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart @@ -2,7 +2,7 @@ import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; -import 'package:example/widgets/screen/fab_widget.dart'; +import 'package:example/widgets/utils/bottom/fab_widget.dart'; import '../dummy/fab_widget.dummy.dart'; @Preview( diff --git a/example/lib/widgets/screen/fab_widget.dart b/example/lib/widgets/utils/bottom/fab_widget.dart similarity index 100% rename from example/lib/widgets/screen/fab_widget.dart rename to example/lib/widgets/utils/bottom/fab_widget.dart diff --git a/lib/src/annotations/internal_preview.dart b/lib/src/annotations/internal_preview.dart new file mode 100644 index 0000000..260dacc --- /dev/null +++ b/lib/src/annotations/internal_preview.dart @@ -0,0 +1,66 @@ +import 'dart:convert'; + +import 'package:catalog/src/base/serial.dart'; + +class InternalPreview implements Serial { + final String id; + final String path; + final String description; + final List parameters; + + const InternalPreview({ + this.id = '', + this.path = '', + this.description = '', + this.parameters = const [], + }); + + @override + InternalPreview fromJson(Map json) => InternalPreview( + id: json['id'] ?? '', + path: json['path'] ?? '', + description: json['description'] ?? '', + parameters: Serial.listObjectFromBasicType( + json['parameters'] ?? [], + ), + ); + + @override + String getId() => id; + + @override + InternalPreview instance() => const InternalPreview(id: '', path: ''); + + @override + Map toJson() => { + 'id': id, + 'path': path, + 'description': description, + 'parameters': parameters, + }; + + @override + InternalPreview fromString(String value) { + Map map = jsonDecode(value); + return fromJson(map); + } + + @override + String stringValue() { + var map = toJson(); + return jsonEncode(map); + } + + InternalPreview copyWith({ + String? id, + String? path, + String? description, + List? parameters, + }) => + InternalPreview( + id: id ?? this.id, + path: path ?? this.path, + description: description ?? this.description, + parameters: parameters ?? this.parameters, + ); +} diff --git a/lib/src/base/serial.dart b/lib/src/base/serial.dart index 8e0739f..25b6f35 100644 --- a/lib/src/base/serial.dart +++ b/lib/src/base/serial.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:catalog/src/annotations/internal_preview.dart'; import 'package:catalog/src/annotations/preview.dart'; import 'package:catalog/src/builders/catalog/built_component.dart'; import 'package:catalog/src/builders/catalog/component_node.dart'; @@ -79,6 +80,7 @@ abstract class Serial { ComponentNode(), BuiltComponent(), const Preview(id: '', path: ''), + const InternalPreview(id: '', path: ''), ]; static Map internalLinkerToMap(map) { diff --git a/lib/src/bin/catalog_builder/catalog_builder.dart b/lib/src/bin/catalog_builder/catalog_builder.dart index 7854507..4cb73d7 100644 --- a/lib/src/bin/catalog_builder/catalog_builder.dart +++ b/lib/src/bin/catalog_builder/catalog_builder.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:catalog/src/annotations/preview.dart'; +import 'package:catalog/src/annotations/internal_preview.dart'; import 'package:catalog/src/builders/catalog/built_component.dart'; import 'package:catalog/src/builders/catalog/component_node.dart'; import 'package:catalog/src/extensions/string_ext.dart'; @@ -22,7 +22,7 @@ Future createPage( String outputPath, String outputFile, String prefix, - Preview preview, + InternalPreview preview, String import, String name, ) async { diff --git a/lib/src/bin/preview_builder/preview_builder.dart b/lib/src/bin/preview_builder/preview_builder.dart index fb2dca8..86fc331 100644 --- a/lib/src/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/preview_builder/preview_builder.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:catalog/src/annotations/preview.dart'; +import 'package:catalog/src/annotations/internal_preview.dart'; Future findClassName(String path) async { try { @@ -20,7 +20,7 @@ Future generatePreview( String previewAnnotation, String className, String prefix, - Preview preview, + InternalPreview preview, ) async { var clazz = className.replaceAll('()', ''); @@ -168,7 +168,7 @@ String dummyWidgetBuilder(String clazz, String widgetCompose) { '''; } -String dummyWidgetContent(String className, Preview preview) { +String dummyWidgetContent(String className, InternalPreview preview) { var clazz = className.replaceAll('()', ''); var widgetCompose = '$clazz('; diff --git a/lib/src/bin/utils/configuration.dart b/lib/src/bin/utils/configuration.dart index 73f8c69..cc3be26 100644 --- a/lib/src/bin/utils/configuration.dart +++ b/lib/src/bin/utils/configuration.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'dart:io'; -import 'package:catalog/src/annotations/preview.dart'; +import 'package:catalog/src/annotations/internal_preview.dart'; import 'package:yaml/yaml.dart'; import 'exceptions.dart'; @@ -74,7 +74,7 @@ String loadId(String basePath) { return yamlMap[nammeId]; } -Future previewOnFile( +Future previewOnFile( String basePath, dynamic config, String originalFilePath, @@ -172,8 +172,12 @@ void main(List arguments) async { var path = file.absolute.path; var result = await Process.run('dart', ['run', path]); - var preview = - const Preview(id: '', path: '').fromJson(jsonDecode(result.stdout)); + var preview = const InternalPreview( + id: '', + path: '', + ).fromJson( + jsonDecode(result.stdout), + ); if (preview.id.isEmpty) { preview = preview.copyWith( diff --git a/lib/src/builders/catalog/built_component.dart b/lib/src/builders/catalog/built_component.dart index 8cf9251..3024bb1 100644 --- a/lib/src/builders/catalog/built_component.dart +++ b/lib/src/builders/catalog/built_component.dart @@ -1,4 +1,4 @@ -import 'package:catalog/src/annotations/preview.dart'; +import 'package:catalog/src/annotations/internal_preview.dart'; import 'package:catalog/src/base/serial.dart'; class BuiltComponent extends Serial { @@ -6,7 +6,7 @@ class BuiltComponent extends Serial { String route = ''; String package = ''; String clazzName = ''; - Preview? preview; + InternalPreview? preview; String get name { if (!path.contains('/')) return path; @@ -35,7 +35,8 @@ class BuiltComponent extends Serial { package = json['package'] ?? ''; clazzName = json['clazzName'] ?? ''; if (json['preview'] != null) { - preview = const Preview(id: '', path: '').fromJson(json['preview'] ?? {}); + preview = const InternalPreview(id: '', path: '') + .fromJson(json['preview'] ?? {}); } return this; } From 0682c18dd1d35685c332225c0d81b57622d32e24 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 01:16:39 +0200 Subject: [PATCH 11/28] feature: removed prints and unused code --- example/assets/preview_config.json | 16 +- example/lib/catalog/catalog_component.dart | 187 +++++-------- example/lib/catalog/widgets/main_screen.dart | 10 +- .../catalog/widgets/screen/body_widget.dart | 10 +- .../widgets/screen/counter_widget.dart | 10 +- .../widgets/utils/bottom/fab_widget.dart | 10 +- .../catalog/preview/main_screen.preview.dart | 33 +-- .../catalog/preview/body_widget.preview.dart | 31 ++- .../preview/counter_widget.preview.dart | 30 +-- .../catalog/preview/fab_widget.preview.dart | 30 +-- lib/src/annotations/preview.dart | 16 +- lib/src/base/serial.dart | 2 +- .../bin/catalog_builder/catalog_builder.dart | 252 ------------------ lib/src/bin/tasks/tasks/catalog_task.dart | 18 +- lib/src/bin/tasks/tasks/preview_task.dart | 1 - lib/src/bin/utils/configuration.dart | 22 +- test/catalog_test.dart | 55 ++-- 17 files changed, 213 insertions(+), 520 deletions(-) diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index 6894852..2d995cd 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -7,8 +7,8 @@ "id": "widgets", "route": "widgets", "builtComponents": { - "./example/lib/catalog/widgets/main_screen.dart": { - "path": "./example/lib/catalog/widgets/main_screen.dart", + "./lib/catalog/widgets/main_screen.dart": { + "path": "./lib/catalog/widgets/main_screen.dart", "route": "widgets", "package": "package:example/catalog/widgets/main_screen.dart", "clazzName": "MainScreenPreviewPreviewPageDummy", @@ -35,8 +35,8 @@ "id": "bottom", "route": "widgets/utils/bottom", "builtComponents": { - "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart": { - "path": "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart", + "./lib/catalog/widgets/utils/bottom/fab_widget.dart": { + "path": "./lib/catalog/widgets/utils/bottom/fab_widget.dart", "route": "widgets/utils/bottom", "package": "package:example/catalog/widgets/utils/bottom/fab_widget.dart", "clazzName": "FabWidgetPreviewPreviewPageDummy", @@ -58,8 +58,8 @@ "id": "screen", "route": "widgets/screen", "builtComponents": { - "./example/lib/catalog/widgets/screen/body_widget.dart": { - "path": "./example/lib/catalog/widgets/screen/body_widget.dart", + "./lib/catalog/widgets/screen/body_widget.dart": { + "path": "./lib/catalog/widgets/screen/body_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/body_widget.dart", "clazzName": "BodyWidgetPreviewPreviewPageDummy", @@ -73,8 +73,8 @@ ] } }, - "./example/lib/catalog/widgets/screen/counter_widget.dart": { - "path": "./example/lib/catalog/widgets/screen/counter_widget.dart", + "./lib/catalog/widgets/screen/counter_widget.dart": { + "path": "./lib/catalog/widgets/screen/counter_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/counter_widget.dart", "clazzName": "CounterWidgetPreviewPreviewPageDummy", diff --git a/example/lib/catalog/catalog_component.dart b/example/lib/catalog/catalog_component.dart index bbed7f9..cd1871d 100644 --- a/example/lib/catalog/catalog_component.dart +++ b/example/lib/catalog/catalog_component.dart @@ -3,126 +3,90 @@ import 'package:flutter/material.dart'; import 'package:catalog/catalog.dart'; - import 'package:example/catalog/widgets/utils/bottom/fab_widget.dart'; - - - - - - -import 'package:example/catalog/widgets/screen/body_widget.dart';import 'package:example/catalog/widgets/screen/counter_widget.dart'; - - +import 'package:example/catalog/widgets/screen/body_widget.dart'; +import 'package:example/catalog/widgets/screen/counter_widget.dart'; import 'package:example/catalog/widgets/main_screen.dart'; - - - - - - class CatalogComponent extends StatefulWidget { static String routeName = '/catalog'; - - static GoRoute route = GoRoute( - path: CatalogComponent.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CatalogComponent(), - ), - routes: [ - GoRoute( - path: 'widgets', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - - GoRoute( - path: MainScreenPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const MainScreenPreviewPreviewPageDummy(), - ), - ) - - - , - GoRoute( - path: 'utils', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - - - GoRoute( - path: 'bottom', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - - GoRoute( - path: FabWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const FabWidgetPreviewPreviewPageDummy(), - ), - ) - - - , - - ], - ) - - ], - ) - , GoRoute( - path: 'screen', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - - GoRoute( - path: BodyWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const BodyWidgetPreviewPreviewPageDummy(), + + static GoRoute route = GoRoute( + path: CatalogComponent.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CatalogComponent(), + ), + routes: [ + GoRoute( + path: 'widgets', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: MainScreenPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const MainScreenPreviewPreviewPageDummy(), + ), ), - ) - - , - GoRoute( - path: CounterWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CounterWidgetPreviewPreviewPageDummy(), + GoRoute( + path: 'utils', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: 'bottom', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: FabWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const FabWidgetPreviewPreviewPageDummy(), + ), + ), + ], + ) + ], ), - ) - - - , - - ], - ) - - ], - ) - - ], + GoRoute( + path: 'screen', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: BodyWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const BodyWidgetPreviewPreviewPageDummy(), + ), + ), + GoRoute( + path: CounterWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CounterWidgetPreviewPreviewPageDummy(), + ), + ), + ], + ) + ], ) -; - + ], + ); + const CatalogComponent({super.key}); @override @@ -130,7 +94,6 @@ class CatalogComponent extends StatefulWidget { } class CatalogComponentState extends State { - @override Widget build(BuildContext context) { return FutureBuilder( @@ -159,5 +122,3 @@ class CatalogComponentState extends State { ); } } - - \ No newline at end of file diff --git a/example/lib/catalog/widgets/main_screen.dart b/example/lib/catalog/widgets/main_screen.dart index 8478f34..2435fa2 100644 --- a/example/lib/catalog/widgets/main_screen.dart +++ b/example/lib/catalog/widgets/main_screen.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/catalog/preview/main_screen.preview.dart'; class MainScreenPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'main_screen'; - + const MainScreenPreviewPreviewPageDummy({super.key}); @override - MainScreenPreviewPreviewPageDummyState createState() => MainScreenPreviewPreviewPageDummyState(); + MainScreenPreviewPreviewPageDummyState createState() => + MainScreenPreviewPreviewPageDummyState(); } -class MainScreenPreviewPreviewPageDummyState extends State { +class MainScreenPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const MainScreenPreview(); } } - \ No newline at end of file diff --git a/example/lib/catalog/widgets/screen/body_widget.dart b/example/lib/catalog/widgets/screen/body_widget.dart index 54eb25b..57f4c75 100644 --- a/example/lib/catalog/widgets/screen/body_widget.dart +++ b/example/lib/catalog/widgets/screen/body_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/body_widget.preview.dart'; class BodyWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'body_widget'; - + const BodyWidgetPreviewPreviewPageDummy({super.key}); @override - BodyWidgetPreviewPreviewPageDummyState createState() => BodyWidgetPreviewPreviewPageDummyState(); + BodyWidgetPreviewPreviewPageDummyState createState() => + BodyWidgetPreviewPreviewPageDummyState(); } -class BodyWidgetPreviewPreviewPageDummyState extends State { +class BodyWidgetPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const BodyWidgetPreview(); } } - \ No newline at end of file diff --git a/example/lib/catalog/widgets/screen/counter_widget.dart b/example/lib/catalog/widgets/screen/counter_widget.dart index 0d5e240..dc4cda2 100644 --- a/example/lib/catalog/widgets/screen/counter_widget.dart +++ b/example/lib/catalog/widgets/screen/counter_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/counter_widget.preview.dart'; class CounterWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'counter_widget'; - + const CounterWidgetPreviewPreviewPageDummy({super.key}); @override - CounterWidgetPreviewPreviewPageDummyState createState() => CounterWidgetPreviewPreviewPageDummyState(); + CounterWidgetPreviewPreviewPageDummyState createState() => + CounterWidgetPreviewPreviewPageDummyState(); } -class CounterWidgetPreviewPreviewPageDummyState extends State { +class CounterWidgetPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const CounterWidgetPreview(); } } - \ No newline at end of file diff --git a/example/lib/catalog/widgets/utils/bottom/fab_widget.dart b/example/lib/catalog/widgets/utils/bottom/fab_widget.dart index 0fc351c..5b10f36 100644 --- a/example/lib/catalog/widgets/utils/bottom/fab_widget.dart +++ b/example/lib/catalog/widgets/utils/bottom/fab_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart'; class FabWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'fab_widget'; - + const FabWidgetPreviewPreviewPageDummy({super.key}); @override - FabWidgetPreviewPreviewPageDummyState createState() => FabWidgetPreviewPreviewPageDummyState(); + FabWidgetPreviewPreviewPageDummyState createState() => + FabWidgetPreviewPreviewPageDummyState(); } -class FabWidgetPreviewPreviewPageDummyState extends State { +class FabWidgetPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const FabWidgetPreview(); } } - \ No newline at end of file diff --git a/example/lib/widgets/catalog/preview/main_screen.preview.dart b/example/lib/widgets/catalog/preview/main_screen.preview.dart index f10f0ac..16f0169 100644 --- a/example/lib/widgets/catalog/preview/main_screen.preview.dart +++ b/example/lib/widgets/catalog/preview/main_screen.preview.dart @@ -11,17 +11,17 @@ import '../dummy/main_screen.dummy.dart'; 'infoText', 'counter', 'incrementCounter', - ],) + ], +) class MainScreenPreview extends ParentPreviewWidget { - @override String get title => 'main_screen'; - + @override String get basePath => '/catalog'; - + const MainScreenPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -106,20 +106,21 @@ class MainScreenPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < MainScreenDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => MainScreenDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return MainScreen(title: dummy.parameters['title'],infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],incrementCounter: dummy.parameters['incrementCounter'],); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => MainScreenDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return MainScreen( + title: dummy.parameters['title'], + infoText: dummy.parameters['infoText'], + counter: dummy.parameters['counter'], + incrementCounter: dummy.parameters['incrementCounter'], + ); + }, + ), ], ) ], ); } - - } - \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart index 76d3689..47dc8ff 100644 --- a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart @@ -9,17 +9,17 @@ import '../dummy/body_widget.dummy.dart'; parameters: [ 'infoText', 'counter', - ],) + ], +) class BodyWidgetPreview extends ParentPreviewWidget { - @override String get title => 'body_widget'; - + @override String get basePath => '/catalog'; - + const BodyWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -104,20 +104,19 @@ class BodyWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < BodyWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => BodyWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return BodyWidget(infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => BodyWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return BodyWidget( + infoText: dummy.parameters['infoText'], + counter: dummy.parameters['counter'], + ); + }, + ), ], ) ], ); } - - } - \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart index ef8888b..74eb890 100644 --- a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart @@ -9,17 +9,17 @@ import '../dummy/counter_widget.dummy.dart'; description: 'Basic counter widget', parameters: [ 'counter', - ],) + ], +) class CounterWidgetPreview extends ParentPreviewWidget { - @override String get title => 'counter_widget'; - + @override String get basePath => '/catalog'; - + const CounterWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -104,20 +104,18 @@ class CounterWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < CounterWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => CounterWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return CounterWidget(counter: dummy.parameters['counter'],); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => CounterWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return CounterWidget( + counter: dummy.parameters['counter'], + ); + }, + ), ], ) ], ); } - - } - \ No newline at end of file diff --git a/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart index d18edaa..1ecbb83 100644 --- a/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart +++ b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart @@ -7,17 +7,17 @@ import '../dummy/fab_widget.dummy.dart'; @Preview( description: 'Basic fab widget', - parameters: ['incrementCounter'],) + parameters: ['incrementCounter'], +) class FabWidgetPreview extends ParentPreviewWidget { - @override String get title => 'fab_widget'; - + @override String get basePath => '/catalog'; - + const FabWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -102,20 +102,18 @@ class FabWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < FabWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => FabWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return FabWidget(incrementCounter: dummy.parameters['incrementCounter'],); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => FabWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return FabWidget( + incrementCounter: dummy.parameters['incrementCounter'], + ); + }, + ), ], ) ], ); } - - } - \ No newline at end of file diff --git a/lib/src/annotations/preview.dart b/lib/src/annotations/preview.dart index 3f2c657..b85c5ef 100644 --- a/lib/src/annotations/preview.dart +++ b/lib/src/annotations/preview.dart @@ -3,22 +3,16 @@ import 'dart:convert'; import 'package:catalog/src/base/serial.dart'; class Preview implements Serial { - final String id; - final String path; final String description; final List parameters; const Preview({ - this.id = '', - this.path = '', this.description = '', this.parameters = const [], }); @override Preview fromJson(Map json) => Preview( - id: json['id'] ?? '', - path: json['path'] ?? '', description: json['description'] ?? '', parameters: Serial.listObjectFromBasicType( json['parameters'] ?? [], @@ -26,15 +20,13 @@ class Preview implements Serial { ); @override - String getId() => id; + String getId() => ''; @override - Preview instance() => const Preview(id: '', path: ''); + Preview instance() => const Preview(); @override Map toJson() => { - 'id': id, - 'path': path, 'description': description, 'parameters': parameters, }; @@ -52,14 +44,10 @@ class Preview implements Serial { } Preview copyWith({ - String? id, - String? path, String? description, List? parameters, }) => Preview( - id: id ?? this.id, - path: path ?? this.path, description: description ?? this.description, parameters: parameters ?? this.parameters, ); diff --git a/lib/src/base/serial.dart b/lib/src/base/serial.dart index 25b6f35..d6ed282 100644 --- a/lib/src/base/serial.dart +++ b/lib/src/base/serial.dart @@ -79,7 +79,7 @@ abstract class Serial { static List instances = [ ComponentNode(), BuiltComponent(), - const Preview(id: '', path: ''), + const Preview(), const InternalPreview(id: '', path: ''), ]; diff --git a/lib/src/bin/catalog_builder/catalog_builder.dart b/lib/src/bin/catalog_builder/catalog_builder.dart index 4cb73d7..53e8891 100644 --- a/lib/src/bin/catalog_builder/catalog_builder.dart +++ b/lib/src/bin/catalog_builder/catalog_builder.dart @@ -3,7 +3,6 @@ import 'dart:io'; import 'package:catalog/src/annotations/internal_preview.dart'; import 'package:catalog/src/builders/catalog/built_component.dart'; import 'package:catalog/src/builders/catalog/component_node.dart'; -import 'package:catalog/src/extensions/string_ext.dart'; Future findPreviewClassName(String path) async { try { @@ -66,8 +65,6 @@ class ${pageClass}State extends State<$pageClass> { var p = file.path.split(base)[1]; var package = 'package:$appId$p'; - print('route added: ${preview.path}'); - return BuiltComponent( path: file.path, route: preview.path, @@ -81,189 +78,12 @@ class ${pageClass}State extends State<$pageClass> { } } -Future buildMiddlePages( - String appId, - String base, - String outputPath, - String outputFile, - String import, - String name, - String path, - String pageRoute, - List children, -) async { - try { - var directory = Directory(outputPath); - await directory.create(recursive: true); - File file = File('$outputPath/$outputFile'); - - final clazz = - name.replaceAll('()', '').split('_').map((e) => e.capitalize()).join(); - final clazzName = '${clazz}PreviewPageDummy'; - - var content = ''' -/// AUTOGENERATED FILE. DO NOT EDIT - -import 'package:catalog/catalog.dart'; -import 'package:flutter/material.dart'; - -class $clazzName extends StatefulWidget { - - static String routeName = '${name.toLowerCase()}'; - - const $clazzName({super.key}); - - @override - ${clazzName}State createState() => ${clazzName}State(); -} - -class ${clazzName}State extends State<$clazzName> { - @override - Widget build(BuildContext context) { - return PreviewScaffold( - child: ListView( - children: [ - '''; - - for (ComponentNode node in children) { - content += ''' - ListTile( - title: const Text( - '${node.id}', - style: TextStyle( - color: Colors.black, - fontSize: 16, - letterSpacing: .3, - ), - ), - onTap: () { - context.go('/$pageRoute/$path/${node.id}'); - }, - ), - '''; - } - - content += ''' - ], - ), - ); - } -} - - '''; - file.writeAsStringSync(content); - - var p = file.path.split(base)[1]; - var package = 'package:$appId$p'; - - return BuiltComponent( - path: file.path, - route: path, - package: package, - clazzName: clazzName, - preview: null, - ); - } catch (e) { - return null; - } -} - -/* -Future buildChildrenPages( - String basePath, - dynamic config, - String appId, - ComponentNode node, - String path, - String pageRoute, - int level, -) async { - try { - ComponentNode n = node; - String p = path; - if (level == 0) { - n.builtComponent = BuiltComponent(); - n.builtComponent!.path = - './${config['base']}/${config['output']}/${config['pageFile']}'; - n.builtComponent!.route = ''; - n.builtComponent!.clazzName = 'CatalogComponent'; - - final File file = File(basePath + n.builtComponent!.path); - var fp = file.path.split(config['base'])[1]; - n.builtComponent!.package = 'package:$appId$fp'; - - for (var entry in n.children.entries) { - var f = await buildChildrenPages( - basePath, - config, - appId, - entry.value, - p, - pageRoute, - level + 1, - ); - if (f == null) continue; - n.children[entry.key] = f; - } - return n; - } - - if (n.builtComponent != null) { - return n; - } - - var current = n.id; - - if (p.isEmpty) { - p += current; - } else { - p += '/$current'; - } - - // print('Generating middle page: $current'); - var middleFolder = './$basePath${config['base']}/${config['output']}/$p'; - n.builtComponent = await buildMiddlePages( - appId, - config['base'], - middleFolder, - '${current.toLowerCase()}_preview_page_dummy.dart', - '', - current.capitalize(), - p, - pageRoute, - n.childrenList, - ); - - n.builtComponent!.route = p; - - for (var entry in n.children.entries) { - print('build children page: ${entry.key}'); - var f = await buildChildrenPages( - basePath, - config, - appId, - entry.value, - p, - pageRoute, - level + 1, - ); - if (f == null) continue; - n.children[entry.key] = f; - } - return n; - } catch (e) { - return null; - } -} -*/ ComponentNode buildTreeFromMap( String pageRoute, Map> componentsMap, ) { - // Nodo raíz del árbol ComponentNode root = ComponentNode(id: pageRoute, route: '/'); - // Función auxiliar para crear o encontrar un nodo dentro del árbol ComponentNode findOrCreateNode( ComponentNode current, List pathParts, @@ -273,7 +93,6 @@ ComponentNode buildTreeFromMap( return current; } - // Obtener el primer segmento del path y crear el nodo hijo si no existe String part = pathParts.removeAt(0); if (!current.children.containsKey(part)) { current.children[part] = ComponentNode( @@ -282,20 +101,15 @@ ComponentNode buildTreeFromMap( ); } - // Recursivamente buscar o crear el siguiente nodo hijo return findOrCreateNode(current.children[part]!, pathParts, fullPath); } - // Recorrer cada entrada del mapa y asignarla a su nodo correspondiente componentsMap.forEach((path, builtComponents) { - // Dividir el path en sus partes, excluyendo la raíz '/' List pathParts = path.split('/').where((part) => part.isNotEmpty).toList(); - // Encontrar o crear el nodo adecuado para este path ComponentNode currentNode = findOrCreateNode(root, pathParts, path); - // Agregar los componentes del directorio actual al nodo correspondiente for (var component in builtComponents) { currentNode.builtComponents[component.path] = component; } @@ -303,69 +117,3 @@ ComponentNode buildTreeFromMap( return root; } - -/* -ComponentNode getNodesFrom( - String pageRoute, - Map> components, -) { - var firstNode = ComponentNode(id: pageRoute, route: '/'); - - final pathLevels = components.entries.toList(); - - for (var entity in pathLevels) { - final pathLevel = entity.key; - final pagesInThatLevel = entity.value.toList(); - - for (var page in pagesInThatLevel) { - print('======================================================='); - print('route: ${page.route}'); - var parts = page.route.split('/'); - if (parts.first == '.') { - parts.removeAt(0); - } - addNode(firstNode, parts, 0, page); - } - } - - return firstNode; -} - -void addNode( - ComponentNode node, - List parts, - int index, - BuiltComponent component, -) { - if (index >= parts.length) { - return; - } - ComponentNode? no; - for (var n in node.children.values.toList()) { - if (n.id == parts[index]) { - no = n; - break; - } - } - - if (no == null) { - print('parts: ${parts.join(', ')}'); - no = ComponentNode( - id: parts[index], - route: '/${parts[index]}', - builtComponent: parts.length - 1 == index ? component : null, - ); - print('adding: ${no.id}'); - print(' ${no.builtComponent?.preview?.path}'); - node.children[no.id] = no; - } - - if (no.route == '/${component.route}') { - final a = '/${component.package.split('/').last}'; - node.children[no.id]?.builtComponents[a] = component; - } else if (index < parts.length) { - addNode(no, parts, index + 1, component); - } -} - - */ diff --git a/lib/src/bin/tasks/tasks/catalog_task.dart b/lib/src/bin/tasks/tasks/catalog_task.dart index b5e8811..772d709 100644 --- a/lib/src/bin/tasks/tasks/catalog_task.dart +++ b/lib/src/bin/tasks/tasks/catalog_task.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'dart:io'; import 'package:catalog/src/base/serial.dart'; @@ -28,8 +27,11 @@ class CatalogTask extends BaseTask { final dirOutPut = Directory('./$base${config['base']}/${config['output']}'); await dirOutPut.create(recursive: true); - final List entities = - await dir.list(recursive: true).toList(); + final List entities = await dir + .list( + recursive: true, + ) + .toList(); final files = []; @@ -66,8 +68,6 @@ class CatalogTask extends BaseTask { var outputFolder = './$base${config['base']}/${config['output']}/${preview.path}/'; - print('Catalog page destination: $outputFolder'); - var build = await createPage( appId, config['base'], @@ -84,9 +84,6 @@ class CatalogTask extends BaseTask { continue; } - print('Built: ${jsonEncode(build.toJson())}'); - - print('${build.route} with classname $className'); if (map[build.route] == null) { map[build.route] = []; } @@ -98,8 +95,9 @@ class CatalogTask extends BaseTask { final File assetsConfig = File('./$base${config['runtimeConfigHolder']}'); assetsConfig.writeAsStringSync(node.toJson().toPrettyString()); - final File catalogFile = - File('./$base${config['base']}/${config['output']}/$page'); + final File catalogFile = File( + './$base${config['base']}/${config['output']}/$page', + ); // print(node.routerBuilder); diff --git a/lib/src/bin/tasks/tasks/preview_task.dart b/lib/src/bin/tasks/tasks/preview_task.dart index 76aad6a..f4728e8 100644 --- a/lib/src/bin/tasks/tasks/preview_task.dart +++ b/lib/src/bin/tasks/tasks/preview_task.dart @@ -45,7 +45,6 @@ class PreviewTask extends BaseTask { final File file = File(fileSystemEntity.path); var p = file.path.split(config['base'])[1]; var classImport = 'package:$appId$p'; - print('preview on file: ${file.path}'); var preview = await previewOnFile(base, config, file.path); var previewAnnotation = await findPreviewAnnotation(file.path); if (previewAnnotation == null) continue; diff --git a/lib/src/bin/utils/configuration.dart b/lib/src/bin/utils/configuration.dart index cc3be26..6e7cb04 100644 --- a/lib/src/bin/utils/configuration.dart +++ b/lib/src/bin/utils/configuration.dart @@ -83,14 +83,11 @@ Future previewOnFile( var output = './$basePath${config['base']}/${config['output']}/'; var fileName = 'process.dart'; - print('\n==========================================================\n'); - print('Original file: $originalFilePath'); - File originalFile = File(originalFilePath); var originalContent = originalFile.readAsStringSync(); var original = - 'Preview${originalContent.split('@Preview')[1].split(')').first});'; + 'InternalPreview${originalContent.split('@Preview')[1].split(')').first});'; var dir = Directory(output); await dir.create(recursive: true); @@ -100,13 +97,13 @@ import 'dart:convert'; import 'package:catalog/src/base/serial.dart'; -class Preview implements Serial { +class InternalPreview implements Serial { final String id; final String path; final String description; final List parameters; - const Preview({ + const InternalPreview({ this.id = '', this.path = '', this.description = '', @@ -114,7 +111,7 @@ class Preview implements Serial { }); @override - Preview fromJson(Map json) => Preview( + InternalPreview fromJson(Map json) => InternalPreview( id: json['id'] ?? '', path: json['path'] ?? '', description: json['description'] ?? '', @@ -127,7 +124,7 @@ class Preview implements Serial { String getId() => id; @override - Preview instance() => const Preview(id: '', path: ''); + InternalPreview instance() => const InternalPreview(id: '', path: ''); @override Map toJson() => { @@ -138,7 +135,7 @@ class Preview implements Serial { }; @override - Preview fromString(String value) { + InternalPreview fromString(String value) { Map map = jsonDecode(value); return fromJson(map); } @@ -149,13 +146,13 @@ class Preview implements Serial { return jsonEncode(map); } - Preview copyWith({ + InternalPreview copyWith({ String? id, String? path, String? description, List? parameters, }) => - Preview( + InternalPreview( id: id ?? this.id, path: path ?? this.path, description: description ?? this.description, @@ -172,7 +169,7 @@ void main(List arguments) async { var path = file.absolute.path; var result = await Process.run('dart', ['run', path]); - var preview = const InternalPreview( + var preview = InternalPreview( id: '', path: '', ).fromJson( @@ -198,7 +195,6 @@ void main(List arguments) async { } } - print('########### GENERATED PREVIEW: ${preview.id} ${preview.path}'); return preview; } catch (e) { print(e); diff --git a/test/catalog_test.dart b/test/catalog_test.dart index 053b1a9..d01d176 100644 --- a/test/catalog_test.dart +++ b/test/catalog_test.dart @@ -6,30 +6,37 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:go_router/go_router.dart'; void main() { - test('Basic dummy test', () { - final runner = CatalogRunner( - application: Container(), - route: GoRoute( - path: '/catalog', - builder: (context, state) => Container() - ), - ); - expect(runner.enabled, false); - }); + final dependency = 'catalog'; + final exampleFolder = 'example'; - test('Test Preview task (preview + format)', () async { - final exampleFolder = 'example'; - var dependencies = loadDependenciesFile('$exampleFolder/'); - print(introMessage(dependencies['catalog'].toString())); - await MainTask().work([exampleFolder]); - assert(true); - }); + test( + 'Basic dummy test', + () { + final runner = CatalogRunner( + application: Container(), + route: + GoRoute(path: '/catalog', builder: (context, state) => Container()), + ); + expect(runner.enabled, false); + }, + ); - test('Test Main task (preview + catalog + format)', () async { - final exampleFolder = 'example'; - var dependencies = loadDependenciesFile('$exampleFolder/'); - print(introMessage(dependencies['catalog'].toString())); - await MainTask().work([exampleFolder]); - assert(true); - }); + test( + 'Test Preview task (preview + format)', + () async { + var dependencies = loadDependenciesFile('$exampleFolder/'); + print(introMessage(dependencies[dependency].toString())); + await MainTask().work([exampleFolder]); + }, + ); + + test( + 'Test Main task (preview + catalog + format)', + () async { + var dependencies = loadDependenciesFile('$exampleFolder/'); + print(introMessage(dependencies[dependency].toString())); + await MainTask().work([exampleFolder]); + assert(true); + }, + ); } From afeb84919d2faa0cd78ec8a4736d91e07ba56589 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 01:42:17 +0200 Subject: [PATCH 12/28] feature: testing tests from catalog --- .../bottom/catalog/test/fab_widget.test.dart | 48 +++++++++++++++++++ example/test/catalog_widget_test.dart | 5 ++ example/test/widget_test.dart | 3 +- lib/catalog.dart | 2 + lib/src/extensions/widget_test_ext.dart | 17 +++++++ pubspec.yaml | 5 +- 6 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart create mode 100644 example/test/catalog_widget_test.dart create mode 100644 lib/src/extensions/widget_test_ext.dart diff --git a/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart b/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart new file mode 100644 index 0000000..9a7b8ab --- /dev/null +++ b/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart @@ -0,0 +1,48 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file for testing the widget FabWidgetPreview +/// + +import 'package:catalog/catalog.dart'; + +import '../../fab_widget.dart'; +import '../dummy/fab_widget.dummy.dart'; + +class FabWidgetTest { + void main() { + group( + 'FabWidget - Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = FabWidgetDummy().dummies.first; + + final widget = FabWidget( + incrementCounter: dummy.parameters['incrementCounter'], + ); + + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = FabWidgetDummy().dummies.first; + + final widget = FabWidget( + incrementCounter: dummy.parameters['incrementCounter'], + ); + + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/test/catalog_widget_test.dart b/example/test/catalog_widget_test.dart new file mode 100644 index 0000000..8fc7eee --- /dev/null +++ b/example/test/catalog_widget_test.dart @@ -0,0 +1,5 @@ +import 'package:example/widgets/utils/bottom/catalog/test/fab_widget.test.dart'; + +void main() { + FabWidgetTest().main(); +} diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 092d222..30fe7e9 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -5,11 +5,10 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. +import 'package:example/main.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:example/main.dart'; - void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. diff --git a/lib/catalog.dart b/lib/catalog.dart index f493228..a2032d1 100644 --- a/lib/catalog.dart +++ b/lib/catalog.dart @@ -28,6 +28,7 @@ export 'package:catalog/src/builders/screenshots/types/apple/i_pad_pro_3gen.dart export 'package:catalog/src/builders/screenshots/types/apple/i_phone_55.dart'; export 'package:catalog/src/builders/screenshots/types/apple/i_phone_65.dart'; export 'package:catalog/src/builders/screenshots/types/apple/macos.dart'; +export 'package:catalog/src/extensions/widget_test_ext.dart'; export 'package:catalog/src/catalog_runner.dart'; export 'package:catalog/src/builders/catalog/component_node.dart'; export 'package:catalog/src/utils/constants.dart'; @@ -35,6 +36,7 @@ export 'package:catalog/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_vi export 'package:catalog/src/extensions/locale_ext.dart'; export 'package:device_frame/device_frame.dart'; export 'package:go_router/go_router.dart'; +export 'package:flutter_test/flutter_test.dart'; class Catalog { static Catalog? _instance; diff --git a/lib/src/extensions/widget_test_ext.dart b/lib/src/extensions/widget_test_ext.dart new file mode 100644 index 0000000..5e7866e --- /dev/null +++ b/lib/src/extensions/widget_test_ext.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:stringcare/stringcare.dart'; + +extension WidgetTestExt on WidgetTester { + Future test(Widget widget) async { + await pumpWidget( + MaterialApp( + navigatorKey: Stringcare().navigatorKey, + supportedLocales: Stringcare().locales, + localizationsDelegates: Stringcare().delegates, + home: widget, + ), + ); + await pumpAndSettle(); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 9855cef..79c0d29 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,11 +19,12 @@ dependencies: http: ^1.2.2 # android ios linux macos web windows image: ^4.2.0 # android ios linux macos web windows shelf: ^1.4.1 # android ios linux macos web windows + stringcare: ^0.1.7 # android ios linux macos web windows vector_graphics: ^1.1.11+1 # android ios linux macos web windows yaml: ^3.1.2 # android ios linux macos web windows yaml_writer: ^2.0.0 # android ios linux macos web windows - -dev_dependencies: flutter_test: sdk: flutter + +dev_dependencies: flutter_lints: ^5.0.0 From dbfd0be2770d260166b46d9b914c77c8c705afa4 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 01:56:31 +0200 Subject: [PATCH 13/28] feature: testing tests --- example/lib/catalog/process.dart | 78 +++++++++++++++++++ .../catalog/preview/main_screen.preview.dart | 16 ++-- .../catalog/preview/body_widget.preview.dart | 12 ++- .../preview/counter_widget.preview.dart | 10 ++- .../catalog/preview/fab_widget.preview.dart | 10 ++- .../bottom/catalog/test/fab_widget.test.dart | 20 ++--- .../bin/preview_builder/preview_builder.dart | 10 ++- 7 files changed, 123 insertions(+), 33 deletions(-) create mode 100644 example/lib/catalog/process.dart diff --git a/example/lib/catalog/process.dart b/example/lib/catalog/process.dart new file mode 100644 index 0000000..a82d622 --- /dev/null +++ b/example/lib/catalog/process.dart @@ -0,0 +1,78 @@ +import 'dart:convert'; + +import 'package:catalog/src/base/serial.dart'; + +class InternalPreview implements Serial { + final String id; + final String path; + final String description; + final List parameters; + + const InternalPreview({ + this.id = '', + this.path = '', + this.description = '', + this.parameters = const [], + }); + + @override + InternalPreview fromJson(Map json) => InternalPreview( + id: json['id'] ?? '', + path: json['path'] ?? '', + description: json['description'] ?? '', + parameters: Serial.listObjectFromBasicType( + json['parameters'] ?? [], + ), + ); + + @override + String getId() => id; + + @override + InternalPreview instance() => const InternalPreview(id: '', path: ''); + + @override + Map toJson() => { + 'id': id, + 'path': path, + 'description': description, + 'parameters': parameters, + }; + + @override + InternalPreview fromString(String value) { + Map map = jsonDecode(value); + return fromJson(map); + } + + @override + String stringValue() { + var map = toJson(); + return jsonEncode(map); + } + + InternalPreview copyWith({ + String? id, + String? path, + String? description, + List? parameters, + }) => + InternalPreview( + id: id ?? this.id, + path: path ?? this.path, + description: description ?? this.description, + parameters: parameters ?? this.parameters, + ); +} + +void main(List arguments) async { + var preview = const InternalPreview( + parameters: [ + 'title', + 'infoText', + 'counter', + 'incrementCounter', + ], + ); + print(jsonEncode(preview.toJson())); +} diff --git a/example/lib/widgets/catalog/preview/main_screen.preview.dart b/example/lib/widgets/catalog/preview/main_screen.preview.dart index 16f0169..7095ff7 100644 --- a/example/lib/widgets/catalog/preview/main_screen.preview.dart +++ b/example/lib/widgets/catalog/preview/main_screen.preview.dart @@ -110,12 +110,7 @@ class MainScreenPreview extends ParentPreviewWidget { widgetKey: GlobalKey(), dummyBuilder: () => MainScreenDummy().dummies[i], builder: (BuildContext context, Dummy dummy) { - return MainScreen( - title: dummy.parameters['title'], - infoText: dummy.parameters['infoText'], - counter: dummy.parameters['counter'], - incrementCounter: dummy.parameters['incrementCounter'], - ); + return buildMainScreen(dummy); }, ), ], @@ -124,3 +119,12 @@ class MainScreenPreview extends ParentPreviewWidget { ); } } + +MainScreen buildMainScreen(Dummy dummy) { + return MainScreen( + title: dummy.parameters['title'], + infoText: dummy.parameters['infoText'], + counter: dummy.parameters['counter'], + incrementCounter: dummy.parameters['incrementCounter'], + ); +} diff --git a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart index 47dc8ff..24af584 100644 --- a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart @@ -108,10 +108,7 @@ class BodyWidgetPreview extends ParentPreviewWidget { widgetKey: GlobalKey(), dummyBuilder: () => BodyWidgetDummy().dummies[i], builder: (BuildContext context, Dummy dummy) { - return BodyWidget( - infoText: dummy.parameters['infoText'], - counter: dummy.parameters['counter'], - ); + return buildBodyWidget(dummy); }, ), ], @@ -120,3 +117,10 @@ class BodyWidgetPreview extends ParentPreviewWidget { ); } } + +BodyWidget buildBodyWidget(Dummy dummy) { + return BodyWidget( + infoText: dummy.parameters['infoText'], + counter: dummy.parameters['counter'], + ); +} diff --git a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart index 74eb890..04f76ab 100644 --- a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart @@ -108,9 +108,7 @@ class CounterWidgetPreview extends ParentPreviewWidget { widgetKey: GlobalKey(), dummyBuilder: () => CounterWidgetDummy().dummies[i], builder: (BuildContext context, Dummy dummy) { - return CounterWidget( - counter: dummy.parameters['counter'], - ); + return buildCounterWidget(dummy); }, ), ], @@ -119,3 +117,9 @@ class CounterWidgetPreview extends ParentPreviewWidget { ); } } + +CounterWidget buildCounterWidget(Dummy dummy) { + return CounterWidget( + counter: dummy.parameters['counter'], + ); +} diff --git a/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart index 1ecbb83..8b87e15 100644 --- a/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart +++ b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart @@ -106,9 +106,7 @@ class FabWidgetPreview extends ParentPreviewWidget { widgetKey: GlobalKey(), dummyBuilder: () => FabWidgetDummy().dummies[i], builder: (BuildContext context, Dummy dummy) { - return FabWidget( - incrementCounter: dummy.parameters['incrementCounter'], - ); + return buildFabWidget(dummy); }, ), ], @@ -117,3 +115,9 @@ class FabWidgetPreview extends ParentPreviewWidget { ); } } + +FabWidget buildFabWidget(Dummy dummy) { + return FabWidget( + incrementCounter: dummy.parameters['incrementCounter'], + ); +} diff --git a/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart b/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart index 9a7b8ab..3121262 100644 --- a/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart +++ b/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart @@ -5,8 +5,8 @@ import 'package:catalog/catalog.dart'; -import '../../fab_widget.dart'; import '../dummy/fab_widget.dummy.dart'; +import '../preview/fab_widget.preview.dart'; class FabWidgetTest { void main() { @@ -15,13 +15,9 @@ class FabWidgetTest { () { testWidgets( 'Lorem text not found', - (tester) async { + (tester) async { final dummy = FabWidgetDummy().dummies.first; - - final widget = FabWidget( - incrementCounter: dummy.parameters['incrementCounter'], - ); - + final widget = buildFabWidget(dummy); await tester.test(widget); expect(find.text('lorem ipsu'), findsNothing); @@ -30,16 +26,12 @@ class FabWidgetTest { testWidgets( 'Other lorem text not found', - (tester) async { + (tester) async { final dummy = FabWidgetDummy().dummies.first; - - final widget = FabWidget( - incrementCounter: dummy.parameters['incrementCounter'], - ); - + final widget = buildFabWidget(dummy); await tester.test(widget); - expect(find.text('lorem ipsu'), findsNothing); + expect(find.text('ipsu lorem'), findsNothing); }, ); }, diff --git a/lib/src/bin/preview_builder/preview_builder.dart b/lib/src/bin/preview_builder/preview_builder.dart index 86fc331..ad8a6cd 100644 --- a/lib/src/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/preview_builder/preview_builder.dart @@ -132,7 +132,7 @@ class ${clazz}Preview extends ParentPreviewWidget { ), ), for (int i = 0; i < ${clazz}Dummy().dummies.length; i++) - ${dummyWidgetBuilder(clazz, widgetCompose)} + ${dummyWidgetBuilder(clazz)} ], ) ], @@ -140,6 +140,10 @@ class ${clazz}Preview extends ParentPreviewWidget { } +} + +$clazz build$clazz(Dummy dummy) { + return $widgetCompose; } '''; @@ -156,13 +160,13 @@ class ${clazz}Preview extends ParentPreviewWidget { await file.writeAsString(content); } -String dummyWidgetBuilder(String clazz, String widgetCompose) { +String dummyWidgetBuilder(String clazz) { return ''' PreviewBoundary( widgetKey: GlobalKey(), dummyBuilder: () => ${clazz}Dummy().dummies[i], builder: (BuildContext context, Dummy dummy) { - return $widgetCompose; + return build$clazz(dummy); }, ), '''; From 0313331a087bacd5c367f93c674dad71cdc95855 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 02:10:14 +0200 Subject: [PATCH 14/28] feature: test builder --- .../bottom/catalog/test/fab_widget.test.dart | 2 +- .../bin/preview_builder/preview_builder.dart | 72 +++++++++++++++++++ lib/src/bin/tasks/main_task.dart | 4 +- lib/src/bin/tasks/preview_task.dart | 4 +- lib/src/bin/tasks/tasks/test_task.dart | 58 +++++++++++++++ 5 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 lib/src/bin/tasks/tasks/test_task.dart diff --git a/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart b/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart index 3121262..34b7fc0 100644 --- a/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart +++ b/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart @@ -1,6 +1,6 @@ /// AUTOGENERATED FILE. /// -/// Use this file for testing the widget FabWidgetPreview +/// Use this file to test the widget FabWidgetPreview /// import 'package:catalog/catalog.dart'; diff --git a/lib/src/bin/preview_builder/preview_builder.dart b/lib/src/bin/preview_builder/preview_builder.dart index ad8a6cd..ec817fc 100644 --- a/lib/src/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/preview_builder/preview_builder.dart @@ -160,6 +160,78 @@ $clazz build$clazz(Dummy dummy) { await file.writeAsString(content); } +Future generateTest( + String srcPath, + String className, + String prefix, +) async { + var clazz = className.replaceAll('()', ''); + + String fileName = srcPath.split('/').last; + String name = fileName.split('.').first; + String dirPath = srcPath.replaceAll(fileName, ''); + String testPath = '${dirPath}catalog/test/'; + + await Directory(testPath).create(recursive: true); + + String testFile = '$testPath$name.test.dart'; + File file = File(testFile); + + if (await file.exists()) { + print( + '🧪 👌 Test file already exist for $clazz - ${clazz}Test ($testFile)'); + return; + } + + print('🧪 Generating test for $clazz - ${clazz}Test ($testFile)'); + + var content = ''' +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget $clazz +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/$name.dummy.dart'; +import '../preview/$name.$prefix.dart'; + +class ${clazz}Test { + void main() { + group( + '$clazz - Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = ${clazz}Dummy().dummies.first; + final widget = build$clazz(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = ${clazz}Dummy().dummies.first; + final widget = build$clazz(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} + + '''; + + await file.writeAsString(content); +} + String dummyWidgetBuilder(String clazz) { return ''' PreviewBoundary( diff --git a/lib/src/bin/tasks/main_task.dart b/lib/src/bin/tasks/main_task.dart index b20ea2e..55d62a6 100644 --- a/lib/src/bin/tasks/main_task.dart +++ b/lib/src/bin/tasks/main_task.dart @@ -2,10 +2,12 @@ import 'base/base_task.dart'; import 'tasks/catalog_task.dart'; import 'tasks/format_task.dart'; import 'tasks/preview_task.dart'; +import 'tasks/test_task.dart'; class MainTask extends BaseTask { final tasks = [ PreviewTask(), + TestTask(), CatalogTask(), FormatTask(), ]; @@ -20,6 +22,6 @@ class MainTask extends BaseTask { print(e); } } - print('\n Previews and catalog generated \n'); + print('\n Previews, tests and catalog generated \n'); } } diff --git a/lib/src/bin/tasks/preview_task.dart b/lib/src/bin/tasks/preview_task.dart index 674c0e3..7aec303 100644 --- a/lib/src/bin/tasks/preview_task.dart +++ b/lib/src/bin/tasks/preview_task.dart @@ -1,10 +1,12 @@ import 'base/base_task.dart'; import 'tasks/format_task.dart'; import 'tasks/preview_task.dart' as preview; +import 'tasks/test_task.dart'; class PreviewTask extends BaseTask { final tasks = [ preview.PreviewTask(), + TestTask(), FormatTask(), ]; @@ -18,6 +20,6 @@ class PreviewTask extends BaseTask { print(e); } } - print('\n Previews generated \n'); + print('\n Previews and tests generated \n'); } } diff --git a/lib/src/bin/tasks/tasks/test_task.dart b/lib/src/bin/tasks/tasks/test_task.dart new file mode 100644 index 0000000..7b426ff --- /dev/null +++ b/lib/src/bin/tasks/tasks/test_task.dart @@ -0,0 +1,58 @@ +import 'dart:io'; + +import '../../preview_builder/preview_builder.dart'; +import '../../utils/configuration.dart'; +import '../base/base_task.dart'; + +class TestTask extends BaseTask { + @override + Future work(List args) async { + final base = args.isEmpty ? '' : '${args.first}/'; + + var config = loadConfigFile(base); + + final prefixValue = config['prefix'] ?? 'preview'; + + final dir = Directory('./$base${config['base']}'); + await dir.create(recursive: true); + + final dirOutPut = Directory('./$base${config['base']}/${config['output']}'); + await dirOutPut.create(recursive: true); + + final List entities = + await dir.list(recursive: true).toList(); + + final files = []; + + for (FileSystemEntity fileSystemEntity in entities) { + try { + if (fileSystemEntity is Directory) continue; + if (fileSystemEntity.path.endsWith('.DS_Store')) continue; + final File file = File(fileSystemEntity.path); + if (file.path.contains('.$prefixValue.')) continue; + final content = await file.readAsString(); + if (content.contains('@Preview(')) { + files.add(fileSystemEntity); + } + } catch (e) { + print(e); + } + } + + for (FileSystemEntity fileSystemEntity in files) { + final File file = File(fileSystemEntity.path); + var preview = await previewOnFile(base, config, file.path); + var previewAnnotation = await findPreviewAnnotation(file.path); + if (previewAnnotation == null) continue; + var className = await findClassName(file.path); + if (className == null) continue; + if (preview == null) continue; + + await generateTest( + file.path, + className, + prefixValue, + ); + } + } +} From fdde7386ff46529537ef29443dcdced5f1f9ecb1 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 04:30:38 +0200 Subject: [PATCH 15/28] feature: adding instrumented test --- example/assets/preview_config.json | 16 +- .../bottom/catalog/test/fab_widget.test.dart | 40 -- example/test/catalog_widget_test.dart | 15 +- lib/catalog.dart | 16 +- .../bin/preview_builder/preview_builder.dart | 175 +++++- lib/src/bin/tasks/main_task.dart | 2 + lib/src/bin/tasks/preview_task.dart | 2 + lib/src/bin/tasks/tasks/format_task.dart | 22 +- .../tasks/tasks/instrumented_test_task.dart | 71 +++ lib/src/bin/tasks/tasks/test_task.dart | 15 +- lib/src/bin/utils/test_builder_info.dart | 11 + .../flutter_fancy_tree_view.dart | 10 - .../src/folder_button.dart | 367 ------------ .../src/sliver_animated_tree.dart | 434 -------------- .../src/sliver_tree.dart | 124 ---- .../src/tree_controller.dart | 536 ------------------ .../src/tree_indentation.dart | 508 ----------------- .../src/tree_view.dart | 152 ----- lib/src/extensions/widget_test_ext.dart | 13 + pubspec.yaml | 2 + 20 files changed, 335 insertions(+), 2196 deletions(-) delete mode 100644 example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart create mode 100644 lib/src/bin/tasks/tasks/instrumented_test_task.dart create mode 100644 lib/src/bin/utils/test_builder_info.dart delete mode 100644 lib/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_view.dart delete mode 100644 lib/src/embed/flutter_fanacy_tree_view/src/folder_button.dart delete mode 100644 lib/src/embed/flutter_fanacy_tree_view/src/sliver_animated_tree.dart delete mode 100644 lib/src/embed/flutter_fanacy_tree_view/src/sliver_tree.dart delete mode 100644 lib/src/embed/flutter_fanacy_tree_view/src/tree_controller.dart delete mode 100644 lib/src/embed/flutter_fanacy_tree_view/src/tree_indentation.dart delete mode 100644 lib/src/embed/flutter_fanacy_tree_view/src/tree_view.dart diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index 2d995cd..6894852 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -7,8 +7,8 @@ "id": "widgets", "route": "widgets", "builtComponents": { - "./lib/catalog/widgets/main_screen.dart": { - "path": "./lib/catalog/widgets/main_screen.dart", + "./example/lib/catalog/widgets/main_screen.dart": { + "path": "./example/lib/catalog/widgets/main_screen.dart", "route": "widgets", "package": "package:example/catalog/widgets/main_screen.dart", "clazzName": "MainScreenPreviewPreviewPageDummy", @@ -35,8 +35,8 @@ "id": "bottom", "route": "widgets/utils/bottom", "builtComponents": { - "./lib/catalog/widgets/utils/bottom/fab_widget.dart": { - "path": "./lib/catalog/widgets/utils/bottom/fab_widget.dart", + "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart": { + "path": "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart", "route": "widgets/utils/bottom", "package": "package:example/catalog/widgets/utils/bottom/fab_widget.dart", "clazzName": "FabWidgetPreviewPreviewPageDummy", @@ -58,8 +58,8 @@ "id": "screen", "route": "widgets/screen", "builtComponents": { - "./lib/catalog/widgets/screen/body_widget.dart": { - "path": "./lib/catalog/widgets/screen/body_widget.dart", + "./example/lib/catalog/widgets/screen/body_widget.dart": { + "path": "./example/lib/catalog/widgets/screen/body_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/body_widget.dart", "clazzName": "BodyWidgetPreviewPreviewPageDummy", @@ -73,8 +73,8 @@ ] } }, - "./lib/catalog/widgets/screen/counter_widget.dart": { - "path": "./lib/catalog/widgets/screen/counter_widget.dart", + "./example/lib/catalog/widgets/screen/counter_widget.dart": { + "path": "./example/lib/catalog/widgets/screen/counter_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/counter_widget.dart", "clazzName": "CounterWidgetPreviewPreviewPageDummy", diff --git a/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart b/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart deleted file mode 100644 index 34b7fc0..0000000 --- a/example/lib/widgets/utils/bottom/catalog/test/fab_widget.test.dart +++ /dev/null @@ -1,40 +0,0 @@ -/// AUTOGENERATED FILE. -/// -/// Use this file to test the widget FabWidgetPreview -/// - -import 'package:catalog/catalog.dart'; - -import '../dummy/fab_widget.dummy.dart'; -import '../preview/fab_widget.preview.dart'; - -class FabWidgetTest { - void main() { - group( - 'FabWidget - Tests', - () { - testWidgets( - 'Lorem text not found', - (tester) async { - final dummy = FabWidgetDummy().dummies.first; - final widget = buildFabWidget(dummy); - await tester.test(widget); - - expect(find.text('lorem ipsu'), findsNothing); - }, - ); - - testWidgets( - 'Other lorem text not found', - (tester) async { - final dummy = FabWidgetDummy().dummies.first; - final widget = buildFabWidget(dummy); - await tester.test(widget); - - expect(find.text('ipsu lorem'), findsNothing); - }, - ); - }, - ); - } -} diff --git a/example/test/catalog_widget_test.dart b/example/test/catalog_widget_test.dart index 8fc7eee..e54c06f 100644 --- a/example/test/catalog_widget_test.dart +++ b/example/test/catalog_widget_test.dart @@ -1,5 +1,16 @@ -import 'package:example/widgets/utils/bottom/catalog/test/fab_widget.test.dart'; +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' + as aaad; +import 'package:example/widgets/screen/catalog/test/body_widget.test.dart' + as gsno; +import 'package:example/widgets/screen/catalog/test/counter_widget.test.dart' + as jnqe; +import 'package:example/widgets/catalog/test/main_screen.test.dart' as pxto; void main() { - FabWidgetTest().main(); + aaad.FabWidgetTest().main(); + gsno.BodyWidgetTest().main(); + jnqe.CounterWidgetTest().main(); + pxto.MainScreenTest().main(); } diff --git a/lib/catalog.dart b/lib/catalog.dart index a2032d1..6816675 100644 --- a/lib/catalog.dart +++ b/lib/catalog.dart @@ -11,14 +11,15 @@ import 'src/builders/preview/preview_boundary.dart'; import 'src/builders/preview/preview_render_widget.dart'; export 'package:catalog/src/annotations/preview.dart'; +export 'package:catalog/src/builders/catalog/component_node.dart'; +export 'package:catalog/src/builders/catalog/preview_scaffold.dart'; +export 'package:catalog/src/builders/catalog/tree_elements_builder.dart'; export 'package:catalog/src/builders/device/device.dart'; export 'package:catalog/src/builders/dummy/dummy.dart'; export 'package:catalog/src/builders/dummy/dummy_text.dart'; +export 'package:catalog/src/builders/dummy/preview_dummy.dart'; export 'package:catalog/src/builders/preview/parent_preview_widget.dart'; export 'package:catalog/src/builders/preview/preview_boundary.dart'; -export 'package:catalog/src/builders/dummy/preview_dummy.dart'; -export 'package:catalog/src/builders/catalog/preview_scaffold.dart'; -export 'package:catalog/src/builders/catalog/tree_elements_builder.dart'; export 'package:catalog/src/builders/screenshots/background.dart'; export 'package:catalog/src/builders/screenshots/op/screenshot_process.dart'; export 'package:catalog/src/builders/screenshots/screenshot.dart'; @@ -28,15 +29,14 @@ export 'package:catalog/src/builders/screenshots/types/apple/i_pad_pro_3gen.dart export 'package:catalog/src/builders/screenshots/types/apple/i_phone_55.dart'; export 'package:catalog/src/builders/screenshots/types/apple/i_phone_65.dart'; export 'package:catalog/src/builders/screenshots/types/apple/macos.dart'; -export 'package:catalog/src/extensions/widget_test_ext.dart'; export 'package:catalog/src/catalog_runner.dart'; -export 'package:catalog/src/builders/catalog/component_node.dart'; -export 'package:catalog/src/utils/constants.dart'; -export 'package:catalog/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_view.dart'; export 'package:catalog/src/extensions/locale_ext.dart'; +export 'package:catalog/src/extensions/widget_test_ext.dart'; +export 'package:catalog/src/utils/constants.dart'; export 'package:device_frame/device_frame.dart'; -export 'package:go_router/go_router.dart'; export 'package:flutter_test/flutter_test.dart'; +export 'package:integration_test/integration_test.dart'; +export 'package:go_router/go_router.dart'; class Catalog { static Catalog? _instance; diff --git a/lib/src/bin/preview_builder/preview_builder.dart b/lib/src/bin/preview_builder/preview_builder.dart index ec817fc..37be64a 100644 --- a/lib/src/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/preview_builder/preview_builder.dart @@ -1,6 +1,8 @@ import 'dart:io'; +import 'dart:math'; import 'package:catalog/src/annotations/internal_preview.dart'; +import 'package:catalog/src/bin/utils/test_builder_info.dart'; Future findClassName(String path) async { try { @@ -160,9 +162,11 @@ $clazz build$clazz(Dummy dummy) { await file.writeAsString(content); } -Future generateTest( +Future generateTest( + dynamic config, String srcPath, String className, + String classImport, String prefix, ) async { var clazz = className.replaceAll('()', ''); @@ -174,13 +178,23 @@ Future generateTest( await Directory(testPath).create(recursive: true); - String testFile = '$testPath$name.test.dart'; + String testFile = '$testPath${name}_test.dart'; File file = File(testFile); + var importParts = classImport.split('/'); + importParts.removeAt(importParts.length - 1); + importParts.add(config['output']); + importParts.add('test'); + importParts.add('${name}_test.dart'); + if (await file.exists()) { print( '🧪 👌 Test file already exist for $clazz - ${clazz}Test ($testFile)'); - return; + return TestBuilderInfo( + alias: buildTestAlias(4), + clazzName: '${clazz}Test', + import: importParts.join('/'), + ); } print('🧪 Generating test for $clazz - ${clazz}Test ($testFile)'); @@ -230,6 +244,161 @@ class ${clazz}Test { '''; await file.writeAsString(content); + + return TestBuilderInfo( + alias: buildTestAlias(4), + clazzName: '${clazz}Test', + import: importParts.join('/'), + ); +} + +Future generateInstrumentedTest( + dynamic config, + String srcPath, + String className, + String classImport, + String prefix, +) async { + var clazz = className.replaceAll('()', ''); + + String fileName = srcPath.split('/').last; + String name = fileName.split('.').first; + String dirPath = srcPath.replaceAll(fileName, ''); + String testPath = '${dirPath}catalog/instrumented_test/'; + + await Directory(testPath).create(recursive: true); + + String testFile = '$testPath${name}_instrumented_test.dart'; + File file = File(testFile); + + var importParts = classImport.split('/'); + importParts.removeAt(importParts.length - 1); + importParts.add(config['output']); + importParts.add('instrumented_test'); + importParts.add('${name}_instrumented_test.dart'); + + if (await file.exists()) { + print( + '🧪 👌 Test file already exist for $clazz - ${clazz}InstrumentedTest ($testFile)'); + return TestBuilderInfo( + alias: buildTestAlias(4), + clazzName: '${clazz}InstrumentedTest', + import: importParts.join('/'), + ); + } + + print('🧪 Generating test for $clazz - ${clazz}Test ($testFile)'); + + var content = ''' +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget $clazz +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/$name.dummy.dart'; +import '../preview/$name.$prefix.dart'; + +class ${clazz}InstrumentedTestTest { + void main() { + group( + '$clazz - InstrumentedTest Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = ${clazz}Dummy().dummies.first; + final widget = build$clazz(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = ${clazz}Dummy().dummies.first; + final widget = build$clazz(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} + + '''; + + await file.writeAsString(content); + + return TestBuilderInfo( + alias: buildTestAlias(4), + clazzName: '${clazz}InstrumentedTest', + import: importParts.join('/'), + ); +} + +Future generateMainTest( + String basePath, + List tests, +) async { + File file = File('./${basePath}test/catalog_widget_test.dart'); + + print('🧪 Updating catalog test collector (${file.path})'); + + var content = ''' +/// AUTOGENERATED FILE. DO NOT EDIT + +${tests.map((t) { + return 'import \'${t.import}\' as ${t.alias};'; + }).join('\n')} + +void main() { + ${tests.map((t) { + return '${t.alias}.${t.clazzName}().main();'; + }).join('\n')} +} + + '''; + + await file.writeAsString(content); +} + +Future generateMainInstrumentedTest( + String basePath, + List tests, +) async { + File file = File('./${basePath}instrumented_test/catalog_widget_instrumented_test.dart'); + + print('🧪 Updating catalog instrumented test collector (${file.path})'); + + var content = ''' +/// AUTOGENERATED FILE. DO NOT EDIT + +${tests.map((t) { + return 'import \'${t.import}\' as ${t.alias};'; + }).join('\n')} + +void main() { + ${tests.map((t) { + return '${t.alias}.${t.clazzName}().main();'; + }).join('\n')} +} + + '''; + + await file.writeAsString(content); +} + +String buildTestAlias(int size) { + const chars = 'abcdefghijklmnopqrstuvwxyz'; + Random random = Random(); + return String.fromCharCodes(Iterable.generate( + size, (_) => chars.codeUnitAt(random.nextInt(chars.length)))); } String dummyWidgetBuilder(String clazz) { diff --git a/lib/src/bin/tasks/main_task.dart b/lib/src/bin/tasks/main_task.dart index 55d62a6..c26ac99 100644 --- a/lib/src/bin/tasks/main_task.dart +++ b/lib/src/bin/tasks/main_task.dart @@ -1,6 +1,7 @@ import 'base/base_task.dart'; import 'tasks/catalog_task.dart'; import 'tasks/format_task.dart'; +import 'tasks/instrumented_test_task.dart'; import 'tasks/preview_task.dart'; import 'tasks/test_task.dart'; @@ -8,6 +9,7 @@ class MainTask extends BaseTask { final tasks = [ PreviewTask(), TestTask(), + InstrumentedTestTask(), CatalogTask(), FormatTask(), ]; diff --git a/lib/src/bin/tasks/preview_task.dart b/lib/src/bin/tasks/preview_task.dart index 7aec303..55ab55c 100644 --- a/lib/src/bin/tasks/preview_task.dart +++ b/lib/src/bin/tasks/preview_task.dart @@ -1,5 +1,6 @@ import 'base/base_task.dart'; import 'tasks/format_task.dart'; +import 'tasks/instrumented_test_task.dart'; import 'tasks/preview_task.dart' as preview; import 'tasks/test_task.dart'; @@ -7,6 +8,7 @@ class PreviewTask extends BaseTask { final tasks = [ preview.PreviewTask(), TestTask(), + InstrumentedTestTask(), FormatTask(), ]; diff --git a/lib/src/bin/tasks/tasks/format_task.dart b/lib/src/bin/tasks/tasks/format_task.dart index a9d0723..e0a4205 100644 --- a/lib/src/bin/tasks/tasks/format_task.dart +++ b/lib/src/bin/tasks/tasks/format_task.dart @@ -13,12 +13,28 @@ class FormatTask extends BaseTask { stdout.write(resultFix.stdout); stderr.write(resultFix.stderr); - var result = await Process.run( + var resultFormatLib = await Process.run( 'dart', ['format', 'lib/'], workingDirectory: Directory.current.path, ); - stdout.write(result.stdout); - stderr.write(result.stderr); + stdout.write(resultFormatLib.stdout); + stderr.write(resultFormatLib.stderr); + + var resultFormatTest = await Process.run( + 'dart', + ['format', 'test/'], + workingDirectory: Directory.current.path, + ); + stdout.write(resultFormatTest.stdout); + stderr.write(resultFormatTest.stderr); + + var resultFormatInstrumentedTest = await Process.run( + 'dart', + ['format', 'instrumented_test/'], + workingDirectory: Directory.current.path, + ); + stdout.write(resultFormatInstrumentedTest.stdout); + stderr.write(resultFormatInstrumentedTest.stderr); } } diff --git a/lib/src/bin/tasks/tasks/instrumented_test_task.dart b/lib/src/bin/tasks/tasks/instrumented_test_task.dart new file mode 100644 index 0000000..073711e --- /dev/null +++ b/lib/src/bin/tasks/tasks/instrumented_test_task.dart @@ -0,0 +1,71 @@ +import 'dart:io'; + +import 'package:catalog/src/bin/utils/test_builder_info.dart'; + +import '../../preview_builder/preview_builder.dart'; +import '../../utils/configuration.dart'; +import '../base/base_task.dart'; + +class InstrumentedTestTask extends BaseTask { + @override + Future work(List args) async { + final base = args.isEmpty ? '' : '${args.first}/'; + + var appId = loadId(base); + var config = loadConfigFile(base); + + final prefixValue = config['prefix'] ?? 'preview'; + + final dir = Directory('./$base${config['base']}'); + await dir.create(recursive: true); + + final dirOutPut = Directory('./$base${config['base']}/${config['output']}'); + await dirOutPut.create(recursive: true); + + final List entities = + await dir.list(recursive: true).toList(); + + final files = []; + + for (FileSystemEntity fileSystemEntity in entities) { + try { + if (fileSystemEntity is Directory) continue; + if (fileSystemEntity.path.endsWith('.DS_Store')) continue; + final File file = File(fileSystemEntity.path); + if (file.path.contains('.$prefixValue.')) continue; + final content = await file.readAsString(); + if (content.contains('@Preview(')) { + files.add(fileSystemEntity); + } + } catch (e) { + print(e); + } + } + + final test = []; + + for (FileSystemEntity fileSystemEntity in files) { + final File file = File(fileSystemEntity.path); + var p = file.path.split(config['base'])[1]; + var classImport = 'package:$appId$p'; + var preview = await previewOnFile(base, config, file.path); + var previewAnnotation = await findPreviewAnnotation(file.path); + if (previewAnnotation == null) continue; + var className = await findClassName(file.path); + if (className == null) continue; + if (preview == null) continue; + + final testFile = await generateInstrumentedTest( + config, + file.path, + className, + classImport, + prefixValue, + ); + + test.add(testFile); + } + + await generateMainInstrumentedTest(base, test); + } +} diff --git a/lib/src/bin/tasks/tasks/test_task.dart b/lib/src/bin/tasks/tasks/test_task.dart index 7b426ff..b3cf032 100644 --- a/lib/src/bin/tasks/tasks/test_task.dart +++ b/lib/src/bin/tasks/tasks/test_task.dart @@ -1,5 +1,7 @@ import 'dart:io'; +import 'package:catalog/src/bin/utils/test_builder_info.dart'; + import '../../preview_builder/preview_builder.dart'; import '../../utils/configuration.dart'; import '../base/base_task.dart'; @@ -9,6 +11,7 @@ class TestTask extends BaseTask { Future work(List args) async { final base = args.isEmpty ? '' : '${args.first}/'; + var appId = loadId(base); var config = loadConfigFile(base); final prefixValue = config['prefix'] ?? 'preview'; @@ -39,8 +42,12 @@ class TestTask extends BaseTask { } } + final test = []; + for (FileSystemEntity fileSystemEntity in files) { final File file = File(fileSystemEntity.path); + var p = file.path.split(config['base'])[1]; + var classImport = 'package:$appId$p'; var preview = await previewOnFile(base, config, file.path); var previewAnnotation = await findPreviewAnnotation(file.path); if (previewAnnotation == null) continue; @@ -48,11 +55,17 @@ class TestTask extends BaseTask { if (className == null) continue; if (preview == null) continue; - await generateTest( + final testFile = await generateTest( + config, file.path, className, + classImport, prefixValue, ); + + test.add(testFile); } + + await generateMainTest(base, test); } } diff --git a/lib/src/bin/utils/test_builder_info.dart b/lib/src/bin/utils/test_builder_info.dart new file mode 100644 index 0000000..3aa77d4 --- /dev/null +++ b/lib/src/bin/utils/test_builder_info.dart @@ -0,0 +1,11 @@ +class TestBuilderInfo { + String alias; + String clazzName; + String import; + + TestBuilderInfo({ + required this.alias, + required this.clazzName, + required this.import, + }); +} diff --git a/lib/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_view.dart b/lib/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_view.dart deleted file mode 100644 index b1a30fc..0000000 --- a/lib/src/embed/flutter_fanacy_tree_view/flutter_fancy_tree_view.dart +++ /dev/null @@ -1,10 +0,0 @@ -/// A collection of widgets and slivers that helps bringing hierarchical data -/// to life. -library; - -export 'src/folder_button.dart'; -export 'src/sliver_animated_tree.dart'; -export 'src/sliver_tree.dart'; -export 'src/tree_controller.dart'; -export 'src/tree_indentation.dart'; -export 'src/tree_view.dart'; diff --git a/lib/src/embed/flutter_fanacy_tree_view/src/folder_button.dart b/lib/src/embed/flutter_fanacy_tree_view/src/folder_button.dart deleted file mode 100644 index acb9654..0000000 --- a/lib/src/embed/flutter_fanacy_tree_view/src/folder_button.dart +++ /dev/null @@ -1,367 +0,0 @@ -import 'package:flutter/material.dart'; - -/// The default transition builder used by [FolderButton]. -/// -/// Wraps [child] in a [ScaleTransition]. -Widget defaultFolderButtonTransitionBuilder( - Widget child, - Animation animation, -) { - return ScaleTransition(scale: animation, child: child); -} - -/// A wrapper around [IconButton] and [AnimatedSwitcher] that animates between -/// [icon], [openedIcon] and [closedIcon] depending on the value of [isOpen]. -/// -/// The value of [isOpen] is mapped as follows: -/// `null` -> [icon] -> [Icons.article] -/// `true` -> [openedIcon] -> [Icons.folder_open] -/// `false` -> [closedIcon] -> [Icons.folder] -/// -/// Example: -/// ```dart -/// final TreeEntry entry; -/// final TreeController controller; -/// -/// @override -/// Widget build(BuildContext context) { -/// bool? isOpen; -/// VoidCallback? onPressed; -/// -/// if (entry.hasChildren) { -/// isOpen = entry.isExpanded; -/// onPressed = () => controller.toggleExpansion(entry.node); -/// } -/// -/// return FolderButton( -/// isOpen: isOpen, -/// onPressed: onPressed, -/// ); -/// } -/// ``` -/// -/// In the above example, the [isOpen] property is composed depending on the -/// context of a [TreeEntry]. This widget will show [icon] when the entry is a -/// leaf (i.e., has no children), [openedIcon] when the expansion state is set -/// to `true` and [closedIcon] if the expansion state is set to `false`. The -/// [onPressed] callback is set to `null` when the entry is a leaf disabling -/// the button. -class FolderButton extends StatelessWidget { - /// Creates a [FolderButton]. - const FolderButton({ - super.key, - this.isOpen = true, - this.icon = const Icon(Icons.article), - this.openedIcon = const Icon(Icons.folder_open), - this.closedIcon = const Icon(Icons.folder), - this.iconSize, - this.visualDensity, - this.padding = const EdgeInsets.all(8.0), - this.alignment = Alignment.center, - this.splashRadius, - this.focusColor, - this.hoverColor, - this.color, - this.splashColor, - this.highlightColor, - this.disabledColor, - this.onPressed, - this.mouseCursor, - this.focusNode, - this.autofocus = false, - this.tooltip, - this.enableFeedback = true, - this.constraints, - this.style, - this.duration = kThemeAnimationDuration, - this.curve = Curves.linear, - this.transitionBuilder = defaultFolderButtonTransitionBuilder, - }); - - /// Defines which of [icon], [openedIcon] and [closedIcon] is currently shown. - final bool? isOpen; - - /// The icon to show when [isOpen] is set to `null`. - /// - /// Defaults to `Icon(Icons.article)`. - final Widget icon; - - /// The icon to show when [isOpen] is set to `true`. - /// - /// Defaults to `Icon(Icons.folder_open)`. - final Widget openedIcon; - - /// The icon to show when [isOpen] is set to `false`. - /// - /// Defaults to `Icon(Icons.folder)`. - final Widget closedIcon; - - /// The size of the icon inside the button. - /// - /// If null, uses [IconThemeData.size]. If it is also null, the default size - /// is 24.0. - /// - /// The size given here is passed down to the widget in the [icon] property - /// via an [IconTheme]. Setting the size here instead of in, for example, the - /// [Icon.size] property allows the [IconButton] to size the splash area to - /// fit the [Icon]. If you were to set the size of the [Icon] using - /// [Icon.size] instead, then the [IconButton] would default to 24.0 and then - /// the [Icon] itself would likely get clipped. - final double? iconSize; - - /// Defines how compact the icon button's layout will be. - /// - /// {@macro flutter.material.themedata.visualDensity} - /// - /// See also: - /// - /// * [ThemeData.visualDensity], which specifies the [visualDensity] for all - /// widgets within a [Theme]. - final VisualDensity? visualDensity; - - /// The padding around the button's icon. The entire padded icon will react - /// to input gestures. - /// - /// This property must not be null. It defaults to 8.0 padding on all sides. - final EdgeInsetsGeometry padding; - - /// Defines how the icon is positioned within the IconButton. - /// - /// This property must not be null. It defaults to [Alignment.center]. - /// - /// See also: - /// - /// * [Alignment], a class with convenient constants typically used to - /// specify an [AlignmentGeometry]. - /// * [AlignmentDirectional], like [Alignment] for specifying alignments - /// relative to text direction. - final AlignmentGeometry alignment; - - /// The splash radius. - /// - /// If [ThemeData.useMaterial3] is set to true, this will not be used. - /// - /// If null, default splash radius of [Material.defaultSplashRadius] is used. - final double? splashRadius; - - /// The color for the button when it has the input focus. - /// - /// If [ThemeData.useMaterial3] is set to true, this [focusColor] will be mapped - /// to be the [ButtonStyle.overlayColor] in focused state, which paints on top of - /// the button, as an overlay. Therefore, using a color with some transparency - /// is recommended. For example, one could customize the [focusColor] below: - /// - /// ```dart - /// IconButton( - /// focusColor: Colors.orange.withOpacity(0.3), - /// ) - /// ``` - /// - /// Defaults to [ThemeData.focusColor] of the ambient theme. - final Color? focusColor; - - /// The color for the button when a pointer is hovering over it. - /// - /// If [ThemeData.useMaterial3] is set to true, this [hoverColor] will be mapped - /// to be the [ButtonStyle.overlayColor] in hovered state, which paints on top of - /// the button, as an overlay. Therefore, using a color with some transparency - /// is recommended. For example, one could customize the [hoverColor] below: - /// - /// ```dart - /// IconButton( - /// hoverColor: Colors.orange.withOpacity(0.3), - /// ) - /// ``` - /// - /// Defaults to [ThemeData.hoverColor] of the ambient theme. - final Color? hoverColor; - - /// The color to use for the icon inside the button, if the icon is enabled. - /// Defaults to leaving this up to the [icon] widget. - /// - /// The icon is enabled if [onPressed] is not null. - /// - /// ```dart - /// IconButton( - /// color: Colors.blue, - /// onPressed: _handleTap, - /// icon: Icons.widgets, - /// ) - /// ``` - final Color? color; - - /// The primary color of the button when the button is in the down (pressed) state. - /// The splash is represented as a circular overlay that appears above the - /// [highlightColor] overlay. The splash overlay has a center point that matches - /// the hit point of the user touch event. The splash overlay will expand to - /// fill the button area if the touch is held for long enough time. If the splash - /// color has transparency then the highlight and button color will show through. - /// - /// If [ThemeData.useMaterial3] is set to true, this will not be used. Use - /// [highlightColor] instead to show the overlay color of the button when the button - /// is in the pressed state. - /// - /// Defaults to the Theme's splash color, [ThemeData.splashColor]. - final Color? splashColor; - - /// The secondary color of the button when the button is in the down (pressed) - /// state. The highlight color is represented as a solid color that is overlaid over the - /// button color (if any). If the highlight color has transparency, the button color - /// will show through. The highlight fades in quickly as the button is held down. - /// - /// If [ThemeData.useMaterial3] is set to true, this [highlightColor] will be mapped - /// to be the [ButtonStyle.overlayColor] in pressed state, which paints on top - /// of the button, as an overlay. Therefore, using a color with some transparency - /// is recommended. For example, one could customize the [highlightColor] below: - /// - /// ```dart - /// IconButton( - /// highlightColor: Colors.orange.withOpacity(0.3), - /// ) - /// ``` - /// - /// Defaults to the Theme's highlight color, [ThemeData.highlightColor]. - final Color? highlightColor; - - /// The color to use for the icon inside the button, if the icon is disabled. - /// Defaults to the [ThemeData.disabledColor] of the current [Theme]. - /// - /// The icon is disabled if [onPressed] is null. - final Color? disabledColor; - - /// The callback that is called when the button is tapped or otherwise activated. - /// - /// If this is set to null, the button will be disabled. - final VoidCallback? onPressed; - - /// {@macro flutter.material.RawMaterialButton.mouseCursor} - /// - /// If set to null, will default to - /// - [SystemMouseCursors.basic], if [onPressed] is null - /// - [SystemMouseCursors.click], otherwise - final MouseCursor? mouseCursor; - - /// {@macro flutter.widgets.Focus.focusNode} - final FocusNode? focusNode; - - /// {@macro flutter.widgets.Focus.autofocus} - final bool autofocus; - - /// Text that describes the action that will occur when the button is pressed. - /// - /// This text is displayed when the user long-presses on the button and is - /// used for accessibility. - final String? tooltip; - - /// Whether detected gestures should provide acoustic and/or haptic feedback. - /// - /// For example, on Android a tap will produce a clicking sound and a - /// long-press will produce a short vibration, when feedback is enabled. - /// - /// See also: - /// - /// * [Feedback] for providing platform-specific feedback to certain actions. - final bool enableFeedback; - - /// Optional size constraints for the button. - /// - /// When unspecified, defaults to: - /// ```dart - /// const BoxConstraints( - /// minWidth: kMinInteractiveDimension, - /// minHeight: kMinInteractiveDimension, - /// ) - /// ``` - /// where [kMinInteractiveDimension] is 48.0, and then with visual density - /// applied. - /// - /// The default constraints ensure that the button is accessible. - /// Specifying this parameter enables creation of buttons smaller than - /// the minimum size, but it is not recommended. - /// - /// The visual density uses the [visualDensity] parameter if specified, - /// and `Theme.of(context).visualDensity` otherwise. - final BoxConstraints? constraints; - - /// Customizes this button's appearance. - /// - /// Non-null properties of this style override the corresponding - /// properties in [_IconButtonM3.themeStyleOf] and [_IconButtonM3.defaultStyleOf]. - /// The [style] is only used for Material 3 [IconButton]. If [ThemeData.useMaterial3] - /// is set to true, [style] is preferred for icon button customization, and any - /// parameters defined in [style] will override the same parameters in [IconButton]. - /// - /// For example, if [IconButton]'s [visualDensity] is set to [VisualDensity.standard] - /// and [style]'s [visualDensity] is set to [VisualDensity.compact], - /// the icon button will have [VisualDensity.compact] to define the button's layout. - /// - /// Null by default. - final ButtonStyle? style; - - /// The duration of the transition of the icons. - /// - /// Defaults to [kThemeAnimationDuration]. - final Duration duration; - - /// The animation curve to use when transitioning the icons. - /// - /// Defaults to [Curves.linear] - final Curve curve; - - /// The transition funciton used to animate the icons swap. - /// - /// Default to wrapping the icon in a [ScaleTransition]. - /// - /// See also: - /// - /// * [AnimatedSwitcherTransitionBuilder] for more information about - /// how a transition builder should function. - final AnimatedSwitcherTransitionBuilder transitionBuilder; - - Widget get _effectiveIcon { - switch (isOpen) { - case true: - return openedIcon; - case false: - return closedIcon; - case null: - default: - return icon; - } - } - - @override - Widget build(BuildContext context) { - return IconButton( - iconSize: iconSize, - visualDensity: visualDensity, - padding: padding, - alignment: alignment, - splashRadius: splashRadius, - focusColor: focusColor, - hoverColor: hoverColor, - color: color, - splashColor: splashColor, - highlightColor: highlightColor, - disabledColor: disabledColor, - onPressed: onPressed, - mouseCursor: mouseCursor, - focusNode: focusNode, - autofocus: autofocus, - tooltip: tooltip, - enableFeedback: enableFeedback, - constraints: constraints, - style: style, - icon: AnimatedSwitcher( - duration: duration, - switchInCurve: curve, - switchOutCurve: curve, - transitionBuilder: transitionBuilder, - child: KeyedSubtree( - key: Key('FolderButton#$isOpen'), - child: _effectiveIcon, - ), - ), - ); - } -} diff --git a/lib/src/embed/flutter_fanacy_tree_view/src/sliver_animated_tree.dart b/lib/src/embed/flutter_fanacy_tree_view/src/sliver_animated_tree.dart deleted file mode 100644 index 5af82c5..0000000 --- a/lib/src/embed/flutter_fanacy_tree_view/src/sliver_animated_tree.dart +++ /dev/null @@ -1,434 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'sliver_tree.dart'; -import 'tree_controller.dart'; - -// Examples can assume: -// -// class Node { -// Node(this.children); -// List children; -// } -// -// final TreeController treeController = TreeController( -// root: [ -// Node([]), -// ], -// childrenProvider: (Node node) => node.children, -// ); - -/// Signature for a function that takes a widget and an animation to apply -/// transitions if needed. -typedef TreeTransitionBuilder = Widget Function( - BuildContext context, - Widget child, - Animation animation, -); - -/// The default transition builder used by [SliverTree] to animate the expansion -/// state changes of a tree node. -/// -/// Wraps [child] in a [SizeTransition]. -Widget defaultTreeTransitionBuilder( - BuildContext context, - Widget child, - Animation animation, -) { - return SizeTransition(sizeFactor: animation, child: child); -} - -/// A wrapper around [SliverList] that adds tree viewing capabilities with -/// support for automatic expand and collapse animations. -/// -/// Usage: -/// ```dart -/// @override -/// Widget build(BuildContext context) { -/// return CustomScrollView( -/// slivers: [ -/// SliverAnimatedTree( -/// controller: treeController, -/// duration: const Duration(milliseconds, 300), -/// curve: Curves.linear, -/// maxNodesToShowWhenAnimating: 50, -/// nodeBuilder: (BuildContext context, TreeEntry entry) { -/// ... -/// }, -/// ), -/// ], -/// ); -/// } -/// ``` -/// -/// This widget will listen to [controller] and rebuild the inner flat -/// representation of the tree keeping a map of the expansion state of tree -/// nodes to then check if the cached value is different from the current -/// node expansion state when visiting that node during flattening and will -/// mark it to be animated. -/// When a node is marked to animate, its subtree won't be traversed during -/// flattening to later on be rendered in the same list item of the subtree -/// root's node widget. Once the animation completes, the node is removed -/// from the set of animating nodes and the tree is flattened again so the -/// animating subtree can go back to being one list item per node. -/// -/// See also: -/// * [AnimatedTreeView], which covers the [CustomScrollView] boilerplate. -/// * [SliverTree], a tree sliver with no custom behaviors. -class SliverAnimatedTree extends SliverTree { - /// Creates a [SliverAnimatedTree]. - const SliverAnimatedTree({ - super.key, - required super.controller, - required super.nodeBuilder, - this.transitionBuilder = defaultTreeTransitionBuilder, - this.duration = const Duration(milliseconds: 300), - this.curve = Curves.linear, - this.maxNodesToShowWhenAnimating = 50, - }) : assert(maxNodesToShowWhenAnimating > 0); - - /// {@template flutter_fancy_tree_view.SliverAnimatedTree.transitionBuilder} - /// A widget builder used to apply a transition to the expansion state changes - /// of a node subtree when animations are enabled. - /// - /// See also: - /// - /// * [defaultTreeTransitionBuilder] which uses a [SizeTransition]. - /// {@endtemplate} - final TreeTransitionBuilder transitionBuilder; - - /// {@template flutter_fancy_tree_view.SliverAnimatedTree.duration} - /// The default duration to use when animating the expand/collapse operations. - /// - /// Provide a [duration] of `Duration.zero` to disable animations. - /// - /// Defaults to `Duration(milliseconds: 300)`. - /// {@endtemplate} - final Duration duration; - - /// {@template flutter_fancy_tree_view.SliverAnimatedTree.curve} - /// The default curve to use when animating the expand/collapse operations. - /// - /// Defaults to `Curves.linear`. - /// {@endtemplate} - final Curve curve; - - /// {@template flutter_fancy_tree_view.SliverAnimatedTree.maxNodesToShowWhenAnimating} - /// The amount of nodes that are going to be shown on an animating subtree. - /// - /// Must be greater than `0`. - /// - /// When animating the expand/collapse state changes, all descendant nodes - /// whose visibility will change are rendered along with the toggled node, - /// i.e. a [Column] is used, therefore rendering the entire subtree regardless - /// of being a "lazy" rendered view. - /// - /// This value can be used to limit how many nodes are actually rendered - /// during the animation, since there could be cases where not all widgets - /// are visible due to scroll offsets. - /// - /// Defaults to `50`. - /// {@endtemplate} - final int maxNodesToShowWhenAnimating; - - @override - State> createState() => _SliverAnimatedTreeState(); -} - -class _SliverAnimatedTreeState - extends State> { - Map get _expansionStates => _expansionStatesCache ??= {}; - Map? _expansionStatesCache; - - List> _flatTree = const []; - - void _updateFlatTree() { - final Map oldExpansionStates = Map.of(_expansionStates); - - final Map currentExpansionStates = {}; - final List> flatTree = >[]; - - final Visitor> onTraverse; - - if (widget.duration == Duration.zero) { - onTraverse = (TreeEntry entry) { - flatTree.add(entry); - currentExpansionStates[entry.node] = entry.isExpanded; - }; - } else { - onTraverse = (TreeEntry entry) { - flatTree.add(entry); - currentExpansionStates[entry.node] = entry.isExpanded; - - final bool? previousState = oldExpansionStates[entry.node]; - if (previousState != null && previousState != entry.isExpanded) { - _animatingNodes.add(entry.node); - } - }; - } - - widget.controller.depthFirstTraversal( - onTraverse: onTraverse, - descendCondition: (TreeEntry entry) { - if (_animatingNodes.contains(entry.node)) { - // The descendants of a node that is animating are not included in - // the flattened tree since those nodes are going to be rendered in - // a single list item. - return false; - } - return entry.isExpanded; - }, - ); - - _flatTree = flatTree; - _expansionStatesCache = currentExpansionStates; - } - - void _rebuild() => setState(_updateFlatTree); - - final Set _animatingNodes = {}; - - void _onAnimationComplete(T node) { - _animatingNodes.remove(node); - _rebuild(); - } - - List> _buildSubtree(TreeEntry entry) { - final List> subtree = >[]; - widget.controller.depthFirstTraversal( - rootEntry: entry, - onTraverse: subtree.add, - ); - if (subtree.length > widget.maxNodesToShowWhenAnimating) { - return subtree.sublist(0, widget.maxNodesToShowWhenAnimating); - } - return subtree; - } - - @override - void initState() { - super.initState(); - widget.controller.addListener(_rebuild); - _updateFlatTree(); - } - - @override - void didUpdateWidget(covariant SliverAnimatedTree oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.controller != widget.controller) { - oldWidget.controller.removeListener(_rebuild); - widget.controller.addListener(_rebuild); - _updateFlatTree(); - } - } - - @override - void dispose() { - widget.controller.removeListener(_rebuild); - _animatingNodes.clear(); - _flatTree = const []; - _expansionStatesCache = null; - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return SliverList( - delegate: SliverChildBuilderDelegate( - childCount: _flatTree.length, - (BuildContext context, int index) { - final TreeEntry entry = _flatTree[index]; - return _TreeEntry( - key: _SaltedTreeNodeKey(entry.node), - entry: entry, - nodeBuilder: widget.nodeBuilder, - buildFlatSubtree: _buildSubtree, - transitionBuilder: widget.transitionBuilder, - onAnimationComplete: _onAnimationComplete, - curve: widget.curve, - duration: widget.duration, - showSubtree: _animatingNodes.contains(entry.node), - ); - }, - ), - ); - } -} - -class _SaltedTreeNodeKey extends GlobalObjectKey { - const _SaltedTreeNodeKey(super.value); -} - -typedef _FlatSubtreeBuilder = List> Function( - TreeEntry virtualRoot, -); - -class _TreeEntry extends StatefulWidget { - const _TreeEntry({ - super.key, - required this.entry, - required this.nodeBuilder, - required this.buildFlatSubtree, - required this.transitionBuilder, - required this.onAnimationComplete, - required this.curve, - required this.duration, - required this.showSubtree, - }); - - final TreeEntry entry; - final TreeNodeBuilder nodeBuilder; - final _FlatSubtreeBuilder buildFlatSubtree; - - final TreeTransitionBuilder transitionBuilder; - final ValueSetter onAnimationComplete; - final Curve curve; - final Duration duration; - final bool showSubtree; - - @override - State<_TreeEntry> createState() => _TreeEntryState(); -} - -class _TreeEntryState extends State<_TreeEntry> - with SingleTickerProviderStateMixin { - TreeEntry get entry => widget.entry; - T get node => entry.node; - - late final AnimationController animationController; - late final CurveTween curveTween; - - bool isExpanded = false; - - void onAnimationComplete() { - widget.onAnimationComplete(node); - if (!mounted) return; - setState(() {}); - } - - void expand() { - // Sometimes when [isExpanded] changes and [widget.shouldAnimate] is set to - // `false`, the animation value is not reset, then later when a subsequent - // animation starts, the controller is already completed and no animation - // is played at all. - final double? from = animationController.value == 1.0 ? 0.0 : null; - animationController.forward(from: from).whenComplete(onAnimationComplete); - } - - void collapse() { - // Sometimes when [isExpanded] changes and [widget.shouldAnimate] is set to - // `false`, the animation value is not reset, then later when a subsequent - // animation starts, the controller is already completed and no animation - // is played at all. - final double? from = animationController.value == 0.0 ? 1.0 : null; - animationController.reverse(from: from).whenComplete(onAnimationComplete); - } - - @override - void initState() { - super.initState(); - isExpanded = entry.isExpanded; - - curveTween = CurveTween(curve: widget.curve); - animationController = AnimationController( - vsync: this, - value: isExpanded ? 1.0 : 0.0, - duration: widget.duration, - ); - } - - @override - void didUpdateWidget(covariant _TreeEntry oldWidget) { - super.didUpdateWidget(oldWidget); - - curveTween.curve = widget.curve; - animationController.duration = widget.duration; - - final bool expansionState = entry.isExpanded; - - if (isExpanded != expansionState) { - isExpanded = expansionState; - - if (widget.showSubtree) { - isExpanded ? expand() : collapse(); - } - } - } - - @override - void dispose() { - animationController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final Widget tile = widget.nodeBuilder(context, entry); - - late final Widget subtree = _Subtree( - virtualRoot: entry, - nodeBuilder: widget.nodeBuilder, - buildFlatSubtree: widget.buildFlatSubtree, - ); - - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - tile, - if (widget.showSubtree && animationController.isAnimating) - widget.transitionBuilder( - context, - subtree, - animationController.drive(curveTween), - ), - ], - ); - } -} - -class _Subtree extends StatefulWidget { - const _Subtree({ - super.key, - required this.virtualRoot, - required this.nodeBuilder, - required this.buildFlatSubtree, - }); - - final TreeEntry virtualRoot; - final TreeNodeBuilder nodeBuilder; - final _FlatSubtreeBuilder buildFlatSubtree; - - @override - State<_Subtree> createState() => _SubtreeState(); -} - -class _SubtreeState extends State<_Subtree> { - late List> virtualEntries; - - @override - void initState() { - super.initState(); - virtualEntries = widget.buildFlatSubtree(widget.virtualRoot); - } - - @override - void dispose() { - virtualEntries = const []; - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return IgnorePointer( - ignoring: true, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - for (final TreeEntry virtualEntry in virtualEntries) - widget.nodeBuilder(context, virtualEntry), - ], - ), - ); - } -} diff --git a/lib/src/embed/flutter_fanacy_tree_view/src/sliver_tree.dart b/lib/src/embed/flutter_fanacy_tree_view/src/sliver_tree.dart deleted file mode 100644 index 18fc75a..0000000 --- a/lib/src/embed/flutter_fanacy_tree_view/src/sliver_tree.dart +++ /dev/null @@ -1,124 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'tree_controller.dart'; - -// Examples can assume: -// -// class Node { -// Node(this.children); -// List children; -// } -// -// final TreeController treeController = TreeController( -// root: [ -// Node([]), -// ], -// childrenProvider: (Node node) => node.children, -// ); - -/// Signature of a widget builder function for tree views. -typedef TreeNodeBuilder = Widget Function( - BuildContext context, - TreeEntry entry, -); - -/// A wrapper around [SliverList] that adds basic tree viewing capabilities. -/// -/// Usage: -/// ```dart -/// @override -/// Widget build(BuildContext context) { -/// return CustomScrollView( -/// slivers: [ -/// SliverTree( -/// controller: treeController, -/// nodeBuilder: (BuildContext context, TreeEntry entry) { -/// ... -/// }, -/// ), -/// ], -/// ); -/// } -/// ``` -/// -/// See also: -/// * [TreeView], which covers the [CustomScrollView] boilerplate. -/// * [AnimatedTreeView], a [TreeView] that animates the expansion state changes -/// of tree nodes. -class SliverTree extends StatefulWidget { - /// Creates a [SliverTree]. - const SliverTree({ - super.key, - required this.controller, - required this.nodeBuilder, - }); - - /// {@template flutter_fancy_tree_view.SliverTree.controller} - /// The object responsible for providing access to tree nodes and its states. - /// - /// This widget will listen to the notifications of this controller and - /// rebuild the internal flat represetantion of the tree to make sure the - /// presented tree view is always up to date. - /// {@endtemplate} - final TreeController controller; - - /// {@template flutter_fancy_tree_view.SliverTree.nodeBuilder} - /// Callback used to map tree nodes into widgets. - /// - /// The `TreeEntry entry` parameter contains important information about - /// the current tree context of the particular [TreeEntry.node] that it holds, - /// like the index, level, expansion state, parent, etc. - /// {@endtemplate} - final TreeNodeBuilder nodeBuilder; - - @override - State> createState() => _SliverTreeState(); -} - -class _SliverTreeState extends State> { - List> _flatTree = const []; - - void _updateFlatTree() { - final List> flatTree = []; - widget.controller.depthFirstTraversal(onTraverse: flatTree.add); - _flatTree = flatTree; - } - - void _rebuild() => setState(_updateFlatTree); - - @override - void initState() { - super.initState(); - widget.controller.addListener(_rebuild); - _updateFlatTree(); - } - - @override - void didUpdateWidget(covariant SliverTree oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.controller != widget.controller) { - oldWidget.controller.removeListener(_rebuild); - widget.controller.addListener(_rebuild); - _updateFlatTree(); - } - } - - @override - void dispose() { - widget.controller.removeListener(_rebuild); - _flatTree = const []; - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return SliverList( - delegate: SliverChildBuilderDelegate( - childCount: _flatTree.length, - (BuildContext context, int index) { - return widget.nodeBuilder(context, _flatTree[index]); - }, - ), - ); - } -} diff --git a/lib/src/embed/flutter_fanacy_tree_view/src/tree_controller.dart b/lib/src/embed/flutter_fanacy_tree_view/src/tree_controller.dart deleted file mode 100644 index 3bcbf30..0000000 --- a/lib/src/embed/flutter_fanacy_tree_view/src/tree_controller.dart +++ /dev/null @@ -1,536 +0,0 @@ -import 'package:flutter/foundation.dart'; - -/// The default level used for root nodes when flattening the tree. -const int treeRootLevel = 0; - -/// Signature of a function that takes a `T` node and returns an `Iterable`. -/// -/// Used to get the children of a node in a tree. -typedef ChildrenProvider = Iterable Function(T node); - -/// Signature of a function that takes a `T` node and returns a `T?` parent. -/// -/// Used to get the parent of a node in a tree. -typedef ParentProvider = T? Function(T node); - -/// Signature of a function used to visit nodes during tree traversal. -typedef Visitor = void Function(T node); - -/// Signature of a function that takes a `T` node and returns a `bool`. -/// -/// Used when traversing a tree to decide if the children of [node] should be -/// traversed or skipped. -typedef DescendCondition = bool Function(T node); - -/// Signature of a function that takes a `T` node and returns a `bool`. -/// -/// Used when traversing the tree in breadth first order to decide whether the -/// traversal should stop. -typedef ReturnCondition = bool Function(T node); - -/// A controller used to dynamically manage the state of a tree. -/// -/// Whenever this controller notifies its listeners any attached tree views -/// will assume that the tree structure changed in some way and will rebuild -/// their internal flat representaton of the tree, showing/hiding the updated -/// nodes (if any). -/// -/// Usage: -/// ```dart -/// class Node { -/// Node(this.children); -/// List children; -/// } -/// -/// final TreeController treeController = TreeController( -/// roots: [ -/// Node([]), -/// ], -/// childrenProvider: (Node node) => node.children, -/// ); -/// ``` -/// -/// The default implementations of [getExpansionState] and [setExpansionState] -/// use a [Set] to manage the expansion state of tree nodes as follows: -/// - getExpansionState(node) = [Set.contains] -/// - setExpansionState(node, true) = [Set.add] -/// - setExpansionState(node, false) = [Set.remove] -/// -/// Those methods can be overridden to use other data structures if desired. -/// Example: -/// ```dart -/// class Node { -/// bool isExpanded = false; -/// } -/// -/// class MyTreeController extends TreeController { -/// @override -/// bool getExpansionState(Node node) => node.isExpanded; -/// -/// // Do not call `notifyListeners` from this method as it is called many -/// // times recursively in cascading operations. -/// @override -/// void setExpansionState(Node node, bool expanded) { -/// node.isExpanded = expanded; -/// } -/// } -/// ``` -class TreeController with ChangeNotifier { - /// Creates a [TreeController]. - /// - /// The [roots] parameter should contain all nodes that occupy the level `0` - /// of the tree, these nodes are going to be used as a starting point when - /// traversing the tree and building tree views. - TreeController({ - required Iterable roots, - required this.childrenProvider, - }) : _roots = roots; - - /// The roots of the tree. - /// - /// These nodes are used as a starting point when traversing the tree. - Iterable get roots => _roots; - Iterable _roots; - set roots(Iterable nodes) { - if (nodes == _roots) return; - _roots = nodes; - rebuild(); - } - - /// A callback used when building the flat representation of the tree to get - /// the direct children of the tree node passed to it. - /// - /// Avoid doing heavy computations in this callback since it is going to be - /// called a lot when traversing the tree. - /// - /// Example using nested objects: - /// ```dart - /// class Node { - /// List children; - /// } - /// - /// Iterable childrenProvider(Node node) => node.children; - /// ``` - /// - /// Example using a Map cache: - /// ```dart - /// class Data { - /// final int id; - /// } - /// - /// final Map> childrenCache = >{}; - /// - /// Iterable childrenProvider(Data parent) { - /// return childrenCache[parent.id] ?? const Iterable.empty(); - /// }, - /// ``` - /// - /// Do not attempt to load the children of a node in this callback as it - /// would significantly slow down tree traversal which might couse the ui to - /// hang. Prefer doing such operations on a user interaction (e.g., a button - /// press, keyboard shortcut, etc.). When lazy loading, temporarily return - /// an empty iterable so tree traversal can continue. Once the loading is - /// done, set the expansion state of the parent node to `true` and call - /// [rebuild] to reveal the loaded nodes. - final ChildrenProvider childrenProvider; - - Set get _expandedNodes => _expandedNodesCache ??= {}; - Set? _expandedNodesCache; - - /// The current expansion state of [node]. - /// - /// If this method returns `true`, the children of [node] should be visible - /// in tree views. - bool getExpansionState(T node) { - return _expandedNodesCache?.contains(node) ?? false; - } - - /// Updates the expansion state of [node] to the value of [expanded]. - /// - /// When overriding this method, do not call `notifyListeners` as this may be - /// called many times recursively in cascading operations. - void setExpansionState(T node, bool expanded) { - expanded ? _expandedNodes.add(node) : _expandedNodes.remove(node); - } - - /// Notify listeners that the tree structure changed in some way. - /// - /// Call this method whenever the tree nodes are updated (i.e., expansion - /// state changed, node added/removed/reordered, etc...), so that listeners - /// may handle the updated values. Most methods of this controller (like - /// expand, collapse, etc.) already call [rebuild] implicitly. - /// - /// Example: - /// ```dart - /// class Node { - /// List children; - /// } - /// - /// TreeController controller = ...; - /// - /// void addChildren(Node parent, Iterable children) { - /// parent.children.addAll(children); - /// controller.rebuild(); - /// } - ///``` - void rebuild() => notifyListeners(); - - void _collapse(T node) => setExpansionState(node, false); - void _expand(T node) => setExpansionState(node, true); - - /// Updates the expansion state of [node] to the opposite state, then calls - /// [rebuild]. - void toggleExpansion(T node) { - setExpansionState(node, !getExpansionState(node)); - rebuild(); - } - - /// Sets the expansion state of [node] to `true`, then calls [rebuild]. - /// - /// If [node] is already expanded, nothing happens. - void expand(T node) { - if (getExpansionState(node)) return; - _expand(node); - rebuild(); - } - - /// Sets the expansion state of [node] to `false`, then calls [rebuild]. - /// - /// If [node] is already collapsed, nothing happens. - void collapse(T node) { - if (!getExpansionState(node)) return; - _collapse(node); - rebuild(); - } - - void _applyCascadingAction(Iterable nodes, Visitor action) { - for (final T node in nodes) { - action(node); - _applyCascadingAction(childrenProvider(node), action); - } - } - - /// Traverses the subtrees of [nodes] in depth first order expanding every - /// visited node, then calls [rebuild]. - void expandCascading(Iterable nodes) { - if (nodes.isEmpty) return; - _applyCascadingAction(nodes, _expand); - rebuild(); - } - - /// Traverses the subtrees of [nodes] in depth first order collapsing every - /// visited node, then calls [rebuild]. - void collapseCascading(Iterable nodes) { - if (nodes.isEmpty) return; - _applyCascadingAction(nodes, _collapse); - rebuild(); - } - - /// Expands all nodes of this tree recursively. - /// - /// This method delegates its call to [expandCascading] passing in [roots] - /// as the nodes to be expanded. - void expandAll() => expandCascading(roots); - - /// Collapses all nodes of this tree recursively. - /// - /// This method delegates its call to [collapseCascading] passing in [roots] - /// as the nodes to be collapsed. - void collapseAll() => collapseCascading(roots); - - /// Walks up the ancestors of [node] setting their expansion state to `true`. - /// Note: [node] is not expanded by this method. - /// - /// This can be used to reveal a hidden node (e.g. when searching for a node - /// in a search view). - /// - /// [parentProvider] should return the direct parent of the given node or - /// `null` if the root node is reached, this callback is used to traverse the - /// ancestors of [node]. - void expandAncestors(T node, ParentProvider parentProvider) { - T? current = parentProvider(node); - - if (current == null) return; - - while (current != null) { - _expand(current); - current = parentProvider(current); - } - - rebuild(); - } - - /// Whether all root nodes of this tree are expanded. - bool get areAllRootsExpanded => roots.every(getExpansionState); - - /// Whether all root nodes of this tree are collapsed. - bool get areAllRootsCollapsed => !roots.any(getExpansionState); - - /// Whether **all** nodes of this tree are expanded. - /// - /// Traverses the tree in breadth first order checking the expansion state of - /// each visited node. The traversal will return early if it finds a collapsed - /// node. - bool get isTreeExpanded { - bool allNodesExpanded = false; - - breadthFirstSearch( - returnCondition: (T node) { - final bool isExpanded = getExpansionState(node); - allNodesExpanded = isExpanded; - // Stop the traversal if [node] is not expanded - return !isExpanded; - }, - ); - - return allNodesExpanded; - } - - /// Whether **all** nodes of this tree are collapsed. - /// - /// Traverses the tree in breadth first order checking the expansion state of - /// each visited node. The traversal will return early if it finds an expanded - /// node. - bool get isTreeCollapsed { - bool allNodesCollapsed = true; - - breadthFirstSearch( - returnCondition: (T node) { - final bool isExpanded = getExpansionState(node); - allNodesCollapsed = !isExpanded; - // Stop the traversal if [node] is expanded - return isExpanded; - }, - ); - - return allNodesCollapsed; - } - - /// Traverses the subtrees of [startingNodes] in breadth first order. If - /// [startingNodes] is not provided, [roots] will be used instead. - /// - /// [descendCondition] is used to determine if the descendants of the node - /// passed to it should be traversed. When not provided, defaults to - /// [alwaysReturnsTrue], a function that always returns `true` which leads - /// to every node on the tree being visited by this traversal. - /// - /// [returnCondition] is used as a predicate to decide if the iteration should - /// be stopped. If this callback returns `true` the node that was passed to - /// it is returned from this method. When not provided, defaults to - /// [alwaysReturnsFalse], a function that always returns `false` which leads - /// to every node on the tree being visited by this traversal. - /// - /// An optional [onTraverse] callback can be provided to apply an action to - /// each visited node. This callback is called prior to [returnCondition] and - /// [descendCondition] making it possible to update a node before checking - /// its properties. - T? breadthFirstSearch({ - Iterable? startingNodes, - DescendCondition descendCondition = alwaysReturnsTrue, - ReturnCondition returnCondition = alwaysReturnsFalse, - Visitor? onTraverse, - }) { - final List nodes = List.of(startingNodes ?? roots); - - while (nodes.isNotEmpty) { - final T node = nodes.removeAt(0); - - onTraverse?.call(node); - - if (returnCondition(node)) { - return node; - } - - if (descendCondition(node)) { - nodes.addAll(childrenProvider(node)); - } - } - - return null; - } - - /// Traverses the subtrees of [roots] creating [TreeEntry] instances for - /// each visited node. - /// - /// Every new [TreeEntry] instance is provided to [onTraverse] right after it - /// is created, before descending into its subtrees. - /// - /// [descendCondition] is used to determine if the descendants of the entry - /// passed to it should be traversed. When not provided, defaults to - /// `(TreeEntry entry) => entry.isExpanded`. - /// - /// If [rootEntry] is provided, its children will be used instead of [roots] - /// as the roots during traversal. This entry can be used to build a subtree - /// keeping the context of the ancestors in the main tree. This parameter - /// is used by [SliverAnimatedTree] when animating the expand and collapse - /// operations to animate subtrees in and out of the view without losing - /// indentation context of the main tree. - void depthFirstTraversal({ - required Visitor> onTraverse, - DescendCondition>? descendCondition, - TreeEntry? rootEntry, - }) { - final DescendCondition> shouldDescend = - descendCondition ?? defaultDescendCondition; - - int treeIndex = 0; - - void createTreeEntriesRecursively({ - required TreeEntry? parent, - required Iterable nodes, - required int level, - }) { - TreeEntry? entry; - - for (final T node in nodes) { - final Iterable children = childrenProvider(node); - entry = TreeEntry( - parent: parent, - node: node, - index: treeIndex++, - isExpanded: getExpansionState(node), - level: level, - hasChildren: children.isNotEmpty, - ); - - onTraverse(entry); - - if (shouldDescend(entry) && entry.hasChildren) { - createTreeEntriesRecursively( - parent: entry, - nodes: children, - level: level + 1, - ); - } - } - - entry?._hasNextSibling = false; - } - - if (rootEntry != null) { - createTreeEntriesRecursively( - parent: rootEntry, - nodes: childrenProvider(rootEntry.node), - level: rootEntry.level + 1, - ); - } else { - createTreeEntriesRecursively( - parent: null, - nodes: roots, - level: treeRootLevel, - ); - } - } - - /// The default [DescendCondition] used by [depthFirstTraversal]. - @visibleForTesting - bool defaultDescendCondition(TreeEntry entry) => entry.isExpanded; - - @override - void dispose() { - _roots = const Iterable.empty(); - _expandedNodesCache = null; - super.dispose(); - } -} - -/// A function that can take a nullable [Object] and will always return `true`. -/// -/// Used in other function declarations as a constant default parameter. -bool alwaysReturnsTrue([Object? _]) => true; - -/// A function that can take a nullable [Object] and will always return `false`. -/// -/// Used in other function declarations as a constant default parameter. -bool alwaysReturnsFalse([Object? _]) => false; - -/// Used to store useful information about [node] in a tree. -/// -/// Instances of this class are short lived, created by [TreeController] -/// when traversing the tree; each traversal creates a new [TreeEntry] -/// for each visited node with up to date values. -/// -/// To make sure that tree views are always up to date make sure to call -/// [TreeController.rebuild] to notify its listeners that the tree structure -/// changed in some way and they should update their cached values. -class TreeEntry with Diagnosticable { - /// Creates a [TreeEntry]. - TreeEntry({ - required this.parent, - required this.node, - required this.index, - required this.level, - required this.isExpanded, - required this.hasChildren, - bool hasNextSibling = true, - }) : _hasNextSibling = hasNextSibling; - - /// The direct parent of [node] on the tree, which was collected during - /// traversal. - final TreeEntry? parent; - - /// The tree node that originated this entry. - final T node; - - /// The index of [node] in the flat tree list that originated this entry. - final int index; - - /// The level of the node that owns this entry on the tree. Example: - /// - /// 0 1 2 3 - /// A ⋅ ⋅ ⋅ - /// └─ B ⋅ ⋅ - /// ⋅ ├─ C ⋅ - /// ⋅ │ └─ D - /// ⋅ └─ E - /// F ⋅ - /// └─ G - final int level; - - /// The expansion state of [node]. - /// - /// This value may have changed since this entry was created. - final bool isExpanded; - - /// Whether [node] has any child nodes. - /// - /// This value is gotten from calling [TreeController.childrenProvider] with - /// [node] an checking if the returned iterable is not empty. - /// - /// This value may have changed since this entry was created. - final bool hasChildren; - - /// Whether the node that owns this entry has another node after it at the - /// same level. - /// - /// Used when painting lines to decide if a node should have a vertical line - /// that connects it to its next sibling. If a node is the last child of its - /// parent, a half vertical line "└─" is painted instead of a full one "├─". - /// - /// Example: - /// - /// Root - /// ├─ Node <- `hasNextSibling = true` - /// ├─ Node <- `hasNextSibling = true` - /// └─ Node <- `hasNextSibling = false` - bool get hasNextSibling => _hasNextSibling; - bool _hasNextSibling; - - /// Whether this entry should skip being indented. - /// - /// Nodes with a level smaller or equal to [treeRootLevel] are not indented. - bool get skipIndentAndPaint => level <= treeRootLevel; - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties - ..add(DiagnosticsProperty('parent node', parent?.node)) - ..add(DiagnosticsProperty('node', node)) - ..add(DiagnosticsProperty('index', index)) - ..add(DiagnosticsProperty('expanded', isExpanded)) - ..add(DiagnosticsProperty('level', level)) - ..add(DiagnosticsProperty('has children', hasChildren)) - ..add(DiagnosticsProperty('has next sibling', hasNextSibling)); - } -} diff --git a/lib/src/embed/flutter_fanacy_tree_view/src/tree_indentation.dart b/lib/src/embed/flutter_fanacy_tree_view/src/tree_indentation.dart deleted file mode 100644 index 7a746bf..0000000 --- a/lib/src/embed/flutter_fanacy_tree_view/src/tree_indentation.dart +++ /dev/null @@ -1,508 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'tree_controller.dart' show TreeEntry; - -/// Widget responsible for indenting tree nodes and painting lines (if enabled). -/// -/// Check out the factory constructors of [IndentGuide] to discover the -/// available indent guide decorations. -/// -/// Example: -/// ```dart -/// final TreeEntry entry; -/// -/// @override -/// Widget build(BuildContext context) { -/// return TreeIndentation( -/// entry: entry, -/// guide: IndentGuide.connectingLines( -/// indent: 40, -/// color: Colors.grey, -/// thickness: 1.0, -/// origin: 0.5, -/// roundCorners: true, -/// ), -/// child: ... -/// ); -/// } -/// ``` -/// -/// If [guide] is not provided, [DefaultIndentGuide.of] will be used instead. -class TreeIndentation extends StatelessWidget { - /// Creates a [TreeIndentation]. - /// - /// If [guide] is not provided, [DefaultIndentGuide.of] will be used instead. - const TreeIndentation({ - super.key, - required this.child, - required this.entry, - this.guide, - }); - - /// The widget that is going to be displayed to the side of the indentation. - final Widget child; - - /// The [TreeEntry] that will provide the relevant details (i.e., level, - /// line offsets, etc.) when indenting and/or painting indent guides. - final TreeEntry entry; - - /// The configuration used to indent and paint lines (if enabled). - /// - /// If not provided, [DefaultIndentGuide.of] will be used. - /// - /// Check out the factory constructors of [IndentGuide] to discover the - /// available indent guide decorations. - final IndentGuide? guide; - - @override - Widget build(BuildContext context) { - if (entry.skipIndentAndPaint) { - return child; - } - - final IndentGuide effectiveGuide = guide ?? DefaultIndentGuide.of(context); - return effectiveGuide.wrap(context, child, entry); - } -} - -/// An [InheritedTheme] that provides a default [IndentGuide] to its widget tree. -/// -/// The [TreeIndentation] widget will use the value returned from -/// [DefaultIndentGuide.of] if its internal [TreeIndentation.guide] is `null`. -/// -/// If [TreeIndentation.guide] is `null` and there's no [DefaultIndentGuide] in -/// its context, a default [ConnectingLinesGuide] will be returned. -/// -/// Check out the factory constructors of [IndentGuide] to discover the -/// available indent guide decorations. -class DefaultIndentGuide extends InheritedTheme { - /// Creates a [DefaultIndentGuide]. - const DefaultIndentGuide({ - super.key, - required super.child, - required this.guide, - }); - - /// The default [IndentGuide] provided to the widget tree of [child]. - /// - /// Check out the factory constructors of [IndentGuide] to discover the - /// available indent guide decorations. - final IndentGuide guide; - - /// The [IndentGuide] from the closest instance of this class that encloses - /// the given context. - /// - /// If there is no [DefaultIndentGuide] ancestor in the widget tree at the - /// given context, then this will return a [ConnectingLinesGuide] with its - /// default constructor values. - /// - /// Typical usage is as follows: - /// - /// ```dart - /// IndentGuide guide = DefaultIndentGuide.of(context); - /// ``` - static IndentGuide of(BuildContext context) { - final DefaultIndentGuide? instance = - context.dependOnInheritedWidgetOfExactType(); - - return instance?.guide ?? const ConnectingLinesGuide(); - } - - @override - bool updateShouldNotify(DefaultIndentGuide oldWidget) { - return oldWidget.guide != guide; - } - - @override - Widget wrap(BuildContext context, Widget child) { - return DefaultIndentGuide(guide: guide, child: child); - } -} - -/// The configuration used to indent and paint optional guides for tree nodes. -/// -/// This indent guide only indents tree nodes without decorations. Check out the -/// factory constructors of this class to discover the available indent guide -/// decorations. -class IndentGuide { - /// Creates an [IndentGuide]. - const IndentGuide({ - this.indent = 40.0, - }) : assert(indent >= 0.0); - - /// Convenient constructor to create a [ConnectingLinesGuide]. - const factory IndentGuide.connectingLines({ - double indent, - Color color, - double thickness, - double origin, - bool roundCorners, - }) = ConnectingLinesGuide; - - /// Convenient constructor to create a [ScopingLinesGuide]. - const factory IndentGuide.scopingLines({ - double indent, - Color color, - double thickness, - double origin, - }) = ScopingLinesGuide; - - /// The amount of indent to apply for each level of the tree. - /// - /// The indentation of tree nodes is calculated as follows: - /// ```dart - /// final TreeEntry entry; - /// final IndentGuide guide; - /// final double indentation = entry.level * guide.indent; - /// ``` - final double indent; - - /// Method used to wrap [child] in the desired decoration/painting. - /// - /// Subclasses must override this method to customize whats shown inside of - /// [TreeIndentation]. - /// - /// See also: - /// * [AbstractLineGuide], an interface for working with line painting; - Widget wrap(BuildContext context, Widget child, TreeEntry entry) { - return Padding( - padding: EdgeInsetsDirectional.only(start: entry.level * indent), - child: child, - ); - } - - @override - int get hashCode => indent.hashCode; - - @override - operator ==(Object other) { - if (identical(other, this)) return true; - - return other.runtimeType == runtimeType && - other is IndentGuide && - other.indent == indent; - } -} - -/// An interface for configuring how to paint line guides in the indentation of -/// a tree node. -/// -/// Check out the factory constructors of [IndentGuide] to discover the -/// available indent guide decorations. -abstract class AbstractLineGuide extends IndentGuide { - /// Constructor with requried parameters for building the indent line guides. - const AbstractLineGuide({ - super.indent, - this.color = Colors.grey, - this.thickness = 2.0, - this.origin = 0.5, - }) : assert(thickness >= 0.0), - assert( - 0.0 <= origin && origin <= 1.0, - '`origin` must be a value between `0.0` and `1.0`.', - ), - originOffset = indent - (indent * origin); - - /// The color to use when painting the lines on the canvas. - /// - /// Defaults to [Colors.grey]. - final Color color; - - /// The width each line should have. - /// - /// Defaults to `2.0`. - final double thickness; - - /// Defines where horizontally inside [indent] to start painting the vertical - /// lines. - /// - /// The [originOffset] is calculated from [indent] and [origin]: - /// ```dart - /// final double originOffset = indent - (indent * origin); - /// ``` - /// - /// Must be a value between `0.0` and `1.0`, Being: - /// - `0.0`: start; - /// - `0.5`: center; - /// - `1.0`: end; - final double origin; - - /// The value that results from `indent - (indent * origin)`. - /// - /// Used when painting to horizontally position a line on each [indent] level. - final double originOffset; - - /// Subclasses must override this method to provide the [CustomPainter] that - /// will handle line painting. - CustomPainter createPainter(BuildContext context, TreeEntry entry); - - /// Creates the [Paint] object that will be used to paint lines. - Paint createPaint() => Paint() - ..color = color - ..strokeWidth = thickness - ..style = PaintingStyle.stroke; - - /// Calculates the origin offset of the line drawn for the given [level]. - double offsetOfLevel(int level) => (level * indent) - originOffset; - - @override - Widget wrap(BuildContext context, Widget child, TreeEntry entry) { - return RepaintBoundary( - child: CustomPaint( - painter: createPainter(context, entry), - child: super.wrap(context, child, entry), - ), - ); - } -} - -/// The [IndentGuide] configuration for painting vertical lines at every level -/// of the tree. -/// -/// Check out the factory constructors of [IndentGuide] to discover the -/// available indent guide decorations. -class ScopingLinesGuide extends AbstractLineGuide { - /// Creates a [ScopingLinesGuide]. - const ScopingLinesGuide({ - super.indent, - super.color, - super.thickness, - super.origin, - }); - - @override - CustomPainter createPainter(BuildContext context, TreeEntry entry) { - return _ScopingLinesPainter( - guide: this, - nodeLevel: entry.level, - textDirection: Directionality.maybeOf(context), - ); - } - - /// Creates a copy of this indent guide but with the given fields replaced - /// with the new values. - ScopingLinesGuide copyWith({ - double? indent, - Color? color, - double? thickness, - double? origin, - }) { - return ScopingLinesGuide( - indent: indent ?? this.indent, - color: color ?? this.color, - thickness: thickness ?? this.thickness, - origin: origin ?? this.origin, - ); - } - - @override - int get hashCode => Object.hash( - indent, - color, - thickness, - origin, - ); - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other.runtimeType == runtimeType && - other is ScopingLinesGuide && - other.indent == indent && - other.color == color && - other.thickness == thickness && - other.origin == origin; - } -} - -class _ScopingLinesPainter extends CustomPainter { - _ScopingLinesPainter({ - required this.guide, - required this.nodeLevel, - required this.textDirection, - }); - - final ScopingLinesGuide guide; - final int nodeLevel; - final TextDirection? textDirection; - - @override - void paint(Canvas canvas, Size size) { - late double Function(int level) calculateOffset; - - if (textDirection == TextDirection.rtl) { - calculateOffset = (int level) => size.width - guide.offsetOfLevel(level); - } else { - calculateOffset = guide.offsetOfLevel; - } - - final Path path = Path(); - - for (int level = 1; level <= nodeLevel; level++) { - final double x = calculateOffset(level); - path - ..moveTo(x, size.height) - ..lineTo(x, 0); - } - - canvas.drawPath(path, guide.createPaint()); - } - - @override - bool shouldRepaint(covariant _ScopingLinesPainter oldDelegate) => - oldDelegate.guide != guide || - oldDelegate.nodeLevel != nodeLevel || - oldDelegate.textDirection != textDirection; -} - -/// The [IndentGuide] configuration for painting vertical lines that have a -/// horizontal connection to its tree node. -/// -/// Check out the factory constructors of [IndentGuide] to discover the -/// available indent guide decorations. -class ConnectingLinesGuide extends AbstractLineGuide { - /// Creates a [ConnectingLinesGuide]. - const ConnectingLinesGuide({ - super.indent, - super.color, - super.thickness, - super.origin, - this.roundCorners = false, - }); - - /// Determines if the connection between a horizontal and a vertical line - /// should be rounded. - final bool roundCorners; - - @override - CustomPainter createPainter(BuildContext context, TreeEntry entry) { - return _ConnectingLinesPainter( - guide: this, - entry: entry, - textDirection: Directionality.maybeOf(context), - ); - } - - /// Creates a copy of this indent guide but with the given fields replaced - /// with the new values. - ConnectingLinesGuide copyWith({ - double? indent, - Color? color, - double? thickness, - double? origin, - bool? roundCorners, - }) { - return ConnectingLinesGuide( - indent: indent ?? this.indent, - color: color ?? this.color, - thickness: thickness ?? this.thickness, - origin: origin ?? this.origin, - roundCorners: roundCorners ?? this.roundCorners, - ); - } - - @override - int get hashCode => Object.hash( - indent, - color, - thickness, - origin, - roundCorners, - ); - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other.runtimeType == runtimeType && - other is ConnectingLinesGuide && - other.indent == indent && - other.color == color && - other.thickness == thickness && - other.origin == origin && - other.roundCorners == roundCorners; - } -} - -class _ConnectingLinesPainter extends CustomPainter { - _ConnectingLinesPainter({ - required this.guide, - required this.entry, - this.textDirection, - }) : indentation = entry.level * guide.indent; - - final ConnectingLinesGuide guide; - final TreeEntry entry; - final TextDirection? textDirection; - final double indentation; - - void runForEachAncestorLevelThatHasNextSibling( - void Function(int level) action, - ) { - TreeEntry? current = entry; - while (current != null && current.level > 0) { - if (current.hasNextSibling) { - action(current.level); - } - current = current.parent; - } - } - - @override - void paint(Canvas canvas, Size size) { - late double connectionEnd; - late double connectionStart; - late double Function(int level) calculateOffset; - - if (textDirection == TextDirection.rtl) { - connectionEnd = size.width - indentation; - connectionStart = connectionEnd + guide.originOffset; - calculateOffset = (int level) => size.width - guide.offsetOfLevel(level); - } else { - connectionEnd = indentation; - connectionStart = indentation - guide.originOffset; - calculateOffset = guide.offsetOfLevel; - } - - final Path path = Path(); - - // Add vertical lines - runForEachAncestorLevelThatHasNextSibling((int level) { - final double x = calculateOffset(level); - path - ..moveTo(x, size.height) - ..lineTo(x, 0); - }); - - // Add connection - - final double y = size.height * 0.5; - - path.moveTo(connectionStart, 0.0); - - if (guide.roundCorners) { - path.quadraticBezierTo(connectionStart, y, connectionEnd, y); - } else { - // if [entry] has a sibling after it, a full vertical line was - // painted at [entry.level] and we only need to move to the start - // of the horizontal line, otherwise add half of a vertical line - // to connect to the horizontal one. - if (entry.hasNextSibling) { - path.moveTo(connectionStart, y); - } else { - path.lineTo(connectionStart, y); - } - - path.lineTo(connectionEnd, y); - } - - canvas.drawPath(path, guide.createPaint()); - } - - @override - bool shouldRepaint(covariant _ConnectingLinesPainter oldDelegate) => - oldDelegate.entry != entry || - oldDelegate.textDirection != textDirection || - oldDelegate.guide != guide; -} diff --git a/lib/src/embed/flutter_fanacy_tree_view/src/tree_view.dart b/lib/src/embed/flutter_fanacy_tree_view/src/tree_view.dart deleted file mode 100644 index 0a4ee6b..0000000 --- a/lib/src/embed/flutter_fanacy_tree_view/src/tree_view.dart +++ /dev/null @@ -1,152 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'sliver_animated_tree.dart'; -import 'sliver_tree.dart'; -import 'tree_controller.dart'; - -// Examples can assume: -// -// class Node { -// Node(this.children); -// List children; -// } -// -// final TreeController treeController = TreeController( -// root: [ -// Node([]), -// ], -// childrenProvider: (Node node) => node.children, -// ); - -/// A widget used to visualize tree hierarchies. -/// -/// Usage: -/// ```dart -/// @override -/// Widget build(BuildContext context) { -/// return TreeView( -/// treeController: treeController, -/// nodeBuilder: (BuildContext context, TreeEntry entry) { -/// ... -/// }, -/// ); -/// } -/// ``` -/// -/// See also: -/// * [SliverTree], which is created internally by [TreeView]. It can be used -/// to create more sophisticated scrolling experiences. -/// * [AnimatedTreeView], a version of this widget that animates the expansion -/// state changes of tree nodes. -class TreeView extends BoxScrollView { - /// Creates a [TreeView]. - const TreeView({ - super.key, - required this.treeController, - required this.nodeBuilder, - super.padding, - super.controller, - super.primary, - super.physics, - super.shrinkWrap, - super.cacheExtent, - super.semanticChildCount, - super.dragStartBehavior, - super.keyboardDismissBehavior, - super.restorationId, - super.clipBehavior, - }); - - /// {@macro flutter_fancy_tree_view.SliverTree.controller} - final TreeController treeController; - - /// {@macro flutter_fancy_tree_view.SliverTree.nodeBuilder} - final TreeNodeBuilder nodeBuilder; - - @override - Widget buildChildLayout(BuildContext context) { - return SliverTree( - controller: treeController, - nodeBuilder: nodeBuilder, - ); - } -} - -/// A [TreeView] that animates the expansion state changes of tree nodes. -/// -/// Usage: -/// ```dart -/// @override -/// Widget build(BuildContext context) { -/// return AnimatedTreeView( -/// treeController: treeController, -/// duration: const Duration(milliseconds: 300), -/// curve: Curves.linear, -/// maxNodesToShowWhenAnimating: 50, -/// transitionBuilder: (BuildContext context, Widget child, Animation animation) { -/// return FadeTransition( -/// opacity: animation, -/// child: SizeTransition( -/// sizeFactor: animation, -/// child: child, -/// ), -/// ); -/// }, -/// nodeBuilder: (BuildContext context, TreeEntry entry) { -/// ... -/// }, -/// ); -/// } -/// ``` -/// -/// See also: -/// * [SliverAnimatedTree], which is created internally by [AnimatedTreeView]. -/// It can be used to create more sophisticated scrolling experiences. -/// * [TreeView], a version of this widget that has no custom behaviors. -class AnimatedTreeView extends TreeView { - /// Creates a [TreeView]. - const AnimatedTreeView({ - super.key, - required super.treeController, - required super.nodeBuilder, - this.transitionBuilder = defaultTreeTransitionBuilder, - this.duration = const Duration(milliseconds: 300), - this.curve = Curves.linear, - this.maxNodesToShowWhenAnimating = 50, - super.padding, - super.controller, - super.primary, - super.physics, - super.shrinkWrap, - super.cacheExtent, - super.semanticChildCount, - super.dragStartBehavior, - super.keyboardDismissBehavior, - super.restorationId, - super.clipBehavior, - }); - - /// {@macro flutter_fancy_tree_view.SliverAnimatedTree.transitionBuilder} - final TreeTransitionBuilder transitionBuilder; - - /// {@macro flutter_fancy_tree_view.SliverAnimatedTree.duration} - final Duration duration; - - /// {@macro flutter_fancy_tree_view.SliverAnimatedTree.curve} - final Curve curve; - - /// {@macro flutter_fancy_tree_view.SliverAnimatedTree.maxNodesToShowWhenAnimating} - final int maxNodesToShowWhenAnimating; - - @override - Widget buildChildLayout(BuildContext context) { - return SliverAnimatedTree( - controller: treeController, - nodeBuilder: nodeBuilder, - transitionBuilder: transitionBuilder, - duration: duration, - curve: curve, - maxNodesToShowWhenAnimating: maxNodesToShowWhenAnimating, - ); - } -} diff --git a/lib/src/extensions/widget_test_ext.dart b/lib/src/extensions/widget_test_ext.dart index 5e7866e..c0f2a10 100644 --- a/lib/src/extensions/widget_test_ext.dart +++ b/lib/src/extensions/widget_test_ext.dart @@ -1,3 +1,4 @@ +import 'package:catalog/catalog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:stringcare/stringcare.dart'; @@ -14,4 +15,16 @@ extension WidgetTestExt on WidgetTester { ); await pumpAndSettle(); } + + Future setupContext() async { + await pumpWidget( + MaterialApp( + navigatorKey: Stringcare().navigatorKey, + supportedLocales: Stringcare().locales, + localizationsDelegates: Stringcare().delegates, + home: Container(), + ), + ); + await pumpAndSettle(); + } } diff --git a/pubspec.yaml b/pubspec.yaml index 79c0d29..05e84de 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,6 +23,8 @@ dependencies: vector_graphics: ^1.1.11+1 # android ios linux macos web windows yaml: ^3.1.2 # android ios linux macos web windows yaml_writer: ^2.0.0 # android ios linux macos web windows + integration_test: + sdk: flutter flutter_test: sdk: flutter From c3d1513ef0b895896e09677184cd1657e79777d4 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 04:36:17 +0200 Subject: [PATCH 16/28] feature: integration tests --- .../bin/preview_builder/preview_builder.dart | 32 +++++++++++-------- .../tasks/tasks/instrumented_test_task.dart | 4 +-- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/src/bin/preview_builder/preview_builder.dart b/lib/src/bin/preview_builder/preview_builder.dart index 37be64a..fd5c0ec 100644 --- a/lib/src/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/preview_builder/preview_builder.dart @@ -252,7 +252,7 @@ class ${clazz}Test { ); } -Future generateInstrumentedTest( +Future generateIntegrationTest( dynamic config, String srcPath, String className, @@ -264,25 +264,25 @@ Future generateInstrumentedTest( String fileName = srcPath.split('/').last; String name = fileName.split('.').first; String dirPath = srcPath.replaceAll(fileName, ''); - String testPath = '${dirPath}catalog/instrumented_test/'; + String testPath = '${dirPath}catalog/integration_test/'; await Directory(testPath).create(recursive: true); - String testFile = '$testPath${name}_instrumented_test.dart'; + String testFile = '$testPath${name}_integration_test.dart'; File file = File(testFile); var importParts = classImport.split('/'); importParts.removeAt(importParts.length - 1); importParts.add(config['output']); - importParts.add('instrumented_test'); - importParts.add('${name}_instrumented_test.dart'); + importParts.add('integration_test'); + importParts.add('${name}_integration_test.dart'); if (await file.exists()) { print( - '🧪 👌 Test file already exist for $clazz - ${clazz}InstrumentedTest ($testFile)'); + '🧪 👌 Test file already exist for $clazz - ${clazz}IntegrationTest ($testFile)'); return TestBuilderInfo( alias: buildTestAlias(4), - clazzName: '${clazz}InstrumentedTest', + clazzName: '${clazz}IntegrationTest', import: importParts.join('/'), ); } @@ -300,10 +300,10 @@ import 'package:catalog/catalog.dart'; import '../dummy/$name.dummy.dart'; import '../preview/$name.$prefix.dart'; -class ${clazz}InstrumentedTestTest { +class ${clazz}IntegrationTestTest { void main() { group( - '$clazz - InstrumentedTest Tests', + '$clazz - IntegrationTest Tests', () { testWidgets( 'Lorem text not found', @@ -337,7 +337,7 @@ class ${clazz}InstrumentedTestTest { return TestBuilderInfo( alias: buildTestAlias(4), - clazzName: '${clazz}InstrumentedTest', + clazzName: '${clazz}IntegrationTest', import: importParts.join('/'), ); } @@ -368,13 +368,19 @@ void main() { await file.writeAsString(content); } -Future generateMainInstrumentedTest( +Future generateMainIntegrationTest( String basePath, List tests, ) async { - File file = File('./${basePath}instrumented_test/catalog_widget_instrumented_test.dart'); - print('🧪 Updating catalog instrumented test collector (${file.path})'); + String testPath = './${basePath}integration_test/'; + + await Directory(testPath).create(recursive: true); + + + File file = File('./${basePath}integration_test/catalog_widget_integration_test.dart'); + + print('🧪 Updating catalog integration test collector (${file.path})'); var content = ''' /// AUTOGENERATED FILE. DO NOT EDIT diff --git a/lib/src/bin/tasks/tasks/instrumented_test_task.dart b/lib/src/bin/tasks/tasks/instrumented_test_task.dart index 073711e..2422f5c 100644 --- a/lib/src/bin/tasks/tasks/instrumented_test_task.dart +++ b/lib/src/bin/tasks/tasks/instrumented_test_task.dart @@ -55,7 +55,7 @@ class InstrumentedTestTask extends BaseTask { if (className == null) continue; if (preview == null) continue; - final testFile = await generateInstrumentedTest( + final testFile = await generateIntegrationTest( config, file.path, className, @@ -66,6 +66,6 @@ class InstrumentedTestTask extends BaseTask { test.add(testFile); } - await generateMainInstrumentedTest(base, test); + await generateMainIntegrationTest(base, test); } } From 78d44d0e2c8593f70d7d202607bc6653df8a523b Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 04:43:11 +0200 Subject: [PATCH 17/28] feature: building tests --- example/assets/preview_config.json | 16 ++-- .../catalog_widget_integration_test.dart | 17 ++++ example/lib/catalog/process.dart | 78 ------------------- .../main_screen_integration_test.dart | 40 ++++++++++ .../catalog/test/main_screen_test.dart | 40 ++++++++++ .../body_widget_integration_test.dart | 40 ++++++++++ .../counter_widget_integration_test.dart | 40 ++++++++++ .../screen/catalog/test/body_widget_test.dart | 40 ++++++++++ .../catalog/test/counter_widget_test.dart | 40 ++++++++++ .../fab_widget_integration_test.dart | 40 ++++++++++ .../bottom/catalog/test/fab_widget_test.dart | 40 ++++++++++ example/test/catalog_widget_test.dart | 20 ++--- .../bin/preview_builder/preview_builder.dart | 2 +- lib/src/bin/tasks/tasks/format_task.dart | 2 +- 14 files changed, 357 insertions(+), 98 deletions(-) create mode 100644 example/integration_test/catalog_widget_integration_test.dart delete mode 100644 example/lib/catalog/process.dart create mode 100644 example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart create mode 100644 example/lib/widgets/catalog/test/main_screen_test.dart create mode 100644 example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart create mode 100644 example/lib/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart create mode 100644 example/lib/widgets/screen/catalog/test/body_widget_test.dart create mode 100644 example/lib/widgets/screen/catalog/test/counter_widget_test.dart create mode 100644 example/lib/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart create mode 100644 example/lib/widgets/utils/bottom/catalog/test/fab_widget_test.dart diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index 6894852..2d995cd 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -7,8 +7,8 @@ "id": "widgets", "route": "widgets", "builtComponents": { - "./example/lib/catalog/widgets/main_screen.dart": { - "path": "./example/lib/catalog/widgets/main_screen.dart", + "./lib/catalog/widgets/main_screen.dart": { + "path": "./lib/catalog/widgets/main_screen.dart", "route": "widgets", "package": "package:example/catalog/widgets/main_screen.dart", "clazzName": "MainScreenPreviewPreviewPageDummy", @@ -35,8 +35,8 @@ "id": "bottom", "route": "widgets/utils/bottom", "builtComponents": { - "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart": { - "path": "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart", + "./lib/catalog/widgets/utils/bottom/fab_widget.dart": { + "path": "./lib/catalog/widgets/utils/bottom/fab_widget.dart", "route": "widgets/utils/bottom", "package": "package:example/catalog/widgets/utils/bottom/fab_widget.dart", "clazzName": "FabWidgetPreviewPreviewPageDummy", @@ -58,8 +58,8 @@ "id": "screen", "route": "widgets/screen", "builtComponents": { - "./example/lib/catalog/widgets/screen/body_widget.dart": { - "path": "./example/lib/catalog/widgets/screen/body_widget.dart", + "./lib/catalog/widgets/screen/body_widget.dart": { + "path": "./lib/catalog/widgets/screen/body_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/body_widget.dart", "clazzName": "BodyWidgetPreviewPreviewPageDummy", @@ -73,8 +73,8 @@ ] } }, - "./example/lib/catalog/widgets/screen/counter_widget.dart": { - "path": "./example/lib/catalog/widgets/screen/counter_widget.dart", + "./lib/catalog/widgets/screen/counter_widget.dart": { + "path": "./lib/catalog/widgets/screen/counter_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/counter_widget.dart", "clazzName": "CounterWidgetPreviewPreviewPageDummy", diff --git a/example/integration_test/catalog_widget_integration_test.dart b/example/integration_test/catalog_widget_integration_test.dart new file mode 100644 index 0000000..3791204 --- /dev/null +++ b/example/integration_test/catalog_widget_integration_test.dart @@ -0,0 +1,17 @@ +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:example/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart' + as zcch; +import 'package:example/widgets/screen/catalog/integration_test/body_widget_integration_test.dart' + as uetd; +import 'package:example/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart' + as uoui; +import 'package:example/widgets/catalog/integration_test/main_screen_integration_test.dart' + as klxv; + +void main() { + zcch.FabWidgetIntegrationTest().main(); + uetd.BodyWidgetIntegrationTest().main(); + uoui.CounterWidgetIntegrationTest().main(); + klxv.MainScreenIntegrationTest().main(); +} diff --git a/example/lib/catalog/process.dart b/example/lib/catalog/process.dart deleted file mode 100644 index a82d622..0000000 --- a/example/lib/catalog/process.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'dart:convert'; - -import 'package:catalog/src/base/serial.dart'; - -class InternalPreview implements Serial { - final String id; - final String path; - final String description; - final List parameters; - - const InternalPreview({ - this.id = '', - this.path = '', - this.description = '', - this.parameters = const [], - }); - - @override - InternalPreview fromJson(Map json) => InternalPreview( - id: json['id'] ?? '', - path: json['path'] ?? '', - description: json['description'] ?? '', - parameters: Serial.listObjectFromBasicType( - json['parameters'] ?? [], - ), - ); - - @override - String getId() => id; - - @override - InternalPreview instance() => const InternalPreview(id: '', path: ''); - - @override - Map toJson() => { - 'id': id, - 'path': path, - 'description': description, - 'parameters': parameters, - }; - - @override - InternalPreview fromString(String value) { - Map map = jsonDecode(value); - return fromJson(map); - } - - @override - String stringValue() { - var map = toJson(); - return jsonEncode(map); - } - - InternalPreview copyWith({ - String? id, - String? path, - String? description, - List? parameters, - }) => - InternalPreview( - id: id ?? this.id, - path: path ?? this.path, - description: description ?? this.description, - parameters: parameters ?? this.parameters, - ); -} - -void main(List arguments) async { - var preview = const InternalPreview( - parameters: [ - 'title', - 'infoText', - 'counter', - 'incrementCounter', - ], - ); - print(jsonEncode(preview.toJson())); -} diff --git a/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart b/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart new file mode 100644 index 0000000..badb89c --- /dev/null +++ b/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget MainScreen +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/main_screen.dummy.dart'; +import '../preview/main_screen.preview.dart'; + +class MainScreenIntegrationTest { + void main() { + group( + 'MainScreen - IntegrationTest Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = MainScreenDummy().dummies.first; + final widget = buildMainScreen(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = MainScreenDummy().dummies.first; + final widget = buildMainScreen(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/catalog/test/main_screen_test.dart b/example/lib/widgets/catalog/test/main_screen_test.dart new file mode 100644 index 0000000..f08f498 --- /dev/null +++ b/example/lib/widgets/catalog/test/main_screen_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget MainScreen +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/main_screen.dummy.dart'; +import '../preview/main_screen.preview.dart'; + +class MainScreenTest { + void main() { + group( + 'MainScreen - Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = MainScreenDummy().dummies.first; + final widget = buildMainScreen(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = MainScreenDummy().dummies.first; + final widget = buildMainScreen(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart b/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart new file mode 100644 index 0000000..1730a89 --- /dev/null +++ b/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget BodyWidget +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/body_widget.dummy.dart'; +import '../preview/body_widget.preview.dart'; + +class BodyWidgetIntegrationTest { + void main() { + group( + 'BodyWidget - IntegrationTest Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = BodyWidgetDummy().dummies.first; + final widget = buildBodyWidget(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = BodyWidgetDummy().dummies.first; + final widget = buildBodyWidget(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart b/example/lib/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart new file mode 100644 index 0000000..ceee9c9 --- /dev/null +++ b/example/lib/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget CounterWidget +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/counter_widget.dummy.dart'; +import '../preview/counter_widget.preview.dart'; + +class CounterWidgetIntegrationTest { + void main() { + group( + 'CounterWidget - IntegrationTest Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = CounterWidgetDummy().dummies.first; + final widget = buildCounterWidget(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = CounterWidgetDummy().dummies.first; + final widget = buildCounterWidget(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/screen/catalog/test/body_widget_test.dart b/example/lib/widgets/screen/catalog/test/body_widget_test.dart new file mode 100644 index 0000000..d95893a --- /dev/null +++ b/example/lib/widgets/screen/catalog/test/body_widget_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget BodyWidget +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/body_widget.dummy.dart'; +import '../preview/body_widget.preview.dart'; + +class BodyWidgetTest { + void main() { + group( + 'BodyWidget - Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = BodyWidgetDummy().dummies.first; + final widget = buildBodyWidget(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = BodyWidgetDummy().dummies.first; + final widget = buildBodyWidget(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/screen/catalog/test/counter_widget_test.dart b/example/lib/widgets/screen/catalog/test/counter_widget_test.dart new file mode 100644 index 0000000..1682507 --- /dev/null +++ b/example/lib/widgets/screen/catalog/test/counter_widget_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget CounterWidget +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/counter_widget.dummy.dart'; +import '../preview/counter_widget.preview.dart'; + +class CounterWidgetTest { + void main() { + group( + 'CounterWidget - Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = CounterWidgetDummy().dummies.first; + final widget = buildCounterWidget(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = CounterWidgetDummy().dummies.first; + final widget = buildCounterWidget(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart b/example/lib/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart new file mode 100644 index 0000000..9e76b0f --- /dev/null +++ b/example/lib/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget FabWidget +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/fab_widget.dummy.dart'; +import '../preview/fab_widget.preview.dart'; + +class FabWidgetIntegrationTest { + void main() { + group( + 'FabWidget - IntegrationTest Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = FabWidgetDummy().dummies.first; + final widget = buildFabWidget(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = FabWidgetDummy().dummies.first; + final widget = buildFabWidget(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/utils/bottom/catalog/test/fab_widget_test.dart b/example/lib/widgets/utils/bottom/catalog/test/fab_widget_test.dart new file mode 100644 index 0000000..be1de98 --- /dev/null +++ b/example/lib/widgets/utils/bottom/catalog/test/fab_widget_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget FabWidget +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/fab_widget.dummy.dart'; +import '../preview/fab_widget.preview.dart'; + +class FabWidgetTest { + void main() { + group( + 'FabWidget - Tests', + () { + testWidgets( + 'Lorem text not found', + (tester) async { + final dummy = FabWidgetDummy().dummies.first; + final widget = buildFabWidget(dummy); + await tester.test(widget); + + expect(find.text('lorem ipsu'), findsNothing); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = FabWidgetDummy().dummies.first; + final widget = buildFabWidget(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/test/catalog_widget_test.dart b/example/test/catalog_widget_test.dart index e54c06f..e05d713 100644 --- a/example/test/catalog_widget_test.dart +++ b/example/test/catalog_widget_test.dart @@ -1,16 +1,16 @@ /// AUTOGENERATED FILE. DO NOT EDIT import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' - as aaad; -import 'package:example/widgets/screen/catalog/test/body_widget.test.dart' - as gsno; -import 'package:example/widgets/screen/catalog/test/counter_widget.test.dart' - as jnqe; -import 'package:example/widgets/catalog/test/main_screen.test.dart' as pxto; + as mtle; +import 'package:example/widgets/screen/catalog/test/body_widget_test.dart' + as oynh; +import 'package:example/widgets/screen/catalog/test/counter_widget_test.dart' + as cmuo; +import 'package:example/widgets/catalog/test/main_screen_test.dart' as exus; void main() { - aaad.FabWidgetTest().main(); - gsno.BodyWidgetTest().main(); - jnqe.CounterWidgetTest().main(); - pxto.MainScreenTest().main(); + mtle.FabWidgetTest().main(); + oynh.BodyWidgetTest().main(); + cmuo.CounterWidgetTest().main(); + exus.MainScreenTest().main(); } diff --git a/lib/src/bin/preview_builder/preview_builder.dart b/lib/src/bin/preview_builder/preview_builder.dart index fd5c0ec..2e2818d 100644 --- a/lib/src/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/preview_builder/preview_builder.dart @@ -300,7 +300,7 @@ import 'package:catalog/catalog.dart'; import '../dummy/$name.dummy.dart'; import '../preview/$name.$prefix.dart'; -class ${clazz}IntegrationTestTest { +class ${clazz}IntegrationTest { void main() { group( '$clazz - IntegrationTest Tests', diff --git a/lib/src/bin/tasks/tasks/format_task.dart b/lib/src/bin/tasks/tasks/format_task.dart index e0a4205..906a008 100644 --- a/lib/src/bin/tasks/tasks/format_task.dart +++ b/lib/src/bin/tasks/tasks/format_task.dart @@ -31,7 +31,7 @@ class FormatTask extends BaseTask { var resultFormatInstrumentedTest = await Process.run( 'dart', - ['format', 'instrumented_test/'], + ['format', 'integration_test/'], workingDirectory: Directory.current.path, ); stdout.write(resultFormatInstrumentedTest.stdout); From 8db8fce73a89f327b90a2850354a3cda48a7de97 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 05:53:52 +0200 Subject: [PATCH 18/28] feature: working on tests (stringcare lock) --- example/assets/preview_config.json | 16 +- .../catalog_widget_integration_test.dart | 32 +-- example/lib/catalog/catalog_component.dart | 187 +++++++++++------- example/lib/catalog/widgets/main_screen.dart | 10 +- .../catalog/widgets/screen/body_widget.dart | 10 +- .../widgets/screen/counter_widget.dart | 10 +- .../widgets/utils/bottom/fab_widget.dart | 10 +- .../main_screen_integration_test.dart | 14 +- .../catalog/preview/main_screen.preview.dart | 35 ++-- .../catalog/test/main_screen_test.dart | 18 +- .../body_widget_integration_test.dart | 15 +- .../catalog/preview/body_widget.preview.dart | 33 ++-- .../preview/counter_widget.preview.dart | 32 +-- .../screen/catalog/test/body_widget_test.dart | 14 +- .../catalog/preview/fab_widget.preview.dart | 32 +-- example/pubspec.yaml | 9 +- example/test/catalog_widget_test.dart | 21 +- example/test_driver/integration_test.dart | 3 + .../bin/preview_builder/preview_builder.dart | 10 + lib/src/extensions/widget_test_ext.dart | 2 + 20 files changed, 303 insertions(+), 210 deletions(-) create mode 100644 example/test_driver/integration_test.dart diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index 2d995cd..6894852 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -7,8 +7,8 @@ "id": "widgets", "route": "widgets", "builtComponents": { - "./lib/catalog/widgets/main_screen.dart": { - "path": "./lib/catalog/widgets/main_screen.dart", + "./example/lib/catalog/widgets/main_screen.dart": { + "path": "./example/lib/catalog/widgets/main_screen.dart", "route": "widgets", "package": "package:example/catalog/widgets/main_screen.dart", "clazzName": "MainScreenPreviewPreviewPageDummy", @@ -35,8 +35,8 @@ "id": "bottom", "route": "widgets/utils/bottom", "builtComponents": { - "./lib/catalog/widgets/utils/bottom/fab_widget.dart": { - "path": "./lib/catalog/widgets/utils/bottom/fab_widget.dart", + "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart": { + "path": "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart", "route": "widgets/utils/bottom", "package": "package:example/catalog/widgets/utils/bottom/fab_widget.dart", "clazzName": "FabWidgetPreviewPreviewPageDummy", @@ -58,8 +58,8 @@ "id": "screen", "route": "widgets/screen", "builtComponents": { - "./lib/catalog/widgets/screen/body_widget.dart": { - "path": "./lib/catalog/widgets/screen/body_widget.dart", + "./example/lib/catalog/widgets/screen/body_widget.dart": { + "path": "./example/lib/catalog/widgets/screen/body_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/body_widget.dart", "clazzName": "BodyWidgetPreviewPreviewPageDummy", @@ -73,8 +73,8 @@ ] } }, - "./lib/catalog/widgets/screen/counter_widget.dart": { - "path": "./lib/catalog/widgets/screen/counter_widget.dart", + "./example/lib/catalog/widgets/screen/counter_widget.dart": { + "path": "./example/lib/catalog/widgets/screen/counter_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/counter_widget.dart", "clazzName": "CounterWidgetPreviewPreviewPageDummy", diff --git a/example/integration_test/catalog_widget_integration_test.dart b/example/integration_test/catalog_widget_integration_test.dart index 3791204..5a5fb65 100644 --- a/example/integration_test/catalog_widget_integration_test.dart +++ b/example/integration_test/catalog_widget_integration_test.dart @@ -1,17 +1,25 @@ /// AUTOGENERATED FILE. DO NOT EDIT -import 'package:example/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart' - as zcch; -import 'package:example/widgets/screen/catalog/integration_test/body_widget_integration_test.dart' - as uetd; -import 'package:example/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart' - as uoui; -import 'package:example/widgets/catalog/integration_test/main_screen_integration_test.dart' - as klxv; +/// Launch on Android or iOS as usual. +/// Launch on Web with: +/// +/// chromedriver --port=4444 +/// flutter drive --driver=test_driver/integration_test.dart --target=integration_test/catalog_widget_integration_test.dart -d chrome + +import 'package:integration_test/integration_test.dart'; + +import 'package:example/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart' as mzpp; +import 'package:example/widgets/screen/catalog/integration_test/body_widget_integration_test.dart' as satm; +import 'package:example/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart' as azmi; +import 'package:example/widgets/catalog/integration_test/main_screen_integration_test.dart' as kbve; void main() { - zcch.FabWidgetIntegrationTest().main(); - uetd.BodyWidgetIntegrationTest().main(); - uoui.CounterWidgetIntegrationTest().main(); - klxv.MainScreenIntegrationTest().main(); + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + mzpp.FabWidgetIntegrationTest().main(); +satm.BodyWidgetIntegrationTest().main(); +azmi.CounterWidgetIntegrationTest().main(); +kbve.MainScreenIntegrationTest().main(); } + + \ No newline at end of file diff --git a/example/lib/catalog/catalog_component.dart b/example/lib/catalog/catalog_component.dart index cd1871d..bbed7f9 100644 --- a/example/lib/catalog/catalog_component.dart +++ b/example/lib/catalog/catalog_component.dart @@ -3,90 +3,126 @@ import 'package:flutter/material.dart'; import 'package:catalog/catalog.dart'; + import 'package:example/catalog/widgets/utils/bottom/fab_widget.dart'; -import 'package:example/catalog/widgets/screen/body_widget.dart'; -import 'package:example/catalog/widgets/screen/counter_widget.dart'; + + + + + + +import 'package:example/catalog/widgets/screen/body_widget.dart';import 'package:example/catalog/widgets/screen/counter_widget.dart'; + + import 'package:example/catalog/widgets/main_screen.dart'; + + + + + + class CatalogComponent extends StatefulWidget { static String routeName = '/catalog'; - - static GoRoute route = GoRoute( - path: CatalogComponent.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CatalogComponent(), - ), - routes: [ - GoRoute( - path: 'widgets', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - GoRoute( - path: MainScreenPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const MainScreenPreviewPreviewPageDummy(), - ), + + static GoRoute route = GoRoute( + path: CatalogComponent.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CatalogComponent(), ), - GoRoute( - path: 'utils', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - GoRoute( - path: 'bottom', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - GoRoute( - path: FabWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const FabWidgetPreviewPreviewPageDummy(), - ), - ), - ], - ) - ], + routes: [ + GoRoute( + path: 'widgets', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + + GoRoute( + path: MainScreenPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const MainScreenPreviewPreviewPageDummy(), ), - GoRoute( - path: 'screen', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - GoRoute( - path: BodyWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const BodyWidgetPreviewPreviewPageDummy(), - ), - ), - GoRoute( - path: CounterWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CounterWidgetPreviewPreviewPageDummy(), - ), - ), - ], - ) - ], + ) + + + , + GoRoute( + path: 'utils', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + + + GoRoute( + path: 'bottom', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + + GoRoute( + path: FabWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const FabWidgetPreviewPreviewPageDummy(), + ), + ) + + + , + + ], + ) + + ], + ) + , GoRoute( + path: 'screen', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + + GoRoute( + path: BodyWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const BodyWidgetPreviewPreviewPageDummy(), + ), + ) + + , + GoRoute( + path: CounterWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CounterWidgetPreviewPreviewPageDummy(), + ), + ) + + + , + + ], + ) + + ], + ) + + ], ) - ], - ); - +; + const CatalogComponent({super.key}); @override @@ -94,6 +130,7 @@ class CatalogComponent extends StatefulWidget { } class CatalogComponentState extends State { + @override Widget build(BuildContext context) { return FutureBuilder( @@ -122,3 +159,5 @@ class CatalogComponentState extends State { ); } } + + \ No newline at end of file diff --git a/example/lib/catalog/widgets/main_screen.dart b/example/lib/catalog/widgets/main_screen.dart index 2435fa2..8478f34 100644 --- a/example/lib/catalog/widgets/main_screen.dart +++ b/example/lib/catalog/widgets/main_screen.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/catalog/preview/main_screen.preview.dart'; class MainScreenPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'main_screen'; + static String routeName = 'main_screen'; + const MainScreenPreviewPreviewPageDummy({super.key}); @override - MainScreenPreviewPreviewPageDummyState createState() => - MainScreenPreviewPreviewPageDummyState(); + MainScreenPreviewPreviewPageDummyState createState() => MainScreenPreviewPreviewPageDummyState(); } -class MainScreenPreviewPreviewPageDummyState - extends State { +class MainScreenPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const MainScreenPreview(); } } + \ No newline at end of file diff --git a/example/lib/catalog/widgets/screen/body_widget.dart b/example/lib/catalog/widgets/screen/body_widget.dart index 57f4c75..54eb25b 100644 --- a/example/lib/catalog/widgets/screen/body_widget.dart +++ b/example/lib/catalog/widgets/screen/body_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/body_widget.preview.dart'; class BodyWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'body_widget'; + static String routeName = 'body_widget'; + const BodyWidgetPreviewPreviewPageDummy({super.key}); @override - BodyWidgetPreviewPreviewPageDummyState createState() => - BodyWidgetPreviewPreviewPageDummyState(); + BodyWidgetPreviewPreviewPageDummyState createState() => BodyWidgetPreviewPreviewPageDummyState(); } -class BodyWidgetPreviewPreviewPageDummyState - extends State { +class BodyWidgetPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const BodyWidgetPreview(); } } + \ No newline at end of file diff --git a/example/lib/catalog/widgets/screen/counter_widget.dart b/example/lib/catalog/widgets/screen/counter_widget.dart index dc4cda2..0d5e240 100644 --- a/example/lib/catalog/widgets/screen/counter_widget.dart +++ b/example/lib/catalog/widgets/screen/counter_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/counter_widget.preview.dart'; class CounterWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'counter_widget'; + static String routeName = 'counter_widget'; + const CounterWidgetPreviewPreviewPageDummy({super.key}); @override - CounterWidgetPreviewPreviewPageDummyState createState() => - CounterWidgetPreviewPreviewPageDummyState(); + CounterWidgetPreviewPreviewPageDummyState createState() => CounterWidgetPreviewPreviewPageDummyState(); } -class CounterWidgetPreviewPreviewPageDummyState - extends State { +class CounterWidgetPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const CounterWidgetPreview(); } } + \ No newline at end of file diff --git a/example/lib/catalog/widgets/utils/bottom/fab_widget.dart b/example/lib/catalog/widgets/utils/bottom/fab_widget.dart index 5b10f36..0fc351c 100644 --- a/example/lib/catalog/widgets/utils/bottom/fab_widget.dart +++ b/example/lib/catalog/widgets/utils/bottom/fab_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart'; class FabWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'fab_widget'; + static String routeName = 'fab_widget'; + const FabWidgetPreviewPreviewPageDummy({super.key}); @override - FabWidgetPreviewPreviewPageDummyState createState() => - FabWidgetPreviewPreviewPageDummyState(); + FabWidgetPreviewPreviewPageDummyState createState() => FabWidgetPreviewPreviewPageDummyState(); } -class FabWidgetPreviewPreviewPageDummyState - extends State { +class FabWidgetPreviewPreviewPageDummyState extends State { @override Widget build(BuildContext context) { return const FabWidgetPreview(); } } + \ No newline at end of file diff --git a/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart b/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart index badb89c..fbaa7fc 100644 --- a/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart +++ b/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart @@ -4,6 +4,8 @@ /// import 'package:catalog/catalog.dart'; +import 'package:example/r.dart'; +import 'package:stringcare/stringcare.dart'; import '../dummy/main_screen.dummy.dart'; import '../preview/main_screen.preview.dart'; @@ -14,24 +16,28 @@ class MainScreenIntegrationTest { 'MainScreen - IntegrationTest Tests', () { testWidgets( - 'Lorem text not found', + 'Finds title and info text', (tester) async { + await tester.setupContext(); final dummy = MainScreenDummy().dummies.first; final widget = buildMainScreen(dummy); await tester.test(widget); - expect(find.text('lorem ipsu'), findsNothing); + expect(find.text(R.strings.title_app.string()), findsAny); + expect(find.text(R.strings.info_text.string()), findsAny); }, ); testWidgets( - 'Other lorem text not found', + 'Web title not displayed on widget', (tester) async { + await tester.setupContext(); + final dummy = MainScreenDummy().dummies.first; final widget = buildMainScreen(dummy); await tester.test(widget); - expect(find.text('ipsu lorem'), findsNothing); + expect(find.text(R.strings.title.string()), findsNothing); }, ); }, diff --git a/example/lib/widgets/catalog/preview/main_screen.preview.dart b/example/lib/widgets/catalog/preview/main_screen.preview.dart index 7095ff7..41ff423 100644 --- a/example/lib/widgets/catalog/preview/main_screen.preview.dart +++ b/example/lib/widgets/catalog/preview/main_screen.preview.dart @@ -11,17 +11,17 @@ import '../dummy/main_screen.dummy.dart'; 'infoText', 'counter', 'incrementCounter', - ], -) + ],) class MainScreenPreview extends ParentPreviewWidget { + @override String get title => 'main_screen'; - + @override String get basePath => '/catalog'; - + const MainScreenPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -106,25 +106,24 @@ class MainScreenPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < MainScreenDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => MainScreenDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return buildMainScreen(dummy); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => MainScreenDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildMainScreen(dummy); + }, + ), + ], ) ], ); } + + } MainScreen buildMainScreen(Dummy dummy) { - return MainScreen( - title: dummy.parameters['title'], - infoText: dummy.parameters['infoText'], - counter: dummy.parameters['counter'], - incrementCounter: dummy.parameters['incrementCounter'], - ); + return MainScreen(title: dummy.parameters['title'],infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],incrementCounter: dummy.parameters['incrementCounter'],); } + \ No newline at end of file diff --git a/example/lib/widgets/catalog/test/main_screen_test.dart b/example/lib/widgets/catalog/test/main_screen_test.dart index f08f498..04c23b6 100644 --- a/example/lib/widgets/catalog/test/main_screen_test.dart +++ b/example/lib/widgets/catalog/test/main_screen_test.dart @@ -4,6 +4,8 @@ /// import 'package:catalog/catalog.dart'; +import 'package:example/r.dart'; +import 'package:stringcare/stringcare.dart'; import '../dummy/main_screen.dummy.dart'; import '../preview/main_screen.preview.dart'; @@ -14,24 +16,28 @@ class MainScreenTest { 'MainScreen - Tests', () { testWidgets( - 'Lorem text not found', - (tester) async { + 'Finds title and info text', + (tester) async { + await tester.setupContext(); final dummy = MainScreenDummy().dummies.first; final widget = buildMainScreen(dummy); await tester.test(widget); - expect(find.text('lorem ipsu'), findsNothing); + expect(find.text(R.strings.title_app.string()), findsAny); + expect(find.text(R.strings.info_text.string()), findsAny); }, ); testWidgets( - 'Other lorem text not found', - (tester) async { + 'Web title not displayed on widget', + (tester) async { + await tester.setupContext(); + final dummy = MainScreenDummy().dummies.first; final widget = buildMainScreen(dummy); await tester.test(widget); - expect(find.text('ipsu lorem'), findsNothing); + expect(find.text(R.strings.title.string()), findsNothing); }, ); }, diff --git a/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart b/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart index 1730a89..fe54c20 100644 --- a/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart +++ b/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart @@ -4,6 +4,8 @@ /// import 'package:catalog/catalog.dart'; +import 'package:example/r.dart'; +import 'package:stringcare/stringcare.dart'; import '../dummy/body_widget.dummy.dart'; import '../preview/body_widget.preview.dart'; @@ -14,24 +16,29 @@ class BodyWidgetIntegrationTest { 'BodyWidget - IntegrationTest Tests', () { testWidgets( - 'Lorem text not found', + 'No title is found', (tester) async { + await tester.setupContext(); + final dummy = BodyWidgetDummy().dummies.first; final widget = buildBodyWidget(dummy); await tester.test(widget); - expect(find.text('lorem ipsu'), findsNothing); + expect(find.text(R.strings.title_app.string()), findsNothing); }, ); testWidgets( - 'Other lorem text not found', + 'Info text is displayed', (tester) async { + await tester.setupContext(); + final dummy = BodyWidgetDummy().dummies.first; final widget = buildBodyWidget(dummy); await tester.test(widget); - expect(find.text('ipsu lorem'), findsNothing); + expect(find.text('You have pushed the button this many times:'), + findsAny); }, ); }, diff --git a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart index 24af584..c4cc0a7 100644 --- a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart @@ -9,17 +9,17 @@ import '../dummy/body_widget.dummy.dart'; parameters: [ 'infoText', 'counter', - ], -) + ],) class BodyWidgetPreview extends ParentPreviewWidget { + @override String get title => 'body_widget'; - + @override String get basePath => '/catalog'; - + const BodyWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -104,23 +104,24 @@ class BodyWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < BodyWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => BodyWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return buildBodyWidget(dummy); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => BodyWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildBodyWidget(dummy); + }, + ), + ], ) ], ); } + + } BodyWidget buildBodyWidget(Dummy dummy) { - return BodyWidget( - infoText: dummy.parameters['infoText'], - counter: dummy.parameters['counter'], - ); + return BodyWidget(infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],); } + \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart index 04f76ab..0281f98 100644 --- a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart @@ -9,17 +9,17 @@ import '../dummy/counter_widget.dummy.dart'; description: 'Basic counter widget', parameters: [ 'counter', - ], -) + ],) class CounterWidgetPreview extends ParentPreviewWidget { + @override String get title => 'counter_widget'; - + @override String get basePath => '/catalog'; - + const CounterWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -104,22 +104,24 @@ class CounterWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < CounterWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => CounterWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return buildCounterWidget(dummy); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => CounterWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildCounterWidget(dummy); + }, + ), + ], ) ], ); } + + } CounterWidget buildCounterWidget(Dummy dummy) { - return CounterWidget( - counter: dummy.parameters['counter'], - ); + return CounterWidget(counter: dummy.parameters['counter'],); } + \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/test/body_widget_test.dart b/example/lib/widgets/screen/catalog/test/body_widget_test.dart index d95893a..ab4ad94 100644 --- a/example/lib/widgets/screen/catalog/test/body_widget_test.dart +++ b/example/lib/widgets/screen/catalog/test/body_widget_test.dart @@ -4,6 +4,8 @@ /// import 'package:catalog/catalog.dart'; +import 'package:example/r.dart'; +import 'package:stringcare/stringcare.dart'; import '../dummy/body_widget.dummy.dart'; import '../preview/body_widget.preview.dart'; @@ -14,24 +16,28 @@ class BodyWidgetTest { 'BodyWidget - Tests', () { testWidgets( - 'Lorem text not found', + 'No title is found', (tester) async { + await tester.setupContext(); + final dummy = BodyWidgetDummy().dummies.first; final widget = buildBodyWidget(dummy); await tester.test(widget); - expect(find.text('lorem ipsu'), findsNothing); + expect(find.text(R.strings.title_app.string()), findsNothing); }, ); testWidgets( - 'Other lorem text not found', + 'Info text is displayed', (tester) async { + await tester.setupContext(); + final dummy = BodyWidgetDummy().dummies.first; final widget = buildBodyWidget(dummy); await tester.test(widget); - expect(find.text('ipsu lorem'), findsNothing); + expect(find.text('You have pushed the button this many times:'), findsAny); }, ); }, diff --git a/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart index 8b87e15..e4de07b 100644 --- a/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart +++ b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart @@ -7,17 +7,17 @@ import '../dummy/fab_widget.dummy.dart'; @Preview( description: 'Basic fab widget', - parameters: ['incrementCounter'], -) + parameters: ['incrementCounter'],) class FabWidgetPreview extends ParentPreviewWidget { + @override String get title => 'fab_widget'; - + @override String get basePath => '/catalog'; - + const FabWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -102,22 +102,24 @@ class FabWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < FabWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => FabWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return buildFabWidget(dummy); - }, - ), + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => FabWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildFabWidget(dummy); + }, + ), + ], ) ], ); } + + } FabWidget buildFabWidget(Dummy dummy) { - return FabWidget( - incrementCounter: dummy.parameters['incrementCounter'], - ); + return FabWidget(incrementCounter: dummy.parameters['incrementCounter'],); } + \ No newline at end of file diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 436588c..846cb2d 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -12,14 +12,17 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.8 - stringcare: ^0.1.6 # android ios linux macos web windows + stringcare: ^0.1.7 # android ios linux macos web windows catalog: path: ../ dev_dependencies: - flutter_test: + integration_test: sdk: flutter - flutter_lints: ^4.0.0 + flutter_test: + sdk: + flutter + flutter_lints: ^5.0.0 stringcare: lang: diff --git a/example/test/catalog_widget_test.dart b/example/test/catalog_widget_test.dart index e05d713..445b0c7 100644 --- a/example/test/catalog_widget_test.dart +++ b/example/test/catalog_widget_test.dart @@ -1,16 +1,15 @@ /// AUTOGENERATED FILE. DO NOT EDIT -import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' - as mtle; -import 'package:example/widgets/screen/catalog/test/body_widget_test.dart' - as oynh; -import 'package:example/widgets/screen/catalog/test/counter_widget_test.dart' - as cmuo; -import 'package:example/widgets/catalog/test/main_screen_test.dart' as exus; +import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' as cfxg; +import 'package:example/widgets/screen/catalog/test/body_widget_test.dart' as puqi; +import 'package:example/widgets/screen/catalog/test/counter_widget_test.dart' as cmom; +import 'package:example/widgets/catalog/test/main_screen_test.dart' as ldag; void main() { - mtle.FabWidgetTest().main(); - oynh.BodyWidgetTest().main(); - cmuo.CounterWidgetTest().main(); - exus.MainScreenTest().main(); + cfxg.FabWidgetTest().main(); +puqi.BodyWidgetTest().main(); +cmom.CounterWidgetTest().main(); +ldag.MainScreenTest().main(); } + + \ No newline at end of file diff --git a/example/test_driver/integration_test.dart b/example/test_driver/integration_test.dart new file mode 100644 index 0000000..b38629c --- /dev/null +++ b/example/test_driver/integration_test.dart @@ -0,0 +1,3 @@ +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); diff --git a/lib/src/bin/preview_builder/preview_builder.dart b/lib/src/bin/preview_builder/preview_builder.dart index 2e2818d..0ca1458 100644 --- a/lib/src/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/preview_builder/preview_builder.dart @@ -385,11 +385,21 @@ Future generateMainIntegrationTest( var content = ''' /// AUTOGENERATED FILE. DO NOT EDIT +/// Launch on Android or iOS as usual. +/// Launch on Web with: +/// +/// chromedriver --port=4444 +/// flutter drive --driver=test_driver/integration_test.dart --target=integration_test/catalog_widget_integration_test.dart -d chrome + +import 'package:integration_test/integration_test.dart'; + ${tests.map((t) { return 'import \'${t.import}\' as ${t.alias};'; }).join('\n')} void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + ${tests.map((t) { return '${t.alias}.${t.clazzName}().main();'; }).join('\n')} diff --git a/lib/src/extensions/widget_test_ext.dart b/lib/src/extensions/widget_test_ext.dart index c0f2a10..516f6df 100644 --- a/lib/src/extensions/widget_test_ext.dart +++ b/lib/src/extensions/widget_test_ext.dart @@ -17,6 +17,7 @@ extension WidgetTestExt on WidgetTester { } Future setupContext() async { + Stringcare().langPath = 'lang_base'; await pumpWidget( MaterialApp( navigatorKey: Stringcare().navigatorKey, @@ -26,5 +27,6 @@ extension WidgetTestExt on WidgetTester { ), ); await pumpAndSettle(); + await Stringcare().load(); } } From afa2434ffd494db62e11f1fdc64200e0427b0e47 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 10:36:37 +0200 Subject: [PATCH 19/28] feature: test new widget --- .../bottom/warning_info_widget.dart | 22 ++++ .../dummy/warning_info_widget.dummy.dart | 17 +++ .../warning_info_widget_integration_test.dart | 40 ++++++ .../preview/warning_info_widget.preview.dart | 123 ++++++++++++++++++ .../test/warning_info_widget_test.dart | 40 ++++++ .../bottom/warning_info_widget.dart | 20 +++ 6 files changed, 262 insertions(+) create mode 100644 example/lib/catalog/widgets/other_utils/bottom/warning_info_widget.dart create mode 100644 example/lib/widgets/other_utils/bottom/catalog/dummy/warning_info_widget.dummy.dart create mode 100644 example/lib/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart create mode 100644 example/lib/widgets/other_utils/bottom/catalog/preview/warning_info_widget.preview.dart create mode 100644 example/lib/widgets/other_utils/bottom/catalog/test/warning_info_widget_test.dart create mode 100644 example/lib/widgets/other_utils/bottom/warning_info_widget.dart diff --git a/example/lib/catalog/widgets/other_utils/bottom/warning_info_widget.dart b/example/lib/catalog/widgets/other_utils/bottom/warning_info_widget.dart new file mode 100644 index 0000000..bae6d1e --- /dev/null +++ b/example/lib/catalog/widgets/other_utils/bottom/warning_info_widget.dart @@ -0,0 +1,22 @@ +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:flutter/material.dart'; +import 'package:example/widgets/other_utils/bottom/catalog/preview/warning_info_widget.preview.dart'; + +class WarningInfoWidgetPreviewPreviewPageDummy extends StatefulWidget { + static String routeName = 'warning_info_widget'; + + const WarningInfoWidgetPreviewPreviewPageDummy({super.key}); + + @override + WarningInfoWidgetPreviewPreviewPageDummyState createState() => + WarningInfoWidgetPreviewPreviewPageDummyState(); +} + +class WarningInfoWidgetPreviewPreviewPageDummyState + extends State { + @override + Widget build(BuildContext context) { + return const WarningInfoWidgetPreview(); + } +} diff --git a/example/lib/widgets/other_utils/bottom/catalog/dummy/warning_info_widget.dummy.dart b/example/lib/widgets/other_utils/bottom/catalog/dummy/warning_info_widget.dummy.dart new file mode 100644 index 0000000..d36a8d7 --- /dev/null +++ b/example/lib/widgets/other_utils/bottom/catalog/dummy/warning_info_widget.dummy.dart @@ -0,0 +1,17 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file for modify the preview of WarningInfoWidgetPreview +/// + +import 'package:catalog/catalog.dart'; + +class WarningInfoWidgetDummy extends PreviewDummy { + @override + List get dummies => [ + Dummy( + parameters: { + 'infoText': 'text sample', + }, + ), + ]; +} diff --git a/example/lib/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart b/example/lib/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart new file mode 100644 index 0000000..659df09 --- /dev/null +++ b/example/lib/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget WarningInfoWidget +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/warning_info_widget.dummy.dart'; +import '../preview/warning_info_widget.preview.dart'; + +class WarningInfoWidgetIntegrationTest { + void main() { + group( + 'WarningInfoWidget - IntegrationTest Tests', + () { + testWidgets( + 'Finds text sample', + (tester) async { + final dummy = WarningInfoWidgetDummy().dummies.first; + final widget = buildWarningInfoWidget(dummy); + await tester.test(widget); + + expect(find.text('text sample'), findsAny); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = WarningInfoWidgetDummy().dummies.first; + final widget = buildWarningInfoWidget(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/other_utils/bottom/catalog/preview/warning_info_widget.preview.dart b/example/lib/widgets/other_utils/bottom/catalog/preview/warning_info_widget.preview.dart new file mode 100644 index 0000000..71ec6ab --- /dev/null +++ b/example/lib/widgets/other_utils/bottom/catalog/preview/warning_info_widget.preview.dart @@ -0,0 +1,123 @@ +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:catalog/catalog.dart'; +import 'package:flutter/material.dart'; +import 'package:example/widgets/other_utils/bottom/warning_info_widget.dart'; +import '../dummy/warning_info_widget.dummy.dart'; + +@Preview( + description: 'Basic warning info text for alert', + parameters: ['infoText'], +) +class WarningInfoWidgetPreview extends ParentPreviewWidget { + @override + String get title => 'warning_info_widget'; + + @override + String get basePath => '/catalog'; + + const WarningInfoWidgetPreview({super.key}); + + @override + Widget preview(BuildContext context) { + Catalog().widgetBasicPreviewMap.clear(); + Catalog().widgetDevicePreviewMap.clear(); + + if (WarningInfoWidgetDummy().dummies.isEmpty) { + return Container(); + } + + final deviceScreenshotsAvailable = + WarningInfoWidgetDummy().deviceScreenshotsAvailable; + final screenshotsAvailable = WarningInfoWidgetDummy().screenshotsAvailable; + + int basicScreenshots = screenshotsAvailable - deviceScreenshotsAvailable; + + return ListView( + children: [ + Column( + children: [ + if (basicScreenshots > 0) + Center( + child: Container( + constraints: const BoxConstraints( + maxWidth: 400, + ), + child: Card( + clipBehavior: Clip.hardEdge, + child: Container( + padding: const EdgeInsets.all(15), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Center( + child: Text( + '$basicScreenshots basic screenshots available', + ), + ), + ), + const IconButton( + onPressed: processBasicScreenshots, + icon: Icon( + Icons.screenshot, + ), + ) + ], + ), + ), + ), + ), + ), + if (deviceScreenshotsAvailable > 0) + Center( + child: Container( + constraints: const BoxConstraints( + maxWidth: 400, + ), + child: Card( + clipBehavior: Clip.hardEdge, + child: Container( + padding: const EdgeInsets.all(15), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Center( + child: Text( + '$deviceScreenshotsAvailable device screenshots available', + ), + ), + ), + const IconButton( + onPressed: processDeviceScreenshots, + icon: Icon( + Icons.screenshot, + ), + ) + ], + ), + ), + ), + ), + ), + for (int i = 0; i < WarningInfoWidgetDummy().dummies.length; i++) + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => WarningInfoWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildWarningInfoWidget(dummy); + }, + ), + ], + ) + ], + ); + } +} + +WarningInfoWidget buildWarningInfoWidget(Dummy dummy) { + return WarningInfoWidget( + infoText: dummy.parameters['infoText'], + ); +} diff --git a/example/lib/widgets/other_utils/bottom/catalog/test/warning_info_widget_test.dart b/example/lib/widgets/other_utils/bottom/catalog/test/warning_info_widget_test.dart new file mode 100644 index 0000000..54a1cf0 --- /dev/null +++ b/example/lib/widgets/other_utils/bottom/catalog/test/warning_info_widget_test.dart @@ -0,0 +1,40 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget WarningInfoWidget +/// + +import 'package:catalog/catalog.dart'; + +import '../dummy/warning_info_widget.dummy.dart'; +import '../preview/warning_info_widget.preview.dart'; + +class WarningInfoWidgetTest { + void main() { + group( + 'WarningInfoWidget - Tests', + () { + testWidgets( + 'Finds text sample', + (tester) async { + final dummy = WarningInfoWidgetDummy().dummies.first; + final widget = buildWarningInfoWidget(dummy); + await tester.test(widget); + + expect(find.text('text sample'), findsAny); + }, + ); + + testWidgets( + 'Other lorem text not found', + (tester) async { + final dummy = WarningInfoWidgetDummy().dummies.first; + final widget = buildWarningInfoWidget(dummy); + await tester.test(widget); + + expect(find.text('ipsu lorem'), findsNothing); + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/other_utils/bottom/warning_info_widget.dart b/example/lib/widgets/other_utils/bottom/warning_info_widget.dart new file mode 100644 index 0000000..acf52d6 --- /dev/null +++ b/example/lib/widgets/other_utils/bottom/warning_info_widget.dart @@ -0,0 +1,20 @@ +import 'package:catalog/catalog.dart'; +import 'package:flutter/material.dart'; + +@Preview( + description: 'Basic warning info text for alert', + parameters: ['infoText'], +) +class WarningInfoWidget extends StatelessWidget { + final String infoText; + + const WarningInfoWidget({ + super.key, + required this.infoText, + }); + + @override + Widget build(BuildContext context) { + return Text(infoText); + } +} From 180c1984ee8275c1281f672a79207e19a6fe5f94 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sat, 5 Oct 2024 10:36:48 +0200 Subject: [PATCH 20/28] feature: test new widget --- example/assets/preview_config.json | 44 +++- .../catalog_widget_integration_test.dart | 25 ++- example/lib/catalog/catalog_component.dart | 210 +++++++++--------- example/lib/catalog/widgets/main_screen.dart | 10 +- .../catalog/widgets/screen/body_widget.dart | 10 +- .../widgets/screen/counter_widget.dart | 10 +- .../widgets/utils/bottom/fab_widget.dart | 10 +- .../catalog/preview/main_screen.preview.dart | 35 +-- .../catalog/test/main_screen_test.dart | 4 +- .../catalog/preview/body_widget.preview.dart | 33 ++- .../preview/counter_widget.preview.dart | 32 ++- .../screen/catalog/test/body_widget_test.dart | 3 +- .../catalog/preview/fab_widget.preview.dart | 32 ++- example/test/catalog_widget_test.dart | 24 +- 14 files changed, 252 insertions(+), 230 deletions(-) diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index 6894852..80addd8 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -7,8 +7,8 @@ "id": "widgets", "route": "widgets", "builtComponents": { - "./example/lib/catalog/widgets/main_screen.dart": { - "path": "./example/lib/catalog/widgets/main_screen.dart", + "./lib/catalog/widgets/main_screen.dart": { + "path": "./lib/catalog/widgets/main_screen.dart", "route": "widgets", "package": "package:example/catalog/widgets/main_screen.dart", "clazzName": "MainScreenPreviewPreviewPageDummy", @@ -35,8 +35,8 @@ "id": "bottom", "route": "widgets/utils/bottom", "builtComponents": { - "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart": { - "path": "./example/lib/catalog/widgets/utils/bottom/fab_widget.dart", + "./lib/catalog/widgets/utils/bottom/fab_widget.dart": { + "path": "./lib/catalog/widgets/utils/bottom/fab_widget.dart", "route": "widgets/utils/bottom", "package": "package:example/catalog/widgets/utils/bottom/fab_widget.dart", "clazzName": "FabWidgetPreviewPreviewPageDummy", @@ -54,12 +54,40 @@ } } }, + "other_utils": { + "id": "other_utils", + "route": "widgets/other_utils", + "builtComponents": {}, + "children": { + "bottom": { + "id": "bottom", + "route": "widgets/other_utils/bottom", + "builtComponents": { + "./lib/catalog/widgets/other_utils/bottom/warning_info_widget.dart": { + "path": "./lib/catalog/widgets/other_utils/bottom/warning_info_widget.dart", + "route": "widgets/other_utils/bottom", + "package": "package:example/catalog/widgets/other_utils/bottom/warning_info_widget.dart", + "clazzName": "WarningInfoWidgetPreviewPreviewPageDummy", + "preview": { + "id": "warning_info_widget", + "path": "widgets/other_utils/bottom", + "description": "Basic warning info text for alert", + "parameters": [ + "infoText" + ] + } + } + }, + "children": {} + } + } + }, "screen": { "id": "screen", "route": "widgets/screen", "builtComponents": { - "./example/lib/catalog/widgets/screen/body_widget.dart": { - "path": "./example/lib/catalog/widgets/screen/body_widget.dart", + "./lib/catalog/widgets/screen/body_widget.dart": { + "path": "./lib/catalog/widgets/screen/body_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/body_widget.dart", "clazzName": "BodyWidgetPreviewPreviewPageDummy", @@ -73,8 +101,8 @@ ] } }, - "./example/lib/catalog/widgets/screen/counter_widget.dart": { - "path": "./example/lib/catalog/widgets/screen/counter_widget.dart", + "./lib/catalog/widgets/screen/counter_widget.dart": { + "path": "./lib/catalog/widgets/screen/counter_widget.dart", "route": "widgets/screen", "package": "package:example/catalog/widgets/screen/counter_widget.dart", "clazzName": "CounterWidgetPreviewPreviewPageDummy", diff --git a/example/integration_test/catalog_widget_integration_test.dart b/example/integration_test/catalog_widget_integration_test.dart index 5a5fb65..325b9d5 100644 --- a/example/integration_test/catalog_widget_integration_test.dart +++ b/example/integration_test/catalog_widget_integration_test.dart @@ -8,18 +8,23 @@ import 'package:integration_test/integration_test.dart'; -import 'package:example/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart' as mzpp; -import 'package:example/widgets/screen/catalog/integration_test/body_widget_integration_test.dart' as satm; -import 'package:example/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart' as azmi; -import 'package:example/widgets/catalog/integration_test/main_screen_integration_test.dart' as kbve; +import 'package:example/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart' + as lcqt; +import 'package:example/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart' + as babq; +import 'package:example/widgets/screen/catalog/integration_test/body_widget_integration_test.dart' + as izvv; +import 'package:example/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart' + as dmnb; +import 'package:example/widgets/catalog/integration_test/main_screen_integration_test.dart' + as eyhi; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - mzpp.FabWidgetIntegrationTest().main(); -satm.BodyWidgetIntegrationTest().main(); -azmi.CounterWidgetIntegrationTest().main(); -kbve.MainScreenIntegrationTest().main(); + lcqt.FabWidgetIntegrationTest().main(); + babq.WarningInfoWidgetIntegrationTest().main(); + izvv.BodyWidgetIntegrationTest().main(); + dmnb.CounterWidgetIntegrationTest().main(); + eyhi.MainScreenIntegrationTest().main(); } - - \ No newline at end of file diff --git a/example/lib/catalog/catalog_component.dart b/example/lib/catalog/catalog_component.dart index bbed7f9..25f7235 100644 --- a/example/lib/catalog/catalog_component.dart +++ b/example/lib/catalog/catalog_component.dart @@ -3,126 +3,117 @@ import 'package:flutter/material.dart'; import 'package:catalog/catalog.dart'; - import 'package:example/catalog/widgets/utils/bottom/fab_widget.dart'; - - - - - - -import 'package:example/catalog/widgets/screen/body_widget.dart';import 'package:example/catalog/widgets/screen/counter_widget.dart'; +import 'package:example/catalog/widgets/other_utils/bottom/warning_info_widget.dart'; - +import 'package:example/catalog/widgets/screen/body_widget.dart'; +import 'package:example/catalog/widgets/screen/counter_widget.dart'; import 'package:example/catalog/widgets/main_screen.dart'; - - - - - - class CatalogComponent extends StatefulWidget { static String routeName = '/catalog'; - - static GoRoute route = GoRoute( - path: CatalogComponent.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CatalogComponent(), - ), - routes: [ - GoRoute( - path: 'widgets', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - - GoRoute( - path: MainScreenPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const MainScreenPreviewPreviewPageDummy(), - ), - ) - - - , - GoRoute( - path: 'utils', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - - - GoRoute( - path: 'bottom', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - - GoRoute( - path: FabWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const FabWidgetPreviewPreviewPageDummy(), + + static GoRoute route = GoRoute( + path: CatalogComponent.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CatalogComponent(), + ), + routes: [ + GoRoute( + path: 'widgets', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: MainScreenPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const MainScreenPreviewPreviewPageDummy(), + ), ), - ) - - - , - - ], - ) - - ], - ) - , GoRoute( - path: 'screen', - redirect: (context, state) { - if (state.fullPath != state.matchedLocation) return null; - return CatalogComponent.routeName; - }, - routes: [ - - GoRoute( - path: BodyWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const BodyWidgetPreviewPreviewPageDummy(), + GoRoute( + path: 'utils', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: 'bottom', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: FabWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const FabWidgetPreviewPreviewPageDummy(), + ), + ), + ], + ) + ], ), - ) - - , - GoRoute( - path: CounterWidgetPreviewPreviewPageDummy.routeName, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: const CounterWidgetPreviewPreviewPageDummy(), + GoRoute( + path: 'other_utils', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: 'bottom', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: WarningInfoWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const WarningInfoWidgetPreviewPreviewPageDummy(), + ), + ), + ], + ) + ], ), - ) - - - , - - ], - ) - - ], - ) - - ], + GoRoute( + path: 'screen', + redirect: (context, state) { + if (state.fullPath != state.matchedLocation) return null; + return CatalogComponent.routeName; + }, + routes: [ + GoRoute( + path: BodyWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const BodyWidgetPreviewPreviewPageDummy(), + ), + ), + GoRoute( + path: CounterWidgetPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const CounterWidgetPreviewPreviewPageDummy(), + ), + ), + ], + ) + ], ) -; - + ], + ); + const CatalogComponent({super.key}); @override @@ -130,7 +121,6 @@ class CatalogComponent extends StatefulWidget { } class CatalogComponentState extends State { - @override Widget build(BuildContext context) { return FutureBuilder( @@ -159,5 +149,3 @@ class CatalogComponentState extends State { ); } } - - \ No newline at end of file diff --git a/example/lib/catalog/widgets/main_screen.dart b/example/lib/catalog/widgets/main_screen.dart index 8478f34..2435fa2 100644 --- a/example/lib/catalog/widgets/main_screen.dart +++ b/example/lib/catalog/widgets/main_screen.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/catalog/preview/main_screen.preview.dart'; class MainScreenPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'main_screen'; - + const MainScreenPreviewPreviewPageDummy({super.key}); @override - MainScreenPreviewPreviewPageDummyState createState() => MainScreenPreviewPreviewPageDummyState(); + MainScreenPreviewPreviewPageDummyState createState() => + MainScreenPreviewPreviewPageDummyState(); } -class MainScreenPreviewPreviewPageDummyState extends State { +class MainScreenPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const MainScreenPreview(); } } - \ No newline at end of file diff --git a/example/lib/catalog/widgets/screen/body_widget.dart b/example/lib/catalog/widgets/screen/body_widget.dart index 54eb25b..57f4c75 100644 --- a/example/lib/catalog/widgets/screen/body_widget.dart +++ b/example/lib/catalog/widgets/screen/body_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/body_widget.preview.dart'; class BodyWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'body_widget'; - + const BodyWidgetPreviewPreviewPageDummy({super.key}); @override - BodyWidgetPreviewPreviewPageDummyState createState() => BodyWidgetPreviewPreviewPageDummyState(); + BodyWidgetPreviewPreviewPageDummyState createState() => + BodyWidgetPreviewPreviewPageDummyState(); } -class BodyWidgetPreviewPreviewPageDummyState extends State { +class BodyWidgetPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const BodyWidgetPreview(); } } - \ No newline at end of file diff --git a/example/lib/catalog/widgets/screen/counter_widget.dart b/example/lib/catalog/widgets/screen/counter_widget.dart index 0d5e240..dc4cda2 100644 --- a/example/lib/catalog/widgets/screen/counter_widget.dart +++ b/example/lib/catalog/widgets/screen/counter_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/screen/catalog/preview/counter_widget.preview.dart'; class CounterWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'counter_widget'; - + const CounterWidgetPreviewPreviewPageDummy({super.key}); @override - CounterWidgetPreviewPreviewPageDummyState createState() => CounterWidgetPreviewPreviewPageDummyState(); + CounterWidgetPreviewPreviewPageDummyState createState() => + CounterWidgetPreviewPreviewPageDummyState(); } -class CounterWidgetPreviewPreviewPageDummyState extends State { +class CounterWidgetPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const CounterWidgetPreview(); } } - \ No newline at end of file diff --git a/example/lib/catalog/widgets/utils/bottom/fab_widget.dart b/example/lib/catalog/widgets/utils/bottom/fab_widget.dart index 0fc351c..5b10f36 100644 --- a/example/lib/catalog/widgets/utils/bottom/fab_widget.dart +++ b/example/lib/catalog/widgets/utils/bottom/fab_widget.dart @@ -4,19 +4,19 @@ import 'package:flutter/material.dart'; import 'package:example/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart'; class FabWidgetPreviewPreviewPageDummy extends StatefulWidget { - static String routeName = 'fab_widget'; - + const FabWidgetPreviewPreviewPageDummy({super.key}); @override - FabWidgetPreviewPreviewPageDummyState createState() => FabWidgetPreviewPreviewPageDummyState(); + FabWidgetPreviewPreviewPageDummyState createState() => + FabWidgetPreviewPreviewPageDummyState(); } -class FabWidgetPreviewPreviewPageDummyState extends State { +class FabWidgetPreviewPreviewPageDummyState + extends State { @override Widget build(BuildContext context) { return const FabWidgetPreview(); } } - \ No newline at end of file diff --git a/example/lib/widgets/catalog/preview/main_screen.preview.dart b/example/lib/widgets/catalog/preview/main_screen.preview.dart index 41ff423..7095ff7 100644 --- a/example/lib/widgets/catalog/preview/main_screen.preview.dart +++ b/example/lib/widgets/catalog/preview/main_screen.preview.dart @@ -11,17 +11,17 @@ import '../dummy/main_screen.dummy.dart'; 'infoText', 'counter', 'incrementCounter', - ],) + ], +) class MainScreenPreview extends ParentPreviewWidget { - @override String get title => 'main_screen'; - + @override String get basePath => '/catalog'; - + const MainScreenPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -106,24 +106,25 @@ class MainScreenPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < MainScreenDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => MainScreenDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return buildMainScreen(dummy); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => MainScreenDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildMainScreen(dummy); + }, + ), ], ) ], ); } - - } MainScreen buildMainScreen(Dummy dummy) { - return MainScreen(title: dummy.parameters['title'],infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],incrementCounter: dummy.parameters['incrementCounter'],); + return MainScreen( + title: dummy.parameters['title'], + infoText: dummy.parameters['infoText'], + counter: dummy.parameters['counter'], + incrementCounter: dummy.parameters['incrementCounter'], + ); } - \ No newline at end of file diff --git a/example/lib/widgets/catalog/test/main_screen_test.dart b/example/lib/widgets/catalog/test/main_screen_test.dart index 04c23b6..fa49037 100644 --- a/example/lib/widgets/catalog/test/main_screen_test.dart +++ b/example/lib/widgets/catalog/test/main_screen_test.dart @@ -17,7 +17,7 @@ class MainScreenTest { () { testWidgets( 'Finds title and info text', - (tester) async { + (tester) async { await tester.setupContext(); final dummy = MainScreenDummy().dummies.first; final widget = buildMainScreen(dummy); @@ -30,7 +30,7 @@ class MainScreenTest { testWidgets( 'Web title not displayed on widget', - (tester) async { + (tester) async { await tester.setupContext(); final dummy = MainScreenDummy().dummies.first; diff --git a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart index c4cc0a7..24af584 100644 --- a/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/body_widget.preview.dart @@ -9,17 +9,17 @@ import '../dummy/body_widget.dummy.dart'; parameters: [ 'infoText', 'counter', - ],) + ], +) class BodyWidgetPreview extends ParentPreviewWidget { - @override String get title => 'body_widget'; - + @override String get basePath => '/catalog'; - + const BodyWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -104,24 +104,23 @@ class BodyWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < BodyWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => BodyWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return buildBodyWidget(dummy); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => BodyWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildBodyWidget(dummy); + }, + ), ], ) ], ); } - - } BodyWidget buildBodyWidget(Dummy dummy) { - return BodyWidget(infoText: dummy.parameters['infoText'],counter: dummy.parameters['counter'],); + return BodyWidget( + infoText: dummy.parameters['infoText'], + counter: dummy.parameters['counter'], + ); } - \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart index 0281f98..04f76ab 100644 --- a/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart +++ b/example/lib/widgets/screen/catalog/preview/counter_widget.preview.dart @@ -9,17 +9,17 @@ import '../dummy/counter_widget.dummy.dart'; description: 'Basic counter widget', parameters: [ 'counter', - ],) + ], +) class CounterWidgetPreview extends ParentPreviewWidget { - @override String get title => 'counter_widget'; - + @override String get basePath => '/catalog'; - + const CounterWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -104,24 +104,22 @@ class CounterWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < CounterWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => CounterWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return buildCounterWidget(dummy); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => CounterWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildCounterWidget(dummy); + }, + ), ], ) ], ); } - - } CounterWidget buildCounterWidget(Dummy dummy) { - return CounterWidget(counter: dummy.parameters['counter'],); + return CounterWidget( + counter: dummy.parameters['counter'], + ); } - \ No newline at end of file diff --git a/example/lib/widgets/screen/catalog/test/body_widget_test.dart b/example/lib/widgets/screen/catalog/test/body_widget_test.dart index ab4ad94..456ae84 100644 --- a/example/lib/widgets/screen/catalog/test/body_widget_test.dart +++ b/example/lib/widgets/screen/catalog/test/body_widget_test.dart @@ -37,7 +37,8 @@ class BodyWidgetTest { final widget = buildBodyWidget(dummy); await tester.test(widget); - expect(find.text('You have pushed the button this many times:'), findsAny); + expect(find.text('You have pushed the button this many times:'), + findsAny); }, ); }, diff --git a/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart index e4de07b..8b87e15 100644 --- a/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart +++ b/example/lib/widgets/utils/bottom/catalog/preview/fab_widget.preview.dart @@ -7,17 +7,17 @@ import '../dummy/fab_widget.dummy.dart'; @Preview( description: 'Basic fab widget', - parameters: ['incrementCounter'],) + parameters: ['incrementCounter'], +) class FabWidgetPreview extends ParentPreviewWidget { - @override String get title => 'fab_widget'; - + @override String get basePath => '/catalog'; - + const FabWidgetPreview({super.key}); - + @override Widget preview(BuildContext context) { Catalog().widgetBasicPreviewMap.clear(); @@ -102,24 +102,22 @@ class FabWidgetPreview extends ParentPreviewWidget { ), ), for (int i = 0; i < FabWidgetDummy().dummies.length; i++) - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => FabWidgetDummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return buildFabWidget(dummy); - }, - ), - + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => FabWidgetDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildFabWidget(dummy); + }, + ), ], ) ], ); } - - } FabWidget buildFabWidget(Dummy dummy) { - return FabWidget(incrementCounter: dummy.parameters['incrementCounter'],); + return FabWidget( + incrementCounter: dummy.parameters['incrementCounter'], + ); } - \ No newline at end of file diff --git a/example/test/catalog_widget_test.dart b/example/test/catalog_widget_test.dart index 445b0c7..f86e9dc 100644 --- a/example/test/catalog_widget_test.dart +++ b/example/test/catalog_widget_test.dart @@ -1,15 +1,19 @@ /// AUTOGENERATED FILE. DO NOT EDIT -import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' as cfxg; -import 'package:example/widgets/screen/catalog/test/body_widget_test.dart' as puqi; -import 'package:example/widgets/screen/catalog/test/counter_widget_test.dart' as cmom; -import 'package:example/widgets/catalog/test/main_screen_test.dart' as ldag; +import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' + as duva; +import 'package:example/widgets/other_utils/bottom/catalog/test/warning_info_widget_test.dart' + as lklr; +import 'package:example/widgets/screen/catalog/test/body_widget_test.dart' + as gexd; +import 'package:example/widgets/screen/catalog/test/counter_widget_test.dart' + as xhiv; +import 'package:example/widgets/catalog/test/main_screen_test.dart' as dakn; void main() { - cfxg.FabWidgetTest().main(); -puqi.BodyWidgetTest().main(); -cmom.CounterWidgetTest().main(); -ldag.MainScreenTest().main(); + duva.FabWidgetTest().main(); + lklr.WarningInfoWidgetTest().main(); + gexd.BodyWidgetTest().main(); + xhiv.CounterWidgetTest().main(); + dakn.MainScreenTest().main(); } - - \ No newline at end of file From 392f6b4780d8a31481dbd5f2c062d83999e1a391 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sun, 6 Oct 2024 17:33:24 +0200 Subject: [PATCH 21/28] feature: new tasks, stringcare on dynamic test mode --- .flutter-plugins | 3 + .flutter-plugins-dependencies | 1 + bin/integration_test.dart | 8 + bin/test.dart | 8 + .../catalog_widget_integration_test.dart | 20 +- example/lib/catalog/README.md | 18 ++ .../main_screen_integration_test.dart | 4 +- .../catalog/test/main_screen_test.dart | 8 +- .../warning_info_widget_integration_test.dart | 4 +- .../body_widget_integration_test.dart | 4 +- .../screen/catalog/test/body_widget_test.dart | 4 +- example/pubspec.yaml | 2 +- example/test/catalog_widget_test.dart | 20 +- .../catalog_builder.dart | 35 +++ lib/src/bin/builders/common_builder.dart | 24 ++ .../dummy_builder.dart | 0 lib/src/bin/builders/preview_builder.dart | 181 ++++++++++++++ .../test_builder.dart} | 235 ++---------------- lib/src/bin/tasks/integration_test_task.dart | 25 ++ lib/src/bin/tasks/main_task.dart | 8 +- lib/src/bin/tasks/preview_task.dart | 4 +- lib/src/bin/tasks/tasks/catalog_task.dart | 9 +- ...t_task.dart => integration_test_task.dart} | 10 +- lib/src/bin/tasks/tasks/preview_task.dart | 6 +- lib/src/bin/tasks/tasks/test_task.dart | 8 +- lib/src/bin/tasks/test_task.dart | 25 ++ lib/src/bin/utils/messages.dart | 8 + lib/src/extensions/widget_test_ext.dart | 20 +- pubspec.yaml | 2 +- 29 files changed, 439 insertions(+), 265 deletions(-) create mode 100644 .flutter-plugins create mode 100644 .flutter-plugins-dependencies create mode 100644 bin/integration_test.dart create mode 100644 bin/test.dart create mode 100644 example/lib/catalog/README.md rename lib/src/bin/{catalog_builder => builders}/catalog_builder.dart (76%) create mode 100644 lib/src/bin/builders/common_builder.dart rename lib/src/bin/{preview_builder => builders}/dummy_builder.dart (100%) create mode 100644 lib/src/bin/builders/preview_builder.dart rename lib/src/bin/{preview_builder/preview_builder.dart => builders/test_builder.dart} (50%) create mode 100644 lib/src/bin/tasks/integration_test_task.dart rename lib/src/bin/tasks/tasks/{instrumented_test_task.dart => integration_test_task.dart} (87%) create mode 100644 lib/src/bin/tasks/test_task.dart create mode 100644 lib/src/bin/utils/messages.dart diff --git a/.flutter-plugins b/.flutter-plugins new file mode 100644 index 0000000..cd71e30 --- /dev/null +++ b/.flutter-plugins @@ -0,0 +1,3 @@ +# This is a generated file; do not edit or check into version control. +integration_test=/Users/efrain.espada@feverup.com/Development/flutter/packages/integration_test/ +stringcare=/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/ diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies new file mode 100644 index 0000000..c883dd9 --- /dev/null +++ b/.flutter-plugins-dependencies @@ -0,0 +1 @@ +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"/Users/efrain.espada@feverup.com/Development/flutter/packages/integration_test/","native_build":true,"dependencies":[]},{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"android":[{"name":"integration_test","path":"/Users/efrain.espada@feverup.com/Development/flutter/packages/integration_test/","native_build":true,"dependencies":[]},{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"macos":[{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"linux":[{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"windows":[{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"web":[{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","dependencies":[]}]},"dependencyGraph":[{"name":"integration_test","dependencies":[]},{"name":"stringcare","dependencies":[]}],"date_created":"2024-10-06 16:03:34.166454","version":"3.24.3","swift_package_manager_enabled":false} \ No newline at end of file diff --git a/bin/integration_test.dart b/bin/integration_test.dart new file mode 100644 index 0000000..259287e --- /dev/null +++ b/bin/integration_test.dart @@ -0,0 +1,8 @@ +import 'package:catalog/src/bin/tasks/integration_test_task.dart'; +import 'package:catalog/src/bin/utils/configuration.dart'; + +void main(List arguments) async { + var dependencies = loadDependenciesFile(''); + print(introMessage(dependencies['catalog'].toString())); + await IntegrationTestTask().work([]); +} diff --git a/bin/test.dart b/bin/test.dart new file mode 100644 index 0000000..a19721d --- /dev/null +++ b/bin/test.dart @@ -0,0 +1,8 @@ +import 'package:catalog/src/bin/tasks/test_task.dart'; +import 'package:catalog/src/bin/utils/configuration.dart'; + +void main(List arguments) async { + var dependencies = loadDependenciesFile(''); + print(introMessage(dependencies['catalog'].toString())); + await TestTask().work([]); +} diff --git a/example/integration_test/catalog_widget_integration_test.dart b/example/integration_test/catalog_widget_integration_test.dart index 325b9d5..52912c2 100644 --- a/example/integration_test/catalog_widget_integration_test.dart +++ b/example/integration_test/catalog_widget_integration_test.dart @@ -9,22 +9,22 @@ import 'package:integration_test/integration_test.dart'; import 'package:example/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart' - as lcqt; + as fwie; import 'package:example/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart' - as babq; + as aznv; import 'package:example/widgets/screen/catalog/integration_test/body_widget_integration_test.dart' - as izvv; + as yzoq; import 'package:example/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart' - as dmnb; + as zciv; import 'package:example/widgets/catalog/integration_test/main_screen_integration_test.dart' - as eyhi; + as lwvd; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - lcqt.FabWidgetIntegrationTest().main(); - babq.WarningInfoWidgetIntegrationTest().main(); - izvv.BodyWidgetIntegrationTest().main(); - dmnb.CounterWidgetIntegrationTest().main(); - eyhi.MainScreenIntegrationTest().main(); + fwie.FabWidgetIntegrationTest().main(); + aznv.WarningInfoWidgetIntegrationTest().main(); + yzoq.BodyWidgetIntegrationTest().main(); + zciv.CounterWidgetIntegrationTest().main(); + lwvd.MainScreenIntegrationTest().main(); } diff --git a/example/lib/catalog/README.md b/example/lib/catalog/README.md new file mode 100644 index 0000000..a6fab50 --- /dev/null +++ b/example/lib/catalog/README.md @@ -0,0 +1,18 @@ +# Catalog in example + +This is your catalog in example. It shows the widgets that contain `@Preview` in the header. + +You should not manipulate it yourself. If you observe any unexpected behavior please [open an issue on Github](https://github.com/landamessenger/catalog/issues). We will try to fix it as soon as possible. + +Generate dummies, previews (override every time) and tests with: + +```bash +dart run catalog:preview +``` + +All the above plus catalog generation. + +```bash +dart run catalog:build +``` + \ No newline at end of file diff --git a/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart b/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart index fbaa7fc..aa42299 100644 --- a/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart +++ b/example/lib/widgets/catalog/integration_test/main_screen_integration_test.dart @@ -18,7 +18,7 @@ class MainScreenIntegrationTest { testWidgets( 'Finds title and info text', (tester) async { - await tester.setupContext(); + await tester.setupIntegrationTestContext(); final dummy = MainScreenDummy().dummies.first; final widget = buildMainScreen(dummy); await tester.test(widget); @@ -31,7 +31,7 @@ class MainScreenIntegrationTest { testWidgets( 'Web title not displayed on widget', (tester) async { - await tester.setupContext(); + await tester.setupIntegrationTestContext(); final dummy = MainScreenDummy().dummies.first; final widget = buildMainScreen(dummy); diff --git a/example/lib/widgets/catalog/test/main_screen_test.dart b/example/lib/widgets/catalog/test/main_screen_test.dart index fa49037..2c8dd46 100644 --- a/example/lib/widgets/catalog/test/main_screen_test.dart +++ b/example/lib/widgets/catalog/test/main_screen_test.dart @@ -18,20 +18,20 @@ class MainScreenTest { testWidgets( 'Finds title and info text', (tester) async { - await tester.setupContext(); + await tester.setupTestContext(); final dummy = MainScreenDummy().dummies.first; final widget = buildMainScreen(dummy); await tester.test(widget); - expect(find.text(R.strings.title_app.string()), findsAny); - expect(find.text(R.strings.info_text.string()), findsAny); + expect(find.text(R.strings.title_app.string()), findsOneWidget); + expect(find.text(R.strings.info_text.string()), findsOneWidget); }, ); testWidgets( 'Web title not displayed on widget', (tester) async { - await tester.setupContext(); + await tester.setupTestContext(); final dummy = MainScreenDummy().dummies.first; final widget = buildMainScreen(dummy); diff --git a/example/lib/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart b/example/lib/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart index 659df09..9522c70 100644 --- a/example/lib/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart +++ b/example/lib/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart @@ -15,7 +15,7 @@ class WarningInfoWidgetIntegrationTest { () { testWidgets( 'Finds text sample', - (tester) async { + (tester) async { final dummy = WarningInfoWidgetDummy().dummies.first; final widget = buildWarningInfoWidget(dummy); await tester.test(widget); @@ -26,7 +26,7 @@ class WarningInfoWidgetIntegrationTest { testWidgets( 'Other lorem text not found', - (tester) async { + (tester) async { final dummy = WarningInfoWidgetDummy().dummies.first; final widget = buildWarningInfoWidget(dummy); await tester.test(widget); diff --git a/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart b/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart index fe54c20..90ca22d 100644 --- a/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart +++ b/example/lib/widgets/screen/catalog/integration_test/body_widget_integration_test.dart @@ -18,7 +18,7 @@ class BodyWidgetIntegrationTest { testWidgets( 'No title is found', (tester) async { - await tester.setupContext(); + await tester.setupIntegrationTestContext(); final dummy = BodyWidgetDummy().dummies.first; final widget = buildBodyWidget(dummy); @@ -31,7 +31,7 @@ class BodyWidgetIntegrationTest { testWidgets( 'Info text is displayed', (tester) async { - await tester.setupContext(); + await tester.setupIntegrationTestContext(); final dummy = BodyWidgetDummy().dummies.first; final widget = buildBodyWidget(dummy); diff --git a/example/lib/widgets/screen/catalog/test/body_widget_test.dart b/example/lib/widgets/screen/catalog/test/body_widget_test.dart index 456ae84..966e690 100644 --- a/example/lib/widgets/screen/catalog/test/body_widget_test.dart +++ b/example/lib/widgets/screen/catalog/test/body_widget_test.dart @@ -18,7 +18,7 @@ class BodyWidgetTest { testWidgets( 'No title is found', (tester) async { - await tester.setupContext(); + await tester.setupTestContext(); final dummy = BodyWidgetDummy().dummies.first; final widget = buildBodyWidget(dummy); @@ -31,7 +31,7 @@ class BodyWidgetTest { testWidgets( 'Info text is displayed', (tester) async { - await tester.setupContext(); + await tester.setupTestContext(); final dummy = BodyWidgetDummy().dummies.first; final widget = buildBodyWidget(dummy); diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 846cb2d..7b9e54f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.8 - stringcare: ^0.1.7 # android ios linux macos web windows + stringcare: ^1.0.0 # android ios linux macos web windows catalog: path: ../ diff --git a/example/test/catalog_widget_test.dart b/example/test/catalog_widget_test.dart index f86e9dc..136f09b 100644 --- a/example/test/catalog_widget_test.dart +++ b/example/test/catalog_widget_test.dart @@ -1,19 +1,19 @@ /// AUTOGENERATED FILE. DO NOT EDIT import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' - as duva; + as dmsz; import 'package:example/widgets/other_utils/bottom/catalog/test/warning_info_widget_test.dart' - as lklr; + as zjri; import 'package:example/widgets/screen/catalog/test/body_widget_test.dart' - as gexd; + as cpsh; import 'package:example/widgets/screen/catalog/test/counter_widget_test.dart' - as xhiv; -import 'package:example/widgets/catalog/test/main_screen_test.dart' as dakn; + as atcw; +import 'package:example/widgets/catalog/test/main_screen_test.dart' as lsrx; void main() { - duva.FabWidgetTest().main(); - lklr.WarningInfoWidgetTest().main(); - gexd.BodyWidgetTest().main(); - xhiv.CounterWidgetTest().main(); - dakn.MainScreenTest().main(); + dmsz.FabWidgetTest().main(); + zjri.WarningInfoWidgetTest().main(); + cpsh.BodyWidgetTest().main(); + atcw.CounterWidgetTest().main(); + lsrx.MainScreenTest().main(); } diff --git a/lib/src/bin/catalog_builder/catalog_builder.dart b/lib/src/bin/builders/catalog_builder.dart similarity index 76% rename from lib/src/bin/catalog_builder/catalog_builder.dart rename to lib/src/bin/builders/catalog_builder.dart index 53e8891..f00c62a 100644 --- a/lib/src/bin/catalog_builder/catalog_builder.dart +++ b/lib/src/bin/builders/catalog_builder.dart @@ -117,3 +117,38 @@ ComponentNode buildTreeFromMap( return root; } + +Future generateCatalogReadme( + String basePath, + dynamic config, +) async { + String readmeFolderPath = './$basePath${config['base']}/${config['output']}'; + + await Directory(readmeFolderPath).create(recursive: true); + + File file = File('$readmeFolderPath/README.md'); + + print('📃 Updating catalog README.md (${file.path})'); + + var content = ''' +# Catalog in example + +This is your catalog in example. It shows the widgets that contain `@Preview` in the header. + +You should not manipulate it yourself. If you observe any unexpected behavior please [open an issue on Github](https://github.com/landamessenger/catalog/issues). We will try to fix it as soon as possible. + +Generate dummies, previews (override every time) and tests with: + +```bash +dart run catalog:preview +``` + +All the above plus catalog generation. + +```bash +dart run catalog:build +``` + '''; + + await file.writeAsString(content); +} diff --git a/lib/src/bin/builders/common_builder.dart b/lib/src/bin/builders/common_builder.dart new file mode 100644 index 0000000..5487ac0 --- /dev/null +++ b/lib/src/bin/builders/common_builder.dart @@ -0,0 +1,24 @@ +import 'dart:io'; + +Future findClassName(String path) async { + try { + File file = File(path); + final content = await file.readAsString(); + return '${content.split("class ")[1].split(" ").first.trim()}()'; + } catch (e) { + print(e); + return null; + } +} + +Future findPreviewAnnotation(String path) async { + try { + File file = File(path); + final content = await file.readAsString(); + return '@Preview${content.split("@Preview")[1].split(''') +class''').first.trim()})'; + } catch (e) { + print(e); + return null; + } +} diff --git a/lib/src/bin/preview_builder/dummy_builder.dart b/lib/src/bin/builders/dummy_builder.dart similarity index 100% rename from lib/src/bin/preview_builder/dummy_builder.dart rename to lib/src/bin/builders/dummy_builder.dart diff --git a/lib/src/bin/builders/preview_builder.dart b/lib/src/bin/builders/preview_builder.dart new file mode 100644 index 0000000..4ea79b3 --- /dev/null +++ b/lib/src/bin/builders/preview_builder.dart @@ -0,0 +1,181 @@ +import 'dart:io'; + +import 'package:catalog/src/annotations/internal_preview.dart'; + +Future generatePreview( + dynamic config, + String srcPath, + String classImport, + String previewAnnotation, + String className, + String prefix, + InternalPreview preview, +) async { + var clazz = className.replaceAll('()', ''); + + var widgetCompose = dummyWidgetContent(className, preview); + + String fileName = srcPath.split('/').last; + String name = fileName.split('.').first; + + var content = ''' +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:catalog/catalog.dart'; +import 'package:flutter/material.dart'; +import '$classImport'; +import '../dummy/$name.dummy.dart'; + +$previewAnnotation +class ${clazz}Preview extends ParentPreviewWidget { + + @override + String get title => '$name'; + + @override + String get basePath => '/${config['pageRoute']}'; + + const ${clazz}Preview({super.key}); + + @override + Widget preview(BuildContext context) { + Catalog().widgetBasicPreviewMap.clear(); + Catalog().widgetDevicePreviewMap.clear(); + + if (${clazz}Dummy().dummies.isEmpty) { + return Container(); + } + + final deviceScreenshotsAvailable = + ${clazz}Dummy().deviceScreenshotsAvailable; + final screenshotsAvailable = ${clazz}Dummy().screenshotsAvailable; + + int basicScreenshots = screenshotsAvailable - deviceScreenshotsAvailable; + + return ListView( + children: [ + Column( + children: [ + if (basicScreenshots > 0) + Center( + child: Container( + constraints: const BoxConstraints( + maxWidth: 400, + ), + child: Card( + clipBehavior: Clip.hardEdge, + child: Container( + padding: const EdgeInsets.all(15), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Center( + child: Text( + '\$basicScreenshots basic screenshots available', + ), + ), + ), + const IconButton( + onPressed: processBasicScreenshots, + icon: Icon( + Icons.screenshot, + ), + ) + ], + ), + ), + ), + ), + ), + if (deviceScreenshotsAvailable > 0) + Center( + child: Container( + constraints: const BoxConstraints( + maxWidth: 400, + ), + child: Card( + clipBehavior: Clip.hardEdge, + child: Container( + padding: const EdgeInsets.all(15), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Center( + child: Text( + '\$deviceScreenshotsAvailable device screenshots available', + ), + ), + ), + const IconButton( + onPressed: processDeviceScreenshots, + icon: Icon( + Icons.screenshot, + ), + ) + ], + ), + ), + ), + ), + ), + for (int i = 0; i < ${clazz}Dummy().dummies.length; i++) + ${dummyWidgetBuilder(clazz)} + ], + ) + ], + ); + } + + +} + +$clazz build$clazz(Dummy dummy) { + return $widgetCompose; +} + '''; + + String dirPath = srcPath.replaceAll(fileName, ''); + String previewPath = '${dirPath}catalog/preview/'; + + await Directory(previewPath).create(recursive: true); + + String previewFile = '$previewPath$name.$prefix.dart'; + + print('🩻 Generating preview for $clazz - ${clazz}Preview ($previewFile)'); + + File file = File(previewFile); + await file.writeAsString(content); +} + +String dummyWidgetBuilder(String clazz) { + return ''' + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => ${clazz}Dummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return build$clazz(dummy); + }, + ), + '''; +} + +String dummyWidgetContent(String className, InternalPreview preview) { + var clazz = className.replaceAll('()', ''); + + var widgetCompose = '$clazz('; + + var params = preview.parameters; + if (params.isNotEmpty) { + widgetCompose += ''; + for (String key in params) { + widgetCompose += '''$key: dummy.parameters['$key'],'''; + } + widgetCompose += ''; + } + + widgetCompose += ')'; + + return widgetCompose; +} diff --git a/lib/src/bin/preview_builder/preview_builder.dart b/lib/src/bin/builders/test_builder.dart similarity index 50% rename from lib/src/bin/preview_builder/preview_builder.dart rename to lib/src/bin/builders/test_builder.dart index 0ca1458..d3e991d 100644 --- a/lib/src/bin/preview_builder/preview_builder.dart +++ b/lib/src/bin/builders/test_builder.dart @@ -1,167 +1,8 @@ import 'dart:io'; import 'dart:math'; -import 'package:catalog/src/annotations/internal_preview.dart'; import 'package:catalog/src/bin/utils/test_builder_info.dart'; -Future findClassName(String path) async { - try { - File file = File(path); - final content = await file.readAsString(); - return '${content.split("class ")[1].split(" ").first.trim()}()'; - } catch (e) { - print(e); - return null; - } -} - -Future generatePreview( - dynamic config, - String srcPath, - String classImport, - String previewAnnotation, - String className, - String prefix, - InternalPreview preview, -) async { - var clazz = className.replaceAll('()', ''); - - var widgetCompose = dummyWidgetContent(className, preview); - - String fileName = srcPath.split('/').last; - String name = fileName.split('.').first; - - var content = ''' -/// AUTOGENERATED FILE. DO NOT EDIT - -import 'package:catalog/catalog.dart'; -import 'package:flutter/material.dart'; -import '$classImport'; -import '../dummy/$name.dummy.dart'; - -$previewAnnotation -class ${clazz}Preview extends ParentPreviewWidget { - - @override - String get title => '$name'; - - @override - String get basePath => '/${config['pageRoute']}'; - - const ${clazz}Preview({super.key}); - - @override - Widget preview(BuildContext context) { - Catalog().widgetBasicPreviewMap.clear(); - Catalog().widgetDevicePreviewMap.clear(); - - if (${clazz}Dummy().dummies.isEmpty) { - return Container(); - } - - final deviceScreenshotsAvailable = - ${clazz}Dummy().deviceScreenshotsAvailable; - final screenshotsAvailable = ${clazz}Dummy().screenshotsAvailable; - - int basicScreenshots = screenshotsAvailable - deviceScreenshotsAvailable; - - return ListView( - children: [ - Column( - children: [ - if (basicScreenshots > 0) - Center( - child: Container( - constraints: const BoxConstraints( - maxWidth: 400, - ), - child: Card( - clipBehavior: Clip.hardEdge, - child: Container( - padding: const EdgeInsets.all(15), - color: Colors.white, - child: Row( - children: [ - Expanded( - child: Center( - child: Text( - '\$basicScreenshots basic screenshots available', - ), - ), - ), - const IconButton( - onPressed: processBasicScreenshots, - icon: Icon( - Icons.screenshot, - ), - ) - ], - ), - ), - ), - ), - ), - if (deviceScreenshotsAvailable > 0) - Center( - child: Container( - constraints: const BoxConstraints( - maxWidth: 400, - ), - child: Card( - clipBehavior: Clip.hardEdge, - child: Container( - padding: const EdgeInsets.all(15), - color: Colors.white, - child: Row( - children: [ - Expanded( - child: Center( - child: Text( - '\$deviceScreenshotsAvailable device screenshots available', - ), - ), - ), - const IconButton( - onPressed: processDeviceScreenshots, - icon: Icon( - Icons.screenshot, - ), - ) - ], - ), - ), - ), - ), - ), - for (int i = 0; i < ${clazz}Dummy().dummies.length; i++) - ${dummyWidgetBuilder(clazz)} - ], - ) - ], - ); - } - - -} - -$clazz build$clazz(Dummy dummy) { - return $widgetCompose; -} - '''; - - String dirPath = srcPath.replaceAll(fileName, ''); - String previewPath = '${dirPath}catalog/preview/'; - - await Directory(previewPath).create(recursive: true); - - String previewFile = '$previewPath$name.$prefix.dart'; - - print('🩻 Generating preview for $clazz - ${clazz}Preview ($previewFile)'); - - File file = File(previewFile); - await file.writeAsString(content); -} - Future generateTest( dynamic config, String srcPath, @@ -218,22 +59,32 @@ class ${clazz}Test { testWidgets( 'Lorem text not found', (tester) async { + // prepare the context + await setupTestContext(); + + // prepare the widget final dummy = ${clazz}Dummy().dummies.first; final widget = build$clazz(dummy); await tester.test(widget); - expect(find.text('lorem ipsu'), findsNothing); + // check + expect(find.text('cómo están los máquinas'), findsNothing); }, ); testWidgets( 'Other lorem text not found', (tester) async { + // prepare the context + await setupTestContext(); + + // prepare the widget final dummy = ${clazz}Dummy().dummies.first; final widget = build$clazz(dummy); await tester.test(widget); - expect(find.text('ipsu lorem'), findsNothing); + // check + expect(find.text('lo primero de todo'), findsNothing); }, ); }, @@ -308,22 +159,32 @@ class ${clazz}IntegrationTest { testWidgets( 'Lorem text not found', (tester) async { + // prepare the context + await setupIntegrationTestContext(); + + // prepare the widget final dummy = ${clazz}Dummy().dummies.first; final widget = build$clazz(dummy); await tester.test(widget); - expect(find.text('lorem ipsu'), findsNothing); + // check + expect(find.text('cómo están los máquinas'), findsNothing); }, ); testWidgets( 'Other lorem text not found', (tester) async { + // prepare the context + await setupIntegrationTestContext(); + + // prepare the widget final dummy = ${clazz}Dummy().dummies.first; final widget = build$clazz(dummy); await tester.test(widget); - expect(find.text('ipsu lorem'), findsNothing); + // check + expect(find.text('lo primero de todo'), findsNothing); }, ); }, @@ -372,13 +233,12 @@ Future generateMainIntegrationTest( String basePath, List tests, ) async { - String testPath = './${basePath}integration_test/'; await Directory(testPath).create(recursive: true); - - File file = File('./${basePath}integration_test/catalog_widget_integration_test.dart'); + File file = File( + './${basePath}integration_test/catalog_widget_integration_test.dart'); print('🧪 Updating catalog integration test collector (${file.path})'); @@ -416,46 +276,3 @@ String buildTestAlias(int size) { return String.fromCharCodes(Iterable.generate( size, (_) => chars.codeUnitAt(random.nextInt(chars.length)))); } - -String dummyWidgetBuilder(String clazz) { - return ''' - PreviewBoundary( - widgetKey: GlobalKey(), - dummyBuilder: () => ${clazz}Dummy().dummies[i], - builder: (BuildContext context, Dummy dummy) { - return build$clazz(dummy); - }, - ), - '''; -} - -String dummyWidgetContent(String className, InternalPreview preview) { - var clazz = className.replaceAll('()', ''); - - var widgetCompose = '$clazz('; - - var params = preview.parameters; - if (params.isNotEmpty) { - widgetCompose += ''; - for (String key in params) { - widgetCompose += '''$key: dummy.parameters['$key'],'''; - } - widgetCompose += ''; - } - - widgetCompose += ')'; - - return widgetCompose; -} - -Future findPreviewAnnotation(String path) async { - try { - File file = File(path); - final content = await file.readAsString(); - return '@Preview${content.split("@Preview")[1].split(''') -class''').first.trim()})'; - } catch (e) { - print(e); - return null; - } -} diff --git a/lib/src/bin/tasks/integration_test_task.dart b/lib/src/bin/tasks/integration_test_task.dart new file mode 100644 index 0000000..080df25 --- /dev/null +++ b/lib/src/bin/tasks/integration_test_task.dart @@ -0,0 +1,25 @@ +import 'package:catalog/src/bin/utils/messages.dart'; + +import 'base/base_task.dart'; +import 'tasks/format_task.dart'; +import 'tasks/integration_test_task.dart' as test; + +class IntegrationTestTask extends BaseTask { + final tasks = [ + test.IntegrationTestTask(), + FormatTask(), + ]; + + @override + Future work(List args) async { + for (BaseTask task in tasks) { + try { + print('\n - Running ${task.runtimeType.toString()} \n'); + await task.work(args); + } catch (e) { + print(e); + } + } + print(commonMessage('🧪📱 Integration tests generated')); + } +} diff --git a/lib/src/bin/tasks/main_task.dart b/lib/src/bin/tasks/main_task.dart index c26ac99..47fd09e 100644 --- a/lib/src/bin/tasks/main_task.dart +++ b/lib/src/bin/tasks/main_task.dart @@ -1,7 +1,9 @@ +import 'package:catalog/src/bin/utils/messages.dart'; + import 'base/base_task.dart'; import 'tasks/catalog_task.dart'; import 'tasks/format_task.dart'; -import 'tasks/instrumented_test_task.dart'; +import 'tasks/integration_test_task.dart'; import 'tasks/preview_task.dart'; import 'tasks/test_task.dart'; @@ -9,7 +11,7 @@ class MainTask extends BaseTask { final tasks = [ PreviewTask(), TestTask(), - InstrumentedTestTask(), + IntegrationTestTask(), CatalogTask(), FormatTask(), ]; @@ -24,6 +26,6 @@ class MainTask extends BaseTask { print(e); } } - print('\n Previews, tests and catalog generated \n'); + print(commonMessage('Previews, tests, integration tests and catalog generated')); } } diff --git a/lib/src/bin/tasks/preview_task.dart b/lib/src/bin/tasks/preview_task.dart index 55ab55c..4aacfc6 100644 --- a/lib/src/bin/tasks/preview_task.dart +++ b/lib/src/bin/tasks/preview_task.dart @@ -1,6 +1,6 @@ import 'base/base_task.dart'; import 'tasks/format_task.dart'; -import 'tasks/instrumented_test_task.dart'; +import 'tasks/integration_test_task.dart'; import 'tasks/preview_task.dart' as preview; import 'tasks/test_task.dart'; @@ -8,7 +8,7 @@ class PreviewTask extends BaseTask { final tasks = [ preview.PreviewTask(), TestTask(), - InstrumentedTestTask(), + IntegrationTestTask(), FormatTask(), ]; diff --git a/lib/src/bin/tasks/tasks/catalog_task.dart b/lib/src/bin/tasks/tasks/catalog_task.dart index 772d709..290ea0f 100644 --- a/lib/src/bin/tasks/tasks/catalog_task.dart +++ b/lib/src/bin/tasks/tasks/catalog_task.dart @@ -1,13 +1,12 @@ import 'dart:io'; import 'package:catalog/src/base/serial.dart'; +import 'package:catalog/src/bin/builders/catalog_builder.dart'; +import 'package:catalog/src/bin/tasks/base/base_task.dart'; +import 'package:catalog/src/bin/utils/configuration.dart'; import 'package:catalog/src/builders/catalog/built_component.dart'; import 'package:catalog/src/builders/catalog/component_node.dart'; -import '../../catalog_builder/catalog_builder.dart'; -import '../../utils/configuration.dart'; -import '../base/base_task.dart'; - class CatalogTask extends BaseTask { @override Future work(List args) async { @@ -159,5 +158,7 @@ class ${pageName}State extends State<$pageName> { final File file = File('./$base${config['base']}/${config['output']}/process.dart'); if (file.existsSync()) await file.delete(); + + await generateCatalogReadme(base, config); } } diff --git a/lib/src/bin/tasks/tasks/instrumented_test_task.dart b/lib/src/bin/tasks/tasks/integration_test_task.dart similarity index 87% rename from lib/src/bin/tasks/tasks/instrumented_test_task.dart rename to lib/src/bin/tasks/tasks/integration_test_task.dart index 2422f5c..78138ef 100644 --- a/lib/src/bin/tasks/tasks/instrumented_test_task.dart +++ b/lib/src/bin/tasks/tasks/integration_test_task.dart @@ -1,12 +1,12 @@ import 'dart:io'; +import 'package:catalog/src/bin/builders/common_builder.dart'; +import 'package:catalog/src/bin/builders/test_builder.dart'; +import 'package:catalog/src/bin/tasks/base/base_task.dart'; +import 'package:catalog/src/bin/utils/configuration.dart'; import 'package:catalog/src/bin/utils/test_builder_info.dart'; -import '../../preview_builder/preview_builder.dart'; -import '../../utils/configuration.dart'; -import '../base/base_task.dart'; - -class InstrumentedTestTask extends BaseTask { +class IntegrationTestTask extends BaseTask { @override Future work(List args) async { final base = args.isEmpty ? '' : '${args.first}/'; diff --git a/lib/src/bin/tasks/tasks/preview_task.dart b/lib/src/bin/tasks/tasks/preview_task.dart index f4728e8..79737dd 100644 --- a/lib/src/bin/tasks/tasks/preview_task.dart +++ b/lib/src/bin/tasks/tasks/preview_task.dart @@ -1,7 +1,9 @@ import 'dart:io'; -import '../../preview_builder/dummy_builder.dart'; -import '../../preview_builder/preview_builder.dart'; +import 'package:catalog/src/bin/builders/common_builder.dart'; + +import '../../builders/dummy_builder.dart'; +import '../../builders/preview_builder.dart'; import '../../utils/configuration.dart'; import '../base/base_task.dart'; diff --git a/lib/src/bin/tasks/tasks/test_task.dart b/lib/src/bin/tasks/tasks/test_task.dart index b3cf032..b11389d 100644 --- a/lib/src/bin/tasks/tasks/test_task.dart +++ b/lib/src/bin/tasks/tasks/test_task.dart @@ -1,11 +1,11 @@ import 'dart:io'; +import 'package:catalog/src/bin/builders/common_builder.dart'; +import 'package:catalog/src/bin/builders/test_builder.dart'; +import 'package:catalog/src/bin/tasks/base/base_task.dart'; +import 'package:catalog/src/bin/utils/configuration.dart'; import 'package:catalog/src/bin/utils/test_builder_info.dart'; -import '../../preview_builder/preview_builder.dart'; -import '../../utils/configuration.dart'; -import '../base/base_task.dart'; - class TestTask extends BaseTask { @override Future work(List args) async { diff --git a/lib/src/bin/tasks/test_task.dart b/lib/src/bin/tasks/test_task.dart new file mode 100644 index 0000000..7be1cf6 --- /dev/null +++ b/lib/src/bin/tasks/test_task.dart @@ -0,0 +1,25 @@ +import 'package:catalog/src/bin/utils/messages.dart'; + +import 'base/base_task.dart'; +import 'tasks/format_task.dart'; +import 'tasks/test_task.dart' as test; + +class TestTask extends BaseTask { + final tasks = [ + test.TestTask(), + FormatTask(), + ]; + + @override + Future work(List args) async { + for (BaseTask task in tasks) { + try { + print('\n - Running ${task.runtimeType.toString()} \n'); + await task.work(args); + } catch (e) { + print(e); + } + } + print(commonMessage('🧪 Tests generated')); + } +} diff --git a/lib/src/bin/utils/messages.dart b/lib/src/bin/utils/messages.dart new file mode 100644 index 0000000..7bb2a43 --- /dev/null +++ b/lib/src/bin/utils/messages.dart @@ -0,0 +1,8 @@ +String commonMessage(String message) => ''' + +✅ $message. + +🐛 Report any issue on https://github.com/landamessenger/catalog/issues + +ℹ️ Check the documentation on https://github.com/landamessenger/catalog/wiki +'''; diff --git a/lib/src/extensions/widget_test_ext.dart b/lib/src/extensions/widget_test_ext.dart index 516f6df..f968fcd 100644 --- a/lib/src/extensions/widget_test_ext.dart +++ b/lib/src/extensions/widget_test_ext.dart @@ -16,8 +16,24 @@ extension WidgetTestExt on WidgetTester { await pumpAndSettle(); } - Future setupContext() async { - Stringcare().langPath = 'lang_base'; + /// The original unencrypted resources are used on test. + /// Uses `dart:io` under the hood. + Future setupTestContext() => _setupContext( + useEncrypted: false, + ); + + /// The encrypted resources are consumed. + Future setupIntegrationTestContext() => _setupContext( + useEncrypted: true, + ); + + /// Disables the Stringcare native libs (.so and .dylib) and uses the Dart + /// implementation. Also configures the encryption status. + Future _setupContext({ + required bool useEncrypted, + }) async { + Stringcare().disableNative = true; + Stringcare().useEncrypted = useEncrypted; await pumpWidget( MaterialApp( navigatorKey: Stringcare().navigatorKey, diff --git a/pubspec.yaml b/pubspec.yaml index 05e84de..47a0fc9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: http: ^1.2.2 # android ios linux macos web windows image: ^4.2.0 # android ios linux macos web windows shelf: ^1.4.1 # android ios linux macos web windows - stringcare: ^0.1.7 # android ios linux macos web windows + stringcare: ^1.0.0 # android ios linux macos web windows vector_graphics: ^1.1.11+1 # android ios linux macos web windows yaml: ^3.1.2 # android ios linux macos web windows yaml_writer: ^2.0.0 # android ios linux macos web windows From d3831c12190ad2a4eff98dd3ea55bc43f8b3f38d Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sun, 6 Oct 2024 17:33:52 +0200 Subject: [PATCH 22/28] feature: updated CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index caf2700..810ac8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ -## 1.0.6 +## 2.0.0 -* Dependencies updated. +* Added `test` and `integration_test` generation. ## 1.0.5 From 6bc09b4800e5a70375e69d00fa38e44cbb002f3f Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sun, 6 Oct 2024 17:34:28 +0200 Subject: [PATCH 23/28] feature: removed not needed files --- .flutter-plugins | 3 --- .flutter-plugins-dependencies | 1 - 2 files changed, 4 deletions(-) delete mode 100644 .flutter-plugins delete mode 100644 .flutter-plugins-dependencies diff --git a/.flutter-plugins b/.flutter-plugins deleted file mode 100644 index cd71e30..0000000 --- a/.flutter-plugins +++ /dev/null @@ -1,3 +0,0 @@ -# This is a generated file; do not edit or check into version control. -integration_test=/Users/efrain.espada@feverup.com/Development/flutter/packages/integration_test/ -stringcare=/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/ diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies deleted file mode 100644 index c883dd9..0000000 --- a/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"/Users/efrain.espada@feverup.com/Development/flutter/packages/integration_test/","native_build":true,"dependencies":[]},{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"android":[{"name":"integration_test","path":"/Users/efrain.espada@feverup.com/Development/flutter/packages/integration_test/","native_build":true,"dependencies":[]},{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"macos":[{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"linux":[{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"windows":[{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","native_build":true,"dependencies":[]}],"web":[{"name":"stringcare","path":"/Users/efrain.espada@feverup.com/.pub-cache/hosted/pub.dev/stringcare-1.0.0/","dependencies":[]}]},"dependencyGraph":[{"name":"integration_test","dependencies":[]},{"name":"stringcare","dependencies":[]}],"date_created":"2024-10-06 16:03:34.166454","version":"3.24.3","swift_package_manager_enabled":false} \ No newline at end of file From 797ec1dd95cf1cf642ff779b1f6d2c1965392b04 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sun, 6 Oct 2024 20:33:54 +0200 Subject: [PATCH 24/28] feature: added sample --- README.md | 11 +- .../catalog_widget_integration_test.dart | 23 ++-- .../catalog/dummy/sized_container.dummy.dart | 24 ++++ .../sized_container_integration_test.dart | 69 ++++++++++ .../preview/sized_container.preview.dart | 124 ++++++++++++++++++ .../catalog/test/sized_container_test.dart | 69 ++++++++++ .../lib/widgets/screen/sized_container.dart | 25 ++++ example/test/catalog_widget_test.dart | 23 ++-- lib/src/bin/builders/dummy_builder.dart | 6 +- lib/src/bin/builders/test_builder.dart | 8 +- lib/src/bin/tasks/preview_task.dart | 4 - lib/src/builders/dummy/preview_dummy.dart | 6 + lib/src/extensions/widget_test_ext.dart | 2 +- 13 files changed, 361 insertions(+), 33 deletions(-) create mode 100644 example/lib/widgets/screen/catalog/dummy/sized_container.dummy.dart create mode 100644 example/lib/widgets/screen/catalog/integration_test/sized_container_integration_test.dart create mode 100644 example/lib/widgets/screen/catalog/preview/sized_container.preview.dart create mode 100644 example/lib/widgets/screen/catalog/test/sized_container_test.dart create mode 100644 example/lib/widgets/screen/sized_container.dart diff --git a/README.md b/README.md index d847416..283bac5 100644 --- a/README.md +++ b/README.md @@ -29,10 +29,16 @@ This package allows you to create a widget catalog and all kinds of screenshots. [- What are dummies?](https://github.com/landamessenger/catalog/wiki/Dummies#what-are-dummies) -[- Complex page catalog](https://github.com/landamessenger/catalog/wiki/Dummies#complex-page-catalog) - [- Prepare dummies](https://github.com/landamessenger/catalog/wiki/Dummies#prepare-dummies) +### [Test](https://github.com/landamessenger/catalog/wiki/Test) + +[- Tests](https://github.com/landamessenger/catalog/wiki/Test#tests) + +[- Integration Tests](https://github.com/landamessenger/catalog/wiki/Test#integration-tests) + +[- Sample](https://github.com/landamessenger/catalog/wiki/Test#sample) + ### [Build & Run](https://github.com/landamessenger/catalog/wiki/Build-&-Run) [- Building your catalog](https://github.com/landamessenger/catalog/wiki/Build-&-Run#building-your-catalog) @@ -52,4 +58,3 @@ This package allows you to create a widget catalog and all kinds of screenshots. [- Samples](https://github.com/landamessenger/catalog/wiki/Screenshots#samples) ### [Catalog Sample](https://landamessenger.com/catalog) - diff --git a/example/integration_test/catalog_widget_integration_test.dart b/example/integration_test/catalog_widget_integration_test.dart index 52912c2..c627714 100644 --- a/example/integration_test/catalog_widget_integration_test.dart +++ b/example/integration_test/catalog_widget_integration_test.dart @@ -9,22 +9,25 @@ import 'package:integration_test/integration_test.dart'; import 'package:example/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart' - as fwie; + as nsyv; import 'package:example/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart' - as aznv; + as fhuz; +import 'package:example/widgets/screen/catalog/integration_test/sized_container_integration_test.dart' + as qaip; import 'package:example/widgets/screen/catalog/integration_test/body_widget_integration_test.dart' - as yzoq; + as afnp; import 'package:example/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart' - as zciv; + as mvnf; import 'package:example/widgets/catalog/integration_test/main_screen_integration_test.dart' - as lwvd; + as gnzn; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - fwie.FabWidgetIntegrationTest().main(); - aznv.WarningInfoWidgetIntegrationTest().main(); - yzoq.BodyWidgetIntegrationTest().main(); - zciv.CounterWidgetIntegrationTest().main(); - lwvd.MainScreenIntegrationTest().main(); + nsyv.FabWidgetIntegrationTest().main(); + fhuz.WarningInfoWidgetIntegrationTest().main(); + qaip.SizedContainerIntegrationTest().main(); + afnp.BodyWidgetIntegrationTest().main(); + mvnf.CounterWidgetIntegrationTest().main(); + gnzn.MainScreenIntegrationTest().main(); } diff --git a/example/lib/widgets/screen/catalog/dummy/sized_container.dummy.dart b/example/lib/widgets/screen/catalog/dummy/sized_container.dummy.dart new file mode 100644 index 0000000..4325143 --- /dev/null +++ b/example/lib/widgets/screen/catalog/dummy/sized_container.dummy.dart @@ -0,0 +1,24 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to prepare the preview and the tests: +/// +/// - SizedContainerPreview +/// - SizedContainerTest +/// - SizedContainerIntegrationTest +/// + +import 'package:catalog/catalog.dart'; +import 'package:flutter/widgets.dart'; + +class SizedContainerDummy extends PreviewDummy { + @override + List get dummies => List.generate( + 8, + (index) => Dummy( + parameters: { + 'width': (index + 1) * 100.0, + 'child': Text(bigText * 4), + }, + ), + ); +} diff --git a/example/lib/widgets/screen/catalog/integration_test/sized_container_integration_test.dart b/example/lib/widgets/screen/catalog/integration_test/sized_container_integration_test.dart new file mode 100644 index 0000000..d3d5734 --- /dev/null +++ b/example/lib/widgets/screen/catalog/integration_test/sized_container_integration_test.dart @@ -0,0 +1,69 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget SizedContainer +/// + +import 'package:catalog/catalog.dart'; +import 'package:flutter/widgets.dart'; + +import '../dummy/sized_container.dummy.dart'; +import '../preview/sized_container.preview.dart'; + +class SizedContainerIntegrationTest { + void main() { + group( + 'SizedContainer - IntegrationTest Tests', + () { + testWidgets( + 'Child does not exceed the width', + (tester) async { + // prepare the context + await tester.setupTestContext(); + + for (var dummy in SizedContainerDummy().dummies) { + // prepare the widget + final widget = buildSizedContainer(dummy); + await tester.test(widget); + + // get the size of the widget + final widgetSize = tester.getSize(find.byWidget(widget)); + + // check the maximum width + expect( + widgetSize.width, + dummy.parameters['width'], + ); + } + }, + ); + + testWidgets( + 'Child does exceed the width', + (tester) async { + // prepare the context + await tester.setupTestContext(); + + for (var dummy in SizedContainerDummy().dummies) { + // prepare the widget + final widget = Container( + child: dummy.parameters['child'], + ); + await tester.test(widget); + + // get the size of the widget + final widgetSize = tester.getSize(find.byWidget(widget)); + + // check the maximum width + expect( + widgetSize.width, + greaterThanOrEqualTo( + dummy.parameters['width'], + ), + ); + } + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/screen/catalog/preview/sized_container.preview.dart b/example/lib/widgets/screen/catalog/preview/sized_container.preview.dart new file mode 100644 index 0000000..b32761d --- /dev/null +++ b/example/lib/widgets/screen/catalog/preview/sized_container.preview.dart @@ -0,0 +1,124 @@ +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:catalog/catalog.dart'; +import 'package:flutter/material.dart'; +import 'package:example/widgets/screen/sized_container.dart'; +import '../dummy/sized_container.dummy.dart'; + +@Preview( + description: 'Container with a max width', + parameters: ['width', 'child'], +) +class SizedContainerPreview extends ParentPreviewWidget { + @override + String get title => 'sized_container'; + + @override + String get basePath => '/catalog'; + + const SizedContainerPreview({super.key}); + + @override + Widget preview(BuildContext context) { + Catalog().widgetBasicPreviewMap.clear(); + Catalog().widgetDevicePreviewMap.clear(); + + if (SizedContainerDummy().dummies.isEmpty) { + return Container(); + } + + final deviceScreenshotsAvailable = + SizedContainerDummy().deviceScreenshotsAvailable; + final screenshotsAvailable = SizedContainerDummy().screenshotsAvailable; + + int basicScreenshots = screenshotsAvailable - deviceScreenshotsAvailable; + + return ListView( + children: [ + Column( + children: [ + if (basicScreenshots > 0) + Center( + child: Container( + constraints: const BoxConstraints( + maxWidth: 400, + ), + child: Card( + clipBehavior: Clip.hardEdge, + child: Container( + padding: const EdgeInsets.all(15), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Center( + child: Text( + '$basicScreenshots basic screenshots available', + ), + ), + ), + const IconButton( + onPressed: processBasicScreenshots, + icon: Icon( + Icons.screenshot, + ), + ) + ], + ), + ), + ), + ), + ), + if (deviceScreenshotsAvailable > 0) + Center( + child: Container( + constraints: const BoxConstraints( + maxWidth: 400, + ), + child: Card( + clipBehavior: Clip.hardEdge, + child: Container( + padding: const EdgeInsets.all(15), + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Center( + child: Text( + '$deviceScreenshotsAvailable device screenshots available', + ), + ), + ), + const IconButton( + onPressed: processDeviceScreenshots, + icon: Icon( + Icons.screenshot, + ), + ) + ], + ), + ), + ), + ), + ), + for (int i = 0; i < SizedContainerDummy().dummies.length; i++) + PreviewBoundary( + widgetKey: GlobalKey(), + dummyBuilder: () => SizedContainerDummy().dummies[i], + builder: (BuildContext context, Dummy dummy) { + return buildSizedContainer(dummy); + }, + ), + ], + ) + ], + ); + } +} + +SizedContainer buildSizedContainer(Dummy dummy) { + return SizedContainer( + width: dummy.parameters['width'], + child: dummy.parameters['child'], + ); +} diff --git a/example/lib/widgets/screen/catalog/test/sized_container_test.dart b/example/lib/widgets/screen/catalog/test/sized_container_test.dart new file mode 100644 index 0000000..640e06d --- /dev/null +++ b/example/lib/widgets/screen/catalog/test/sized_container_test.dart @@ -0,0 +1,69 @@ +/// AUTOGENERATED FILE. +/// +/// Use this file to test the widget SizedContainer +/// + +import 'package:catalog/catalog.dart'; +import 'package:flutter/widgets.dart'; + +import '../dummy/sized_container.dummy.dart'; +import '../preview/sized_container.preview.dart'; + +class SizedContainerTest { + void main() { + group( + 'SizedContainer - Tests', + () { + testWidgets( + 'Child does not exceed the width', + (tester) async { + // prepare the context + await tester.setupTestContext(); + + for (var dummy in SizedContainerDummy().dummies) { + // prepare the widget + final widget = buildSizedContainer(dummy); + await tester.test(widget); + + // get the size of the widget + final widgetSize = tester.getSize(find.byWidget(widget)); + + // check the maximum width + expect( + widgetSize.width, + dummy.parameters['width'], + ); + } + }, + ); + + testWidgets( + 'Child does exceed the width', + (tester) async { + // prepare the context + await tester.setupTestContext(); + + for (var dummy in SizedContainerDummy().dummies) { + // prepare the widget + final widget = Container( + child: dummy.parameters['child'], + ); + await tester.test(widget); + + // get the size of the widget + final widgetSize = tester.getSize(find.byWidget(widget)); + + // check the maximum width + expect( + widgetSize.width, + greaterThanOrEqualTo( + dummy.parameters['width'], + ), + ); + } + }, + ); + }, + ); + } +} diff --git a/example/lib/widgets/screen/sized_container.dart b/example/lib/widgets/screen/sized_container.dart new file mode 100644 index 0000000..ed51fcd --- /dev/null +++ b/example/lib/widgets/screen/sized_container.dart @@ -0,0 +1,25 @@ +import 'package:catalog/catalog.dart'; +import 'package:flutter/material.dart'; + +@Preview( + description: 'Container with a max width', + parameters: ['width', 'child'], +) +class SizedContainer extends StatelessWidget { + final double width; + final Widget child; + + const SizedContainer({ + super.key, + this.width = 500, + required this.child, + }); + + @override + Widget build(BuildContext context) => Container( + constraints: BoxConstraints( + maxWidth: width, + ), + child: child, + ); +} diff --git a/example/test/catalog_widget_test.dart b/example/test/catalog_widget_test.dart index 136f09b..ff814c2 100644 --- a/example/test/catalog_widget_test.dart +++ b/example/test/catalog_widget_test.dart @@ -1,19 +1,22 @@ /// AUTOGENERATED FILE. DO NOT EDIT import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' - as dmsz; + as mxea; import 'package:example/widgets/other_utils/bottom/catalog/test/warning_info_widget_test.dart' - as zjri; + as estp; +import 'package:example/widgets/screen/catalog/test/sized_container_test.dart' + as baxr; import 'package:example/widgets/screen/catalog/test/body_widget_test.dart' - as cpsh; + as nlha; import 'package:example/widgets/screen/catalog/test/counter_widget_test.dart' - as atcw; -import 'package:example/widgets/catalog/test/main_screen_test.dart' as lsrx; + as djlm; +import 'package:example/widgets/catalog/test/main_screen_test.dart' as aobt; void main() { - dmsz.FabWidgetTest().main(); - zjri.WarningInfoWidgetTest().main(); - cpsh.BodyWidgetTest().main(); - atcw.CounterWidgetTest().main(); - lsrx.MainScreenTest().main(); + mxea.FabWidgetTest().main(); + estp.WarningInfoWidgetTest().main(); + baxr.SizedContainerTest().main(); + nlha.BodyWidgetTest().main(); + djlm.CounterWidgetTest().main(); + aobt.MainScreenTest().main(); } diff --git a/lib/src/bin/builders/dummy_builder.dart b/lib/src/bin/builders/dummy_builder.dart index ea5c5ee..0ecd87d 100644 --- a/lib/src/bin/builders/dummy_builder.dart +++ b/lib/src/bin/builders/dummy_builder.dart @@ -27,7 +27,11 @@ Future generateDummy( var content = ''' /// AUTOGENERATED FILE. /// -/// Use this file for modify the preview of ${clazz}Preview +/// Use this file to prepare the preview and the tests: +/// +/// - ${clazz}Preview +/// - ${clazz}Test +/// - ${clazz}IntegrationTest /// import 'package:catalog/catalog.dart'; diff --git a/lib/src/bin/builders/test_builder.dart b/lib/src/bin/builders/test_builder.dart index d3e991d..fb41dd5 100644 --- a/lib/src/bin/builders/test_builder.dart +++ b/lib/src/bin/builders/test_builder.dart @@ -60,7 +60,7 @@ class ${clazz}Test { 'Lorem text not found', (tester) async { // prepare the context - await setupTestContext(); + await tester.setupTestContext(); // prepare the widget final dummy = ${clazz}Dummy().dummies.first; @@ -76,7 +76,7 @@ class ${clazz}Test { 'Other lorem text not found', (tester) async { // prepare the context - await setupTestContext(); + await tester.setupTestContext(); // prepare the widget final dummy = ${clazz}Dummy().dummies.first; @@ -160,7 +160,7 @@ class ${clazz}IntegrationTest { 'Lorem text not found', (tester) async { // prepare the context - await setupIntegrationTestContext(); + await tester.setupIntegrationTestContext(); // prepare the widget final dummy = ${clazz}Dummy().dummies.first; @@ -176,7 +176,7 @@ class ${clazz}IntegrationTest { 'Other lorem text not found', (tester) async { // prepare the context - await setupIntegrationTestContext(); + await tester.setupIntegrationTestContext(); // prepare the widget final dummy = ${clazz}Dummy().dummies.first; diff --git a/lib/src/bin/tasks/preview_task.dart b/lib/src/bin/tasks/preview_task.dart index 4aacfc6..519e8f7 100644 --- a/lib/src/bin/tasks/preview_task.dart +++ b/lib/src/bin/tasks/preview_task.dart @@ -1,14 +1,10 @@ import 'base/base_task.dart'; import 'tasks/format_task.dart'; -import 'tasks/integration_test_task.dart'; import 'tasks/preview_task.dart' as preview; -import 'tasks/test_task.dart'; class PreviewTask extends BaseTask { final tasks = [ preview.PreviewTask(), - TestTask(), - IntegrationTestTask(), FormatTask(), ]; diff --git a/lib/src/builders/dummy/preview_dummy.dart b/lib/src/builders/dummy/preview_dummy.dart index fc1efaa..af44cc0 100644 --- a/lib/src/builders/dummy/preview_dummy.dart +++ b/lib/src/builders/dummy/preview_dummy.dart @@ -14,4 +14,10 @@ abstract class PreviewDummy { } return index; } + + Dummy get(int index) { + if (dummies.isEmpty) throw Exception('Empty dummies list'); + if (index >= dummies.length) return dummies.first; + return dummies[index]; + } } diff --git a/lib/src/extensions/widget_test_ext.dart b/lib/src/extensions/widget_test_ext.dart index f968fcd..2168aca 100644 --- a/lib/src/extensions/widget_test_ext.dart +++ b/lib/src/extensions/widget_test_ext.dart @@ -10,7 +10,7 @@ extension WidgetTestExt on WidgetTester { navigatorKey: Stringcare().navigatorKey, supportedLocales: Stringcare().locales, localizationsDelegates: Stringcare().delegates, - home: widget, + home: Center(child: widget), ), ); await pumpAndSettle(); From aa90e2c24d332e48b5c8c2c16e91faf0a1808262 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sun, 6 Oct 2024 20:41:03 +0200 Subject: [PATCH 25/28] feature: removing process.dart --- example/assets/preview_config.json | 15 ++++++++++++ .../catalog_widget_integration_test.dart | 24 +++++++++---------- example/lib/catalog/catalog_component.dart | 8 +++++++ .../widgets/screen/sized_container.dart | 22 +++++++++++++++++ example/test/catalog_widget_test.dart | 24 +++++++++---------- lib/src/bin/tasks/tasks/catalog_task.dart | 4 ---- lib/src/bin/tasks/tasks/format_task.dart | 10 ++++++++ 7 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 example/lib/catalog/widgets/screen/sized_container.dart diff --git a/example/assets/preview_config.json b/example/assets/preview_config.json index 80addd8..d710b33 100644 --- a/example/assets/preview_config.json +++ b/example/assets/preview_config.json @@ -101,6 +101,21 @@ ] } }, + "./lib/catalog/widgets/screen/sized_container.dart": { + "path": "./lib/catalog/widgets/screen/sized_container.dart", + "route": "widgets/screen", + "package": "package:example/catalog/widgets/screen/sized_container.dart", + "clazzName": "SizedContainerPreviewPreviewPageDummy", + "preview": { + "id": "sized_container", + "path": "widgets/screen", + "description": "Container with a max width", + "parameters": [ + "width", + "child" + ] + } + }, "./lib/catalog/widgets/screen/counter_widget.dart": { "path": "./lib/catalog/widgets/screen/counter_widget.dart", "route": "widgets/screen", diff --git a/example/integration_test/catalog_widget_integration_test.dart b/example/integration_test/catalog_widget_integration_test.dart index c627714..7134d4a 100644 --- a/example/integration_test/catalog_widget_integration_test.dart +++ b/example/integration_test/catalog_widget_integration_test.dart @@ -9,25 +9,25 @@ import 'package:integration_test/integration_test.dart'; import 'package:example/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart' - as nsyv; + as krix; import 'package:example/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart' - as fhuz; + as lqzu; import 'package:example/widgets/screen/catalog/integration_test/sized_container_integration_test.dart' - as qaip; + as olvc; import 'package:example/widgets/screen/catalog/integration_test/body_widget_integration_test.dart' - as afnp; + as rxco; import 'package:example/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart' - as mvnf; + as zesi; import 'package:example/widgets/catalog/integration_test/main_screen_integration_test.dart' - as gnzn; + as nlyv; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - nsyv.FabWidgetIntegrationTest().main(); - fhuz.WarningInfoWidgetIntegrationTest().main(); - qaip.SizedContainerIntegrationTest().main(); - afnp.BodyWidgetIntegrationTest().main(); - mvnf.CounterWidgetIntegrationTest().main(); - gnzn.MainScreenIntegrationTest().main(); + krix.FabWidgetIntegrationTest().main(); + lqzu.WarningInfoWidgetIntegrationTest().main(); + olvc.SizedContainerIntegrationTest().main(); + rxco.BodyWidgetIntegrationTest().main(); + zesi.CounterWidgetIntegrationTest().main(); + nlyv.MainScreenIntegrationTest().main(); } diff --git a/example/lib/catalog/catalog_component.dart b/example/lib/catalog/catalog_component.dart index 25f7235..cee5377 100644 --- a/example/lib/catalog/catalog_component.dart +++ b/example/lib/catalog/catalog_component.dart @@ -8,6 +8,7 @@ import 'package:example/catalog/widgets/utils/bottom/fab_widget.dart'; import 'package:example/catalog/widgets/other_utils/bottom/warning_info_widget.dart'; import 'package:example/catalog/widgets/screen/body_widget.dart'; +import 'package:example/catalog/widgets/screen/sized_container.dart'; import 'package:example/catalog/widgets/screen/counter_widget.dart'; import 'package:example/catalog/widgets/main_screen.dart'; @@ -100,6 +101,13 @@ class CatalogComponent extends StatefulWidget { child: const BodyWidgetPreviewPreviewPageDummy(), ), ), + GoRoute( + path: SizedContainerPreviewPreviewPageDummy.routeName, + pageBuilder: (context, state) => NoTransitionPage( + key: state.pageKey, + child: const SizedContainerPreviewPreviewPageDummy(), + ), + ), GoRoute( path: CounterWidgetPreviewPreviewPageDummy.routeName, pageBuilder: (context, state) => NoTransitionPage( diff --git a/example/lib/catalog/widgets/screen/sized_container.dart b/example/lib/catalog/widgets/screen/sized_container.dart new file mode 100644 index 0000000..6a8daf8 --- /dev/null +++ b/example/lib/catalog/widgets/screen/sized_container.dart @@ -0,0 +1,22 @@ +/// AUTOGENERATED FILE. DO NOT EDIT + +import 'package:flutter/material.dart'; +import 'package:example/widgets/screen/catalog/preview/sized_container.preview.dart'; + +class SizedContainerPreviewPreviewPageDummy extends StatefulWidget { + static String routeName = 'sized_container'; + + const SizedContainerPreviewPreviewPageDummy({super.key}); + + @override + SizedContainerPreviewPreviewPageDummyState createState() => + SizedContainerPreviewPreviewPageDummyState(); +} + +class SizedContainerPreviewPreviewPageDummyState + extends State { + @override + Widget build(BuildContext context) { + return const SizedContainerPreview(); + } +} diff --git a/example/test/catalog_widget_test.dart b/example/test/catalog_widget_test.dart index ff814c2..ae810da 100644 --- a/example/test/catalog_widget_test.dart +++ b/example/test/catalog_widget_test.dart @@ -1,22 +1,22 @@ /// AUTOGENERATED FILE. DO NOT EDIT import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' - as mxea; + as rfnk; import 'package:example/widgets/other_utils/bottom/catalog/test/warning_info_widget_test.dart' - as estp; + as sshj; import 'package:example/widgets/screen/catalog/test/sized_container_test.dart' - as baxr; + as tzgw; import 'package:example/widgets/screen/catalog/test/body_widget_test.dart' - as nlha; + as bbmy; import 'package:example/widgets/screen/catalog/test/counter_widget_test.dart' - as djlm; -import 'package:example/widgets/catalog/test/main_screen_test.dart' as aobt; + as metb; +import 'package:example/widgets/catalog/test/main_screen_test.dart' as lvau; void main() { - mxea.FabWidgetTest().main(); - estp.WarningInfoWidgetTest().main(); - baxr.SizedContainerTest().main(); - nlha.BodyWidgetTest().main(); - djlm.CounterWidgetTest().main(); - aobt.MainScreenTest().main(); + rfnk.FabWidgetTest().main(); + sshj.WarningInfoWidgetTest().main(); + tzgw.SizedContainerTest().main(); + bbmy.BodyWidgetTest().main(); + metb.CounterWidgetTest().main(); + lvau.MainScreenTest().main(); } diff --git a/lib/src/bin/tasks/tasks/catalog_task.dart b/lib/src/bin/tasks/tasks/catalog_task.dart index 290ea0f..1a0bebd 100644 --- a/lib/src/bin/tasks/tasks/catalog_task.dart +++ b/lib/src/bin/tasks/tasks/catalog_task.dart @@ -155,10 +155,6 @@ class ${pageName}State extends State<$pageName> { catalogFile.writeAsStringSync(catalogContent); - final File file = - File('./$base${config['base']}/${config['output']}/process.dart'); - if (file.existsSync()) await file.delete(); - await generateCatalogReadme(base, config); } } diff --git a/lib/src/bin/tasks/tasks/format_task.dart b/lib/src/bin/tasks/tasks/format_task.dart index 906a008..59579a9 100644 --- a/lib/src/bin/tasks/tasks/format_task.dart +++ b/lib/src/bin/tasks/tasks/format_task.dart @@ -1,10 +1,20 @@ import 'dart:io'; +import 'package:catalog/src/bin/utils/configuration.dart'; + import '../base/base_task.dart'; class FormatTask extends BaseTask { @override Future work(List args) async { + final base = args.isEmpty ? '' : '${args.first}/'; + + var config = loadConfigFile(base); + + final File file = + File('./$base${config['base']}/${config['output']}/process.dart'); + if (file.existsSync()) await file.delete(); + var resultFix = await Process.run( 'dart', ['fix', '--apply'], From d5e03ccd5d00d4ced45a7e06c188af9116113ec4 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sun, 6 Oct 2024 20:42:25 +0200 Subject: [PATCH 26/28] feature: updated version and dependencies --- pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 47a0fc9..b85049c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: catalog description: A Flutter package to render widgets in real time and generate screenshots for fastlane. -version: 1.0.6 +version: 2.0.0 homepage: https://landamessenger.com/ repository: https://github.com/landamessenger/catalog @@ -15,7 +15,7 @@ dependencies: device_frame: ^1.2.0 # android ios linux macos web windows flutter_svg: ^2.0.10+1 # android ios linux macos windows global_refresh: ^1.0.0 # android ios linux macos web windows - go_router: ^14.2.8 # android ios linux macos web windows + go_router: ^14.3.0 # android ios linux macos web windows http: ^1.2.2 # android ios linux macos web windows image: ^4.2.0 # android ios linux macos web windows shelf: ^1.4.1 # android ios linux macos web windows From 57dc95eafbe8abb4e1013149371a196f1ef8e0f5 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sun, 6 Oct 2024 20:45:14 +0200 Subject: [PATCH 27/28] feature: added publish workflow --- .github/workflows/tag_version_and_publish.yml | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 .github/workflows/tag_version_and_publish.yml diff --git a/.github/workflows/tag_version_and_publish.yml b/.github/workflows/tag_version_and_publish.yml new file mode 100644 index 0000000..92192dd --- /dev/null +++ b/.github/workflows/tag_version_and_publish.yml @@ -0,0 +1,116 @@ +name: Tag Version and Publish on Push to Master + +on: + push: + branches: + - master + +jobs: + tag_version_and_publish: + + runs-on: self-hosted + + steps: + - uses: actions/checkout@v4 + + - name: Read version from pubspec.yml + id: read_version + run: | + VERSION=$(grep '^version: ' pubspec.yaml | cut -d ' ' -f 2) + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - name: Create tag + id: create_tag + run: | + # Checks if the tag already exists in the remote repository + if git rev-parse "v${{ env.VERSION }}" >/dev/null 2>&1; then + echo "Error: Tag v${{ env.VERSION }} already exists." + exit 1 + fi + + # Check if the version was found + if [ -z "${{ env.VERSION }}" ]; then + echo "Error: No version found in pubspec.yml" + exit 1 + fi + + git tag "v${{ env.VERSION }}" + git push origin "v${{ env.VERSION }}" + + - name: Handle job completion + if: always() + run: | + if [ "${{ job.status }}" == "failure" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🔴 Creation Tag Failed" \ + --body "${{ github.repository }}: Tag v${{ env.VERSION }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/tag_version_and_publish.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + elif [ "${{ job.status }}" == "cancelled" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟠 Creation Tag Canceled" \ + --body "${{ github.repository }}: Tag v${{ env.VERSION }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/tag_version_and_publish.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + else + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟢 Creation Tag Passed" \ + --body "${{ github.repository }}: Tag v${{ env.VERSION }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/tag_version_and_publish.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + fi + + - run: flutter pub get + + - run: dart pub publish --dry-run + + - run: dart pub publish -f + + - name: Handle publish job completion + if: always() + run: | + if [ "${{ job.status }}" == "failure" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🔴 Pub Publish Failed" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/tag_version_and_publish.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + elif [ "${{ job.status }}" == "cancelled" ]; then + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟠 Pub Publish Canceled" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/tag_version_and_publish.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + else + landa-messenger-api chat-send \ + --id "${{ secrets.CHAT_ID }}" \ + --api_key "${{ secrets.CHAT_KEY }}" \ + --title "🟢 Pub Publish Passed" \ + --body "${{ github.repository }}: ${{ github.event.head_commit.message }}" \ + --url "https://github.com/landamessenger/catalog/actions/workflows/tag_version_and_publish.yml" \ + --image "https://avatars.githubusercontent.com/u/63705403?s=200&v=4" \ + --background_color "#55000000" \ + --text_color "#FFFFFFFF" + fi + + From 873e7afddb70a3fba22250d6328cdec74cd66810 Mon Sep 17 00:00:00 2001 From: Efra Espada Date: Sun, 6 Oct 2024 20:54:08 +0200 Subject: [PATCH 28/28] feature: added tests --- .../catalog_widget_integration_test.dart | 24 +++++++++--------- example/lib/catalog/README.md | 2 +- example/test/catalog_widget_test.dart | 24 +++++++++--------- lib/src/bin/builders/catalog_builder.dart | 2 +- lib/src/bin/tasks/main_task.dart | 6 ++++- lib/src/bin/utils/messages.dart | 2 +- test/catalog_test.dart | 25 +++++++++++++++++-- 7 files changed, 55 insertions(+), 30 deletions(-) diff --git a/example/integration_test/catalog_widget_integration_test.dart b/example/integration_test/catalog_widget_integration_test.dart index 7134d4a..c34e55d 100644 --- a/example/integration_test/catalog_widget_integration_test.dart +++ b/example/integration_test/catalog_widget_integration_test.dart @@ -9,25 +9,25 @@ import 'package:integration_test/integration_test.dart'; import 'package:example/widgets/utils/bottom/catalog/integration_test/fab_widget_integration_test.dart' - as krix; + as akcl; import 'package:example/widgets/other_utils/bottom/catalog/integration_test/warning_info_widget_integration_test.dart' - as lqzu; + as gjrq; import 'package:example/widgets/screen/catalog/integration_test/sized_container_integration_test.dart' - as olvc; + as pvar; import 'package:example/widgets/screen/catalog/integration_test/body_widget_integration_test.dart' - as rxco; + as utcx; import 'package:example/widgets/screen/catalog/integration_test/counter_widget_integration_test.dart' - as zesi; + as ujyk; import 'package:example/widgets/catalog/integration_test/main_screen_integration_test.dart' - as nlyv; + as sqbo; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - krix.FabWidgetIntegrationTest().main(); - lqzu.WarningInfoWidgetIntegrationTest().main(); - olvc.SizedContainerIntegrationTest().main(); - rxco.BodyWidgetIntegrationTest().main(); - zesi.CounterWidgetIntegrationTest().main(); - nlyv.MainScreenIntegrationTest().main(); + akcl.FabWidgetIntegrationTest().main(); + gjrq.WarningInfoWidgetIntegrationTest().main(); + pvar.SizedContainerIntegrationTest().main(); + utcx.BodyWidgetIntegrationTest().main(); + ujyk.CounterWidgetIntegrationTest().main(); + sqbo.MainScreenIntegrationTest().main(); } diff --git a/example/lib/catalog/README.md b/example/lib/catalog/README.md index a6fab50..08a8dcc 100644 --- a/example/lib/catalog/README.md +++ b/example/lib/catalog/README.md @@ -4,7 +4,7 @@ This is your catalog in example. It shows the widgets that contain `@Preview` in You should not manipulate it yourself. If you observe any unexpected behavior please [open an issue on Github](https://github.com/landamessenger/catalog/issues). We will try to fix it as soon as possible. -Generate dummies, previews (override every time) and tests with: +Generate dummies, previews (override every time) with: ```bash dart run catalog:preview diff --git a/example/test/catalog_widget_test.dart b/example/test/catalog_widget_test.dart index ae810da..8c11d3d 100644 --- a/example/test/catalog_widget_test.dart +++ b/example/test/catalog_widget_test.dart @@ -1,22 +1,22 @@ /// AUTOGENERATED FILE. DO NOT EDIT import 'package:example/widgets/utils/bottom/catalog/test/fab_widget_test.dart' - as rfnk; + as aleo; import 'package:example/widgets/other_utils/bottom/catalog/test/warning_info_widget_test.dart' - as sshj; + as dgjg; import 'package:example/widgets/screen/catalog/test/sized_container_test.dart' - as tzgw; + as ntbg; import 'package:example/widgets/screen/catalog/test/body_widget_test.dart' - as bbmy; + as wwjj; import 'package:example/widgets/screen/catalog/test/counter_widget_test.dart' - as metb; -import 'package:example/widgets/catalog/test/main_screen_test.dart' as lvau; + as dqlj; +import 'package:example/widgets/catalog/test/main_screen_test.dart' as gpwz; void main() { - rfnk.FabWidgetTest().main(); - sshj.WarningInfoWidgetTest().main(); - tzgw.SizedContainerTest().main(); - bbmy.BodyWidgetTest().main(); - metb.CounterWidgetTest().main(); - lvau.MainScreenTest().main(); + aleo.FabWidgetTest().main(); + dgjg.WarningInfoWidgetTest().main(); + ntbg.SizedContainerTest().main(); + wwjj.BodyWidgetTest().main(); + dqlj.CounterWidgetTest().main(); + gpwz.MainScreenTest().main(); } diff --git a/lib/src/bin/builders/catalog_builder.dart b/lib/src/bin/builders/catalog_builder.dart index f00c62a..0d48fc4 100644 --- a/lib/src/bin/builders/catalog_builder.dart +++ b/lib/src/bin/builders/catalog_builder.dart @@ -137,7 +137,7 @@ This is your catalog in example. It shows the widgets that contain `@Preview` in You should not manipulate it yourself. If you observe any unexpected behavior please [open an issue on Github](https://github.com/landamessenger/catalog/issues). We will try to fix it as soon as possible. -Generate dummies, previews (override every time) and tests with: +Generate dummies, previews (override every time) with: ```bash dart run catalog:preview diff --git a/lib/src/bin/tasks/main_task.dart b/lib/src/bin/tasks/main_task.dart index 47fd09e..e27c8ba 100644 --- a/lib/src/bin/tasks/main_task.dart +++ b/lib/src/bin/tasks/main_task.dart @@ -26,6 +26,10 @@ class MainTask extends BaseTask { print(e); } } - print(commonMessage('Previews, tests, integration tests and catalog generated')); + print( + commonMessage( + 'Previews, tests, integration tests and catalog generated', + ), + ); } } diff --git a/lib/src/bin/utils/messages.dart b/lib/src/bin/utils/messages.dart index 7bb2a43..894ad1d 100644 --- a/lib/src/bin/utils/messages.dart +++ b/lib/src/bin/utils/messages.dart @@ -1,6 +1,6 @@ String commonMessage(String message) => ''' -✅ $message. +✅ $message. 🐛 Report any issue on https://github.com/landamessenger/catalog/issues diff --git a/test/catalog_test.dart b/test/catalog_test.dart index d01d176..174acf3 100644 --- a/test/catalog_test.dart +++ b/test/catalog_test.dart @@ -1,4 +1,7 @@ +import 'package:catalog/src/bin/tasks/integration_test_task.dart'; import 'package:catalog/src/bin/tasks/main_task.dart'; +import 'package:catalog/src/bin/tasks/preview_task.dart'; +import 'package:catalog/src/bin/tasks/test_task.dart'; import 'package:catalog/src/bin/utils/configuration.dart'; import 'package:catalog/src/catalog_runner.dart'; import 'package:flutter/material.dart'; @@ -26,12 +29,30 @@ void main() { () async { var dependencies = loadDependenciesFile('$exampleFolder/'); print(introMessage(dependencies[dependency].toString())); - await MainTask().work([exampleFolder]); + await PreviewTask().work([exampleFolder]); + }, + ); + + test( + 'Test Test task (test + format)', + () async { + var dependencies = loadDependenciesFile('$exampleFolder/'); + print(introMessage(dependencies[dependency].toString())); + await TestTask().work([exampleFolder]); + }, + ); + + test( + 'Test Integration Test task (integration_test + format)', + () async { + var dependencies = loadDependenciesFile('$exampleFolder/'); + print(introMessage(dependencies[dependency].toString())); + await IntegrationTestTask().work([exampleFolder]); }, ); test( - 'Test Main task (preview + catalog + format)', + 'Test Main task (preview + test + integration_test + catalog + format)', () async { var dependencies = loadDependenciesFile('$exampleFolder/'); print(introMessage(dependencies[dependency].toString()));