diff --git a/ohos/lz_petitparser_test_os/.gitignore b/ohos/lz_petitparser_test_os/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/lz_petitparser_test_os/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/lz_petitparser_test_os/.metadata b/ohos/lz_petitparser_test_os/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..e0f0961aa036e30d738e49ac6752e3f869f9d9d1 --- /dev/null +++ b/ohos/lz_petitparser_test_os/.metadata @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: android + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/lz_petitparser_test_os/README.md b/ohos/lz_petitparser_test_os/README.md new file mode 100644 index 0000000000000000000000000000000000000000..88d248f5f107133d3cbdd0aa3bd9b7c1de088def --- /dev/null +++ b/ohos/lz_petitparser_test_os/README.md @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + + +# lz_petitparser_test_os + +The Ohos implementation of petitparser. + +## Getting Started + +This package is endorsed, which means you can simply use path_parsing normally. This package will be automatically included in your app when you do, so you do not need to add it to your pubspec.yaml. + +However, if you import this package to use any of its APIs directly, you should add it to your pubspec.yaml as usual. + diff --git a/ohos/lz_petitparser_test_os/analysis_options.yaml b/ohos/lz_petitparser_test_os/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5244b43ffc1c779eee636467f39a142a81cd9cb8 --- /dev/null +++ b/ohos/lz_petitparser_test_os/analysis_options.yaml @@ -0,0 +1,45 @@ + /* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + # This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/lz_petitparser_test_os/lib/common/base_page.dart b/ohos/lz_petitparser_test_os/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..8b9755c020fe74512f14d58c9185e70278f212a8 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/common/base_page.dart @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import '../common/test_route.dart'; + +import '../main.dart'; +import 'main_item_widget.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({super.key, required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center(child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.of(context).pushNamed(item.route!); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/common/item_widget.dart b/ohos/lz_petitparser_test_os/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..695f7932876e45ed2412ec4efa757d7123ac8976 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/common/item_widget.dart @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, + required this.index, + required this.getGroupRange, + required this.runGroup, + required this.onTap, + this.summary, + Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index + ? Border(bottom: BorderSide(color: Colors.grey)) + : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index + ? EdgeInsets.only(left: 35) + : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/common/main_item_widget.dart b/ohos/lz_petitparser_test_os/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..4c85d8b98ca4d5f7ba141b196a1ec2647021dbdb --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/common/main_item_widget.dart @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import '../common/test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + subtitle: Text(widget.item.description), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/common/test_model_app.dart b/ohos/lz_petitparser_test_os/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..99876a75a2654a5e287e899bcae8dc594cf1a419 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/common/test_model_app.dart @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final TestRoute data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + routes: widget.data.routes, + initialRoute: '/', + ); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/common/test_page.dart b/ohos/lz_petitparser_test_os/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..14165ed541e1f973b00869e20f32afe8aa5434e6 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/common/test_page.dart @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage(this.title, {Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text(widget.title), actions: [ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ]), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + }); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + // for (int i = 0; i < contentList.length; i++) { + // print(contentList[i].data); + // } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/lz_petitparser_test_os/lib/common/test_route.dart b/ohos/lz_petitparser_test_os/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..d1a0da42babdbbe064ee24ed8e5a62e4be394213 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/common/test_route.dart @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.description, {this.route}); + + /// Title. + String title; + + /// Description. + String description; + + /// Page route. + String? route; +} + +class TestRoute { + TestRoute({required Map routes, required this.items}) { + if (routes.containsKey('/')) { + throw Exception('不允许传入 / 路由'); + } + + this.routes.addAll({ + '/': (BuildContext context) => BasePage(data: items), + }); + this.routes.addAll(routes); + } + + Map routes = {}; + + List items = []; +} diff --git a/ohos/lz_petitparser_test_os/lib/main.dart b/ohos/lz_petitparser_test_os/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..3e1ff77de0080322d4f74c61819ff39e58192b1f --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/main.dart @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; + +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; +import 'pages/context_test.dart'; +import 'pages/debug_test.dart'; +import 'pages/definition_test.dart'; +import 'pages/example_test.dart'; +import 'pages/expression_test.dart'; +import 'pages/function_list.dart'; +import 'pages/generated/sequence_test.dart'; +import 'pages/indent_test.dart'; +import 'pages/matcher_test.dart'; +import 'pages/parser_test.dart'; +import 'pages/reflection_test.dart'; +import 'pages/regression_test.dart'; +import 'pages/s_AndParser_test.dart'; +import 'pages/s_AnyCharacterParser_test.dart'; +import 'pages/s_CastListParser_test.dart'; +import 'pages/s_CastParser_testr.dart'; +import 'pages/s_CharacterPredicate_test.dart'; +import 'pages/s_ChoiceParser_test.dart'; +import 'pages/s_ContinuationParser_test.dart'; +import 'pages/s_DelegateParser_test.dart'; +import 'pages/s_DigitCharPredicate_test.dart'; +import 'pages/s_EndOfInputParser_test.dart'; +import 'pages/s_EpsilonParser_test.dart'; +import 'pages/s_FailureParser_test.dart'; +import 'pages/s_FlattenParser_test.dart'; +import 'pages/s_GreedyRepeatingParser_test.dart'; +import 'pages/s_LabelParser_test.dart'; +import 'pages/s_LabeledParser_test.dart'; +import 'pages/s_LazyRepeatingParser_test.dart'; +import 'pages/s_LetterCharPredicate_test.dart'; +import 'pages/s_LimitedRepeatingParser_test.dart'; +import 'pages/s_ListParser_test.dart'; +import 'pages/s_LowercaseCharPredicate_test.dart'; +import 'pages/s_MapParser_test.dart'; +import 'pages/s_NewlineParser_test.dart'; +import 'pages/s_NotParser_test.dart'; +import 'pages/s_OptionalParser_test.dart'; +import 'pages/s_Parser_test.dart'; +import 'pages/s_PatternParser_test.dart'; +import 'pages/s_PermuteParser_test.dart'; +import 'pages/s_PickParser_test.dart'; +import 'pages/s_PositionParser_test.dart'; +import 'pages/s_PossessiveRepeatingParser_test.dart'; +import 'pages/s_PredicateParser_test.dart'; +import 'pages/s_RangeCharPredicate_test.dart'; +import 'pages/s_RepeatingCharacterParser_test.dart'; +import 'pages/s_RepeatingParser_test.dart'; +import 'pages/s_ResolvableParser_test.dart'; +import 'pages/s_SeparatedList_test.dart'; +import 'pages/s_SeparatedRepeatingParser_test.dart'; +import 'pages/s_SequenceParser2_test.dart'; +import 'pages/s_SequenceParser3_test.dart'; +import 'pages/s_SequenceParser4_test.dart'; +import 'pages/s_SequenceParser5_test.dart'; +import 'pages/s_SequenceParser6_test.dart'; +import 'pages/s_SequenceParser7_test.dart'; +import 'pages/s_SequenceParser8_test.dart'; +import 'pages/s_SequenceParser9_test.dart'; +import 'pages/s_SequenceParser_test.dart'; +import 'pages/s_SettableParser_test.dart'; +import 'pages/s_SingleCharPredicate_test.dart'; +import 'pages/s_SingleCharacterParser_test.dart'; +import 'pages/s_SkipParser_test.dart'; +import 'pages/s_TokenParser_test.dart'; +import 'pages/s_TrimmingParser_test.dart'; +import 'pages/s_UppercaseCharPredicate_test.dart'; +import 'pages/s_WhereParser_test.dart'; +import 'pages/s_WhitespaceCharPredicate_test.dart'; +import 'pages/s_WordCharPredicate_test.dart'; +import 'pages/tutorial_test.dart'; + +void main() { + final items = [ + //FunctionList + MainItem('functions', "", route: "FunctionList"), + MainItem('s_AndParser_test', "", route: "SAndParserTestPage"), + MainItem('s_AnyCharacterParser_test', "", route: "SAnyCharacterParserTestPage"), + MainItem('s_CastListParser_test', "", route: "SCastListParserTestPage"), + MainItem('s_CastParser_test', "", route: "SCastParserTestPage"), + MainItem('s_CharacterPredicate_test', "", route: "SCharacterPredicateTestPage"), + MainItem('s_ChoiceParser_test', "", route: "SChoiceParserTestPage"), + MainItem('s_ContinuationParser_test', "", route: "SContinuationParserTestPage"), + MainItem('s_DelegateParser_test', "", route: "SDelegateParserTestPage"), + MainItem('s_DigitCharPredicate_test', "", route: "SDigitCharPredicateTestPage"), + MainItem('s_EndOfInputParser_test', "", route: "SEndOfInputParserTestPage"), + MainItem('s_EpsilonParser_test', "", route: "SEpsilonParserTestPage"), + MainItem('s_FailureParser_test', "", route: "SFailureParserTestPage"), + MainItem('s_FlattenParser_test', "", route: "SFlattenParserTestPage"), + MainItem('s_GreedyRepeatingParser_test', "", route: "SGreedyRepeatingParserTestPage"), + MainItem('s_LabeledParser_test', "", route: "SLabeledParserTestPage"), + MainItem('s_LabelParser_test', "", route: "SLabelParserTestPage"), + MainItem('s_LazyRepeatingParser_test', "", route: "SLazyRepeatingParserTestPage"), + MainItem('s_LetterCharPredicate_test', "", route: "SLetterCharPredicateTestPage"), + MainItem('s_LimitedRepeatingParser_test', "", route: "SLimitedRepeatingParserTestPage"), + MainItem('s_ListParser_test', "", route: "SListParserTestPage"), + MainItem('s_LowercaseCharPredicate_test', "", route: "SLowercaseCharPredicateTestPage"), + MainItem('s_MapParser_test', "", route: "SMapParserTestPage"), + MainItem('s_NewlineParser_test', "", route: "SNewlineParserTestPage"), + MainItem('s_NotParser_test', "", route: "SNotParserTestPage"), + MainItem('s_OptionalParser_test', "", route: "SOptionalParserTestPage"), + MainItem('s_Parser_test', "", route: "SParserTestPage"), + MainItem('s_PatternParser_test', "", route: "SPatternParserTestPage"), + MainItem('s_PermuteParser_test', "", route: "SPermuteParserTestPage"), + MainItem('s_PickParser_test', "", route: "SPickParserTestPage"), + MainItem('s_PositionParser_test', "", route: "SPositionParserTestPage"), + MainItem('s_PossessiveRepeatingParser_test', "", route: "SPossessiveRepeatingParserTestPage"), + MainItem('s_PredicateParser_test', "", route: "SPredicateParserTestPage"), + MainItem('s_RangeCharPredicate_test', "", route: "SRangeCharPredicateTestPage"), + MainItem('s_RepeatingCharacterParser_test', "", route: "SRepeatingCharacterParserTestPage"), + MainItem('s_RepeatingParser_test', "", route: "SRepeatingParserTestPage"), + MainItem('s_ResolvableParser_test', "", route: "SResolvableParserTestPage"), + MainItem('s_SeparatedList_test', "", route: "SSeparatedListTestPage"), + MainItem('s_SeparatedRepeatingParser_test', "", route: "SSeparatedRepeatingParserTestPage"), + MainItem('s_SequenceParser_test', "", route: "SSequenceParserTestPage"), + MainItem('s_SequenceParser2_test', "", route: "SSequenceParser2TestPage"), + MainItem('s_SequenceParser3_test', "", route: "SSequenceParser3TestPage"), + MainItem('s_SequenceParser4_test', "", route: "SSequenceParser4TestPage"), + MainItem('s_SequenceParser5_test', "", route: "SSequenceParser5TestPage"), + MainItem('s_SequenceParser6_test', "", route: "SSequenceParser6TestPage"), + MainItem('s_SequenceParser7_test', "", route: "SSequenceParser7TestPage"), + MainItem('s_SequenceParser8_test', "", route: "SSequenceParser8TestPage"), + MainItem('s_SequenceParser9_test', "", route: "SSequenceParser9TestPage"), + MainItem('s_SettableParser_test', "", route: "SSettableParserTestPage"), + MainItem('s_SingleCharacterParser_test', "", route: "SSingleCharacterParserTestPage"), + MainItem('s_SingleCharPredicate_test', "", route: "SSingleCharPredicateTestPage"), + MainItem('s_SkipParser_test', "", route: "SSkipParserTestPage"), + MainItem('s_TokenParser_test', "", route: "STokenParserTestPage"), + MainItem('s_TrimmingParser_test', "", route: "STrimmingParserTestPage"), + MainItem('s_UppercaseCharPredicate_test', "", route: "SUppercaseCharPredicateTestPage"), + MainItem('s_WhereParser_test', "", route: "SWhereParserTestPage"), + MainItem('s_WhitespaceCharPredicate_test', "", route: "SWhitespaceCharPredicateTestPage"), + MainItem('s_WordCharPredicate_test', "", route: "SWordCharPredicateTestPage"), + //SWordCharPredicateTestPage + MainItem('matcher_test', "", route: "MatcherTestPage"), + MainItem('context_test', "", route: "ContextTestPage"), + MainItem('debug_test', "", route: "DebugTestPage"), + MainItem('definition_test', "", route: "DefinitionTestPage"), + MainItem('example_test', "", route: "ExamTestPage"), + MainItem('expression_test', "", route: "ExpressionTestPage"), + MainItem('indent_test', "", route: "IndentTestPage"), //TutorialTestPage + MainItem('reflection_test', "", route: "ReflectionTestPage"), + MainItem('regression_test', "", route: "RegressionTestPage"), + MainItem('tutorial_test', "", route: "TutorialTestPage"), + MainItem('parset_test', "", route: "ParsetTestPage"), + MainItem('sequence_test', "", route: "SequenceTestPage"), + ]; + + runApp(TestModelApp( + appName: 'petitparser', + data: TestRoute( + items: items, + routes: { + "FunctionList": (context) { + return FunctionList(); + }, + "SAndParserTestPage": (context) { + return SAndParserTestPage("SAndParserTestPage"); + }, + "SAnyCharacterParserTestPage": (context) { + return SAnyCharacterParserTestPage("SAnyCharacterParserTestPage"); + }, + "SCastListParserTestPage": (context) { + return SCastListParserTestPage("SCastListParserTestPage"); + }, + "SCastParserTestPage": (context) { + return SCastParserTestPage("SCastParserTestPage"); + }, + "SCharacterPredicateTestPage": (context) { + return SCharacterPredicateTestPage("SCharacterPredicateTestPage"); + }, + "SChoiceParserTestPage": (context) { + return SChoiceParserTestPage("SChoiceParserTestPage"); + }, + "SContinuationParserTestPage": (context) { + return SContinuationParserTestPage("SContinuationParserTestPage"); + }, + "SDelegateParserTestPage": (context) { + return SDelegateParserTestPage("SDelegateParserTestPage"); + }, + "SDigitCharPredicateTestPage": (context) { + return SDigitCharPredicateTestPage("SDigitCharPredicateTestPage"); + }, + "SEndOfInputParserTestPage": (context) { + return SEndOfInputParserTestPage("SEndOfInputParserTestPage"); + }, + "SEpsilonParserTestPage": (context) { + return SEpsilonParserTestPage("SEpsilonParserTestPage"); + }, + "SFailureParserTestPage": (context) { + return SFailureParserTestPage("SFailureParserTestPage"); + }, + "SFlattenParserTestPage": (context) { + return SFlattenParserTestPage("SFlattenParserTestPage"); + }, + "SGreedyRepeatingParserTestPage": (context) { + return SGreedyRepeatingParserTestPage("SGreedyRepeatingParserTestPage"); + }, + "SLabeledParserTestPage": (context) { + return SLabeledParserTestPage("SLabeledParserTestPage"); + }, + "SLabelParserTestPage": (context) { + return SLabelParserTestPage("SLabelParserTestPage"); + }, + "SLazyRepeatingParserTestPage": (context) { + return SLazyRepeatingParserTestPage("SLazyRepeatingParserTestPage"); + }, + "SLetterCharPredicateTestPage": (context) { + return SLetterCharPredicateTestPage("SLetterCharPredicateTestPage"); + }, + "SLimitedRepeatingParserTestPage": (context) { + return SLimitedRepeatingParserTestPage("SLimitedRepeatingParserTestPage"); + }, + "SListParserTestPage": (context) { + return SListParserTestPage("SListParserTestPage"); + }, + "SLowercaseCharPredicateTestPage": (context) { + return SLowercaseCharPredicateTestPage("SLowercaseCharPredicateTestPage"); + }, + "SMapParserTestPage": (context) { + return SMapParserTestPage("SMapParserTestPage"); + }, + "SNewlineParserTestPage": (context) { + return SNewlineParserTestPage("SNewlineParserTestPage"); + }, + "SNotParserTestPage": (context) { + return SNotParserTestPage("SNotParserTestPage"); + }, + "SOptionalParserTestPage": (context) { + return SOptionalParserTestPage("SOptionalParserTestPage"); + }, + "SParserTestPage": (context) { + return SParserTestPage("SParserTestPage"); + }, + "SPatternParserTestPage": (context) { + return SPatternParserTestPage("SPatternParserTestPage"); + }, + "SPermuteParserTestPage": (context) { + return SPermuteParserTestPage("SPermuteParserTestPage"); + }, + "SPickParserTestPage": (context) { + return SPickParserTestPage("SPickParserTestPage"); + }, + "SPositionParserTestPage": (context) { + return SPositionParserTestPage("SPositionParserTestPage"); + }, + "SPossessiveRepeatingParserTestPage": (context) { + return SPossessiveRepeatingParserTestPage("SPossessiveRepeatingParserTestPage"); + }, + "SPossessiveRepeatingParserTestPage": (context) { + return SPossessiveRepeatingParserTestPage("SPossessiveRepeatingParserTestPage"); + }, + "SPredicateParserTestPage": (context) { + return SPredicateParserTestPage("SPredicateParserTestPage"); + }, + "SRangeCharPredicateTestPage": (context) { + return SRangeCharPredicateTestPage("SRangeCharPredicateTestPage"); + }, + "SRepeatingCharacterParserTestPage": (context) { + return SRepeatingCharacterParserTestPage("SRepeatingCharacterParserTestPage"); + }, + "SRepeatingParserTestPage": (context) { + return SRepeatingParserTestPage("SRepeatingParserTestPage"); + }, + + "SResolvableParserTestPage": (context) { + return SResolvableParserTestPage("SResolvableParserTestPage"); + }, + "SSeparatedListTestPage": (context) { + return SSeparatedListTestPage("SSeparatedListTestPage"); + }, + "SSeparatedRepeatingParserTestPage": (context) { + return SSeparatedRepeatingParserTestPage("SSeparatedRepeatingParserTestPage"); + }, + "SSequenceParserTestPage": (context) { + return SSequenceParserTestPage("SSequenceParserTestPage"); + }, + "SSequenceParser2TestPage": (context) { + return SSequenceParser2TestPage("SSequenceParser2TestPage"); + }, + "SSequenceParser3TestPage": (context) { + return SSequenceParser3TestPage("SSequenceParser3TestPage"); + }, + "SSequenceParser4TestPage": (context) { + return SSequenceParser4TestPage("SSequenceParser4TestPage"); + }, + "SSequenceParser5TestPage": (context) { + return SSequenceParser5TestPage("SSequenceParser5TestPage"); + }, + "SSequenceParser6TestPage": (context) { + return SSequenceParser6TestPage("SSequenceParser6TestPage"); + }, + "SSequenceParser7TestPage": (context) { + return SSequenceParser7TestPage("SSequenceParser7TestPage"); + }, + "SSequenceParser8TestPage": (context) { + return SSequenceParser8TestPage("SSequenceParser8TestPage"); + }, + "SSequenceParser9TestPage": (context) { + return SSequenceParser9TestPage("SSequenceParser9TestPage"); + }, + "SSettableParserTestPage": (context) { + return SSettableParserTestPage("SSettableParserTestPage"); + }, + "SSingleCharacterParserTestPage": (context) { + return SSingleCharacterParserTestPage("SSingleCharacterParserTestPage"); + }, + "SSingleCharPredicateTestPage": (context) { + return SSingleCharPredicateTestPage("SSingleCharPredicateTestPage"); + }, + "SSkipParserTestPage": (context) { + return SSkipParserTestPage("SSkipParserTestPage"); + }, + "STokenParserTestPage": (context) { + return STokenParserTestPage("STokenParserTestPage"); + }, + "STrimmingParserTestPage": (context) { + return STrimmingParserTestPage("STrimmingParserTestPage"); + }, + "SUppercaseCharPredicateTestPage": (context) { + return SUppercaseCharPredicateTestPage("SUppercaseCharPredicateTestPage"); + }, + "SWhereParserTestPage": (context) { + return SWhereParserTestPage("SWhereParserTestPage"); + }, + "SWhitespaceCharPredicateTestPage": (context) { + return SWhitespaceCharPredicateTestPage("SWhitespaceCharPredicateTestPage"); + }, + "SWordCharPredicateTestPage": (context) { + return SWordCharPredicateTestPage("SWordCharPredicateTestPage"); + }, + //SWordCharPredicateTestPage + "MatcherTestPage": (context) { + return MatcherTestPage("MatcherTestPage"); + }, + "ContextTestPage": (context) { + return ContextTestPage("ContextTestPage"); + }, + "DebugTestPage": (context) { + return DebugTestPage("DebugTestPage"); + }, + "DefinitionTestPage": (context) { + return DefinitionTestPage("DefinitionTestPage"); + }, + "ExamTestPage": (context) { + return ExamTestPage("ExamTestPage"); + }, + "ExpressionTestPage": (context) { + return ExpressionTestPage("ExpressionTestPage"); + }, + "IndentTestPage": (context) { + return IndentTestPage("IndentTestPage"); + }, + "ReflectionTestPage": (context) { + return ReflectionTestPage("ReflectionTestPage"); + }, + "RegressionTestPage": (context) { + return RegressionTestPage("RegressionTestPage"); + }, + "TutorialTestPage": (context) { + return TutorialTestPage("TutorialTestPage"); + }, + "ParsetTestPage": (context) { + return ParsetTestPage("ParsetTestPage"); + }, + "SequenceTestPage": (context) { + return SequenceTestPage("SequenceTestPage"); + }, + }, + ))); //SequenceTestPage +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/context_test.dart b/ohos/lz_petitparser_test_os/lib/pages/context_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..f4fad7b83b05a7b41c3b7b218d7f374e8897fae3 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/context_test.dart @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +// import 'utils/matchers.dart'; + +class ContextTestPage extends TestPage { + ContextTestPage(String title, {Key? key}) : super(title, key: key) { + const buffer = 'a\nc'; + const context = Context(buffer, 0); + test('context', () { + expect(context.buffer, buffer); + expect(context.position, 0); + expect(context.toString(), 'Context[1:1]'); + }); + group('success', () { + test('default', () { + final success = context.success('result'); + expect(success.buffer, buffer); + expect(success.position, 0); + expect(success.value, 'result'); + expect(success.isSuccess, null); + expect(success.isFailure, null); + expect(success.toString(), 'Success[1:1]: result'); + }); + test('default-1, 此处应该为X', () { + final success = context.success('result'); + success.message; + }); + test('with position', () { + final success = context.success('result', 2); + expect(success.buffer, buffer); + expect(success.position, 2); + expect(success.value, 'result'); + expect(success.isSuccess, null); + expect(success.isFailure, null); + expect(success.toString(), 'Success[2:1]: result'); + }); + test('with position-1, 此处应该为X', () { + final success = context.success('result', 2); + success.message; + }); + test('with mapping', () { + final success = context.success('result', 2).map((value) { + expect(value, 'result'); + return 123; + }); + expect(success.buffer, buffer); + expect(success.position, 2); + expect(success.value, 123); + expect(success.isSuccess, null); + expect(success.isFailure, null); + expect(success.toString(), 'Success[2:1]: 123'); + }); + test('with mapping-1, 此处应该为X', () { + final success = context.success('result', 2).map((value) { + expect(value, 'result'); + return 123; + }); + success.message; + }); + }); + group('failure', () { + test('default', () { + final failure = context.failure('error'); + expect(failure.buffer, buffer); + expect(failure.position, 0); + expect(failure.message, 'error'); + expect(failure.isSuccess, null); + expect(failure.isFailure, null); + expect(failure.toString(), 'Failure[1:1]: error'); + }); + test('default-1, 此处应该为X', () { + final failure = context.failure('error'); + failure.value; + }); + + test('with position', () { + final failure = context.failure('error', 2); + expect(failure.buffer, buffer); + expect(failure.position, 2); + expect(failure.message, 'error'); + expect(failure.isSuccess, null); + expect(failure.isFailure, null); + expect(failure.toString(), 'Failure[2:1]: error'); + }); + test('with position-1, 此处应该为X', () { + final failure = context.failure('error', 2); + failure.value; + }); + + test('with mapping', () { + final failure = context.failure('error', 2).map((value) => fail('Not expected to be called')); + expect(failure.buffer, buffer); + expect(failure.position, 2); + + expect(failure.message, 'error'); + expect(failure.isSuccess, null); + expect(failure.isFailure, null); + expect(failure.toString(), 'Failure[2:1]: error'); + }); + + test('with mapping-1, 此处应该为X', () { + final failure = context.failure('error', 2).map((value) => fail('Not expected to be called')); + + failure.value; + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/custom_dialog.dart b/ohos/lz_petitparser_test_os/lib/pages/custom_dialog.dart new file mode 100644 index 0000000000000000000000000000000000000000..e668330d9ac463f77d977a53ea75b458e09b20b6 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/custom_dialog.dart @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; + +class CustomDialog extends StatelessWidget { + final String title; + final String message; + + CustomDialog(this.title, this.message); + + @override + Widget build(BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + elevation: 0, + backgroundColor: Colors.transparent, + child: _buildDialogContent(context), + ); + } + + Widget _buildDialogContent(BuildContext context) { + return Container( + padding: EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black26, + blurRadius: 10.0, + offset: const Offset(0.0, 10.0), + ), + ], + ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '原数据:', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + ), + ), + Container( + color: const Color.fromARGB(255, 232, 232, 232), + padding: EdgeInsets.all(10), + child: Text( + title, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + ), + ), + ), + SizedBox(height: 16), + Text( + '解析后的数据:', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + ), + ), + Container( + color: const Color.fromARGB(255, 232, 232, 232), + padding: EdgeInsets.all(10), + child: Text( + message, + style: TextStyle(fontSize: 16), + textAlign: TextAlign.center, + ), + ), + SizedBox(height: 24), + ElevatedButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('关闭'), + ), + ], + ), + ), + ); + } +} + +class CustomDialogFailed extends StatelessWidget { + final String title; + final String message; + + CustomDialogFailed({required this.title, required this.message}); + + @override + Widget build(BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + elevation: 0, + backgroundColor: Colors.transparent, + child: _buildDialogContent(context), + ); + } + + Widget _buildDialogContent(BuildContext context) { + return Container( + padding: EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black26, + blurRadius: 10.0, + offset: const Offset(0.0, 10.0), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + title, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 16), + Text( + message, + style: TextStyle(fontSize: 16), + textAlign: TextAlign.center, + ), + SizedBox(height: 24), + ElevatedButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('关闭'), + ), + ], + ), + ); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/debug_test.dart b/ohos/lz_petitparser_test_os/lib/pages/debug_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..9bd5fc59f71acb157590d860634702bf16e29cfc --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/debug_test.dart @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/debug.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +// import 'utils/matchers.dart'; + +final identifier = letter() & word().star(); +final labeledIdentifier = letter().labeled('first') & word().star().labeled('remaining'); + +// Matcher isProfileFrame({required String parser, int count = 0}) => isA() +// .having((frame) => frame.parser.toString(), 'parser', contains(parser)) +// .having((frame) => frame.count, 'count', count) +// .having((frame) => frame.elapsed, 'elapsed', greaterThanOrEqualTo(Duration.zero)) +// .having((frame) => frame.toString(), 'toString', allOf(startsWith(count.toString()), contains(parser))); +bool isProfileFrame(ProfileFrame frame, {required String parser, int count = 0}) { + bool isParserValid = frame.parser.toString().contains(parser); + bool isCountValid = frame.count == count; + bool isElapsedValid = frame.elapsed.compareTo(Duration.zero) >= 0; + bool isToStringValid = frame.toString().startsWith(count.toString()) && frame.toString().contains(parser); + + return isParserValid && isCountValid && isElapsedValid && isToStringValid; +} + +// Matcher isProgressFrame({required String parser, required int position}) => isA() +// .having((frame) => frame.parser.toString(), 'parser', contains(parser)) +// .having((frame) => frame.position, 'position', position) +// .having((frame) => frame.toString(), 'toString', allOf(startsWith('*' * (position + 1)), contains(parser))); + +// Matcher isTraceEvent({required String parser, required int level, dynamic result = isNull}) => isA() +// .having((frame) => frame.parent, 'parent', level == 0 ? isNull : isNotNull) +// .having((frame) => frame.parser.toString(), 'parser', contains(parser)) +// .having((frame) => frame.level, 'level', level) +// .having((frame) => frame.result, 'result', result) +// .having((frame) => frame.toString(), 'toString', +// allOf(startsWith(' ' * level), result == isNull ? contains(parser) : contains(RegExp('Success|Failure')))); + +class DebugTestPage extends TestPage { + DebugTestPage(String title, {Key? key}) : super(title, key: key) { + group('profile', () { + test('success', () { + final frames = []; + final parser = profile(identifier, output: frames.add); + expect(parser.parse('ab123').isSuccess, null); + expect(frames, null); + // expect(frames, [ + // isProfileFrame(parser: 'SequenceParser', count: 1), + // isProfileFrame(parser: 'letter expected', count: 1), + // isProfileFrame(parser: '[0..*]', count: 1), + // isProfileFrame(parser: 'letter or digit expected', count: 5), + // ]); + }); + test('labeled', () { + final frames = []; + final parser = profile(labeledIdentifier, output: frames.add, predicate: (parser) => parser is LabeledParser); + expect(parser.parse('ab123').isSuccess, null); + expect(frames, null); + // expect(frames, [ + // isProfileFrame(parser: 'first', count: 1), + // isProfileFrame(parser: 'remaining', count: 1), + // ]); + }); + test('failure', () { + final frames = []; + final parser = profile(identifier, output: frames.add); + expect(parser.parse('1').isFailure, null); + expect(frames, null); + // expect(frames, [ + // isProfileFrame(parser: 'SequenceParser', count: 1), + // isProfileFrame(parser: 'letter expected', count: 1), + // isProfileFrame(parser: '[0..*]'), + // isProfileFrame(parser: 'letter or digit expected'), + // ]); + }); + }); + group('progress', () { + test('success', () { + final frames = []; + final parser = progress(identifier, output: frames.add); + expect(parser.parse('ab123').isSuccess, null); + expect(frames, null); + // expect(frames, [ + // isProgressFrame(parser: 'SequenceParser', position: 0), + // isProgressFrame(parser: 'letter expected', position: 0), + // isProgressFrame(parser: '[0..*]', position: 1), + // isProgressFrame(parser: 'letter or digit expected', position: 1), + // isProgressFrame(parser: 'letter or digit expected', position: 2), + // isProgressFrame(parser: 'letter or digit expected', position: 3), + // isProgressFrame(parser: 'letter or digit expected', position: 4), + // isProgressFrame(parser: 'letter or digit expected', position: 5), + // ]); + }); + test('labeled', () { + final frames = []; + final parser = progress(labeledIdentifier, output: frames.add, predicate: (parser) => parser is LabeledParser); + expect(parser.parse('ab123').isSuccess, null); + expect(frames, null); + // expect(frames, [ + // isProgressFrame(parser: 'first', position: 0), + // isProgressFrame(parser: 'remaining', position: 1), + // ]); + }); + test('failure', () { + final frames = []; + final parser = progress(identifier, output: frames.add); + expect(parser.parse('1').isFailure, null); + expect(frames, null); + // expect(frames, [ + // isProgressFrame(parser: 'SequenceParser', position: 0), + // isProgressFrame(parser: 'letter expected', position: 0), + // ]); + }); + }); + group('trace', () { + test('success', () { + final events = []; + final parser = trace(identifier, output: events.add); + expect(parser.parse('a').isSuccess, null); + expect(events, null); + // expect(events, [ + // isTraceEvent(parser: 'SequenceParser', level: 0), + // isTraceEvent(parser: 'letter expected', level: 1), + // isTraceEvent(parser: 'letter expected', level: 1, result: isSuccessContext(value: 'a')), + // isTraceEvent(parser: '[0..*]', level: 1), + // isTraceEvent(parser: 'letter or digit expected', level: 2), + // isTraceEvent( + // parser: 'letter or digit expected', level: 2, result: isFailureContext(message: 'letter or digit expected')), + // isTraceEvent(parser: '[0..*]', level: 1, result: isSuccessContext(value: [])), + // isTraceEvent(parser: 'SequenceParser', level: 0, result: isSuccessContext()), + // ]); + }); + test('labeled', () { + final events = []; + final parser = trace(labeledIdentifier, output: events.add, predicate: (parser) => parser is LabeledParser); + expect(parser.parse('ab123').isSuccess, null); + expect(events, null); + // expect(events, [ + // isTraceEvent(parser: 'first', level: 0), + // isTraceEvent(parser: 'first', level: 0, result: isSuccessContext(value: 'a')), + // isTraceEvent(parser: 'remaining', level: 0), + // isTraceEvent(parser: 'remaining', level: 0, result: isSuccessContext(value: 'b123'.split(''))), + // ]); + }); + test('failure', () { + final events = []; + final parser = trace(identifier, output: events.add); + expect(parser.parse('1').isFailure, null); + expect(events, null); + // expect(events, [ + // isTraceEvent(parser: 'SequenceParser', level: 0), + // isTraceEvent(parser: 'letter expected', level: 1), + // isTraceEvent(parser: 'letter expected', level: 1, result: isFailureContext(message: 'letter expected')), + // isTraceEvent(parser: 'SequenceParser', level: 0, result: isFailureContext(message: 'letter expected')), + // ]); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/definition_test.dart b/ohos/lz_petitparser_test_os/lib/pages/definition_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c88ce500b1d5274774ed5fb1b059517f09aacfd1 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/definition_test.dart @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +// import 'utils/assertions.dart'; +// import 'utils/matchers.dart'; + +class ListGrammarDefinition extends GrammarDefinition { + @override + Parser start() => ref0(list).end(); + + Parser list() => ref0(element) & char(',') & ref0(list) | ref0(element); + + Parser element() => digit().plus().flatten(); +} + +class ListParserDefinition extends ListGrammarDefinition { + @override + Parser element() => super.element().map((value) => int.parse(value)); +} + +class TokenizedListGrammarDefinition extends GrammarDefinition { + @override + Parser start() => ref0(list).end(); + + Parser list() => ref0(element) & ref1(token, char(',')) & ref0(list) | ref0(element); + + Parser element() => ref1(token, digit().plus()); + + Parser token(Parser parser) => parser.flatten().trim(); +} + +class TypedReferencesGrammarDefinition extends GrammarDefinition { + @override + Parser> start() => ref0(f0); + + Parser> f0() => ref1(f1, 1); + + Parser> f1(int a1) => ref2(f2, a1, 2); + + Parser> f2(int a1, int a2) => ref3(f3, a1, a2, 3); + + Parser> f3(int a1, int a2, int a3) => ref4(f4, a1, a2, a3, 4); + + Parser> f4(int a1, int a2, int a3, int a4) => ref5(f5, a1, a2, a3, a4, 5); + + Parser> f5(int a1, int a2, int a3, int a4, int a5) => [ + a1.toString().toParser(), + a2.toString().toParser(), + a3.toString().toParser(), + a4.toString().toParser(), + a5.toString().toParser(), + ].toSequenceParser(); +} + +class UntypedReferencesGrammarDefinition extends GrammarDefinition { + @override + Parser start() => ref0(f0); + + Parser f0() => ref1(f1, 1); + + Parser f1(int a1) => ref2(f2, a1, 2); + + Parser f2(int a1, int a2) => ref3(f3, a1, a2, 3); + + Parser f3(int a1, int a2, int a3) => ref4(f4, a1, a2, a3, 4); + + Parser f4(int a1, int a2, int a3, int a4) => ref5(f5, a1, a2, a3, a4, 5); + + Parser f5(int a1, int a2, int a3, int a4, int a5) => [ + a1.toString().toParser(), + a2.toString().toParser(), + a3.toString().toParser(), + a4.toString().toParser(), + a5.toString().toParser(), + ].toSequenceParser(); +} + +// ignore_for_file: deprecated_member_use_from_same_package +class DeprecatedUntypedReferencesGrammarDefinition extends GrammarDefinition { + @override + Parser start() => ref(f0); + + Parser f0() => ref(f1, 1); + + Parser f1(int a1) => ref(f2, a1, 2); + + Parser f2(int a1, int a2) => ref(f3, a1, a2, 3); + + Parser f3(int a1, int a2, int a3) => ref(f4, a1, a2, a3, 4); + + Parser f4(int a1, int a2, int a3, int a4) => ref(f5, a1, a2, a3, a4, 5); + + Parser f5(int a1, int a2, int a3, int a4, int a5) => [ + a1.toString().toParser(), + a2.toString().toParser(), + a3.toString().toParser(), + a4.toString().toParser(), + a5.toString().toParser(), + ].toSequenceParser(); +} + +class BuggedGrammarDefinition extends GrammarDefinition { + @override + Parser start() => epsilon(); + + Parser directRecursion1() => ref0(directRecursion1); + + Parser indirectRecursion1() => ref0(indirectRecursion2); + + Parser indirectRecursion2() => ref0(indirectRecursion3); + + Parser indirectRecursion3() => ref0(indirectRecursion1); + + Parser delegation1() => ref0(delegation2); + + Parser delegation2() => ref0(delegation3); + + Parser delegation3() => epsilon(); +} + +class LambdaGrammarDefinition extends GrammarDefinition { + @override + Parser start() => ref0(expression).end(); + + Parser expression() => ref0(variable) | ref0(abstraction) | ref0(application); + + Parser variable() => (letter() & word().star()).flatten().trim(); + + Parser abstraction() => token('\\') & ref0(variable) & token('.') & ref0(expression); + + Parser application() => token('(') & ref0(expression) & ref0(expression) & token(')'); + + Parser token(String value) => char(value).trim(); +} + +class ExpressionGrammarDefinition extends GrammarDefinition { + @override + Parser start() => ref0(terms).end(); + + Parser terms() => ref0(addition) | ref0(factors); + + Parser addition() => ref0(factors).separatedBy(token(char('+') | char('-'))); + + Parser factors() => ref0(multiplication) | ref0(power); + + Parser multiplication() => ref0(power).separatedBy(token(char('*') | char('/'))); + + Parser power() => ref0(primary).separatedBy(char('^').trim()); + + Parser primary() => ref0(number) | ref0(parentheses); + + Parser number() => token(char('-').optional() & digit().plus() & (char('.') & digit().plus()).optional()); + + Parser parentheses() => token('(') & ref0(terms) & token(')'); + + Parser token(Object value) { + if (value is String) { + return char(value).trim(); + } else if (value is Parser) { + return value.flatten().trim(); + } + throw ArgumentError.value(value, 'unable to parse'); + } +} + +class DefinitionTestPage extends TestPage { + DefinitionTestPage(String title, {Key? key}) : super(title, key: key) { + group('reference & resolve', () { + Parser numberToken() => + (char('-').optional() & digit().plus() & (char('.') & digit().plus()).optional()).flatten().trim(); + Parser number() => ref0(numberToken).map(num.parse); + Parser> numberList([String separator = ',']) => + ref0(number).separatedBy(separator.toParser(), includeSeparators: false); + + test('reference without parameters', () { + final firstReference = ref0(number); + final secondReference = ref0(number); + expect(firstReference != secondReference, null); + expect(firstReference == secondReference, null); //isTrue + }); + test('reference with different production', () { + final firstReference = ref0(number); + final secondReference = ref0(numberToken); + expect(firstReference != secondReference, null); //isNot(same(secondReference)) + // ignore: unrelated_type_equality_checks + expect(firstReference == secondReference, null); //isFalse + }); + test('reference with same parameters', () { + final firstReference = ref1(numberList, ','); + final secondReference = ref1(numberList, ','); + expect(firstReference != secondReference, null); //isNot(same(secondReference)) + expect(firstReference == secondReference, null); //isTrue + }); + test('reference with different parameters', () { + final firstReference = ref1(numberList, ','); + final secondReference = ref1(numberList, ';'); + expect(firstReference != secondReference, null); //isNot(same(secondReference)) + expect(firstReference == secondReference, null); //isFalse + }); + test('reference unsupported methods-0, 此处应该为X', () { + final reference = ref0(number); + reference.copy(); + }); + test('reference unsupported methods-1, 此处应该为X', () { + final reference = ref0(number); + reference.parse('0'); + }); + test('reference unsupported methods-2, 此处应该为X', () { + final reference = ref0(number); + reference.fastParseOn('0', 0); + }); + + test('references typed', () { + Parser> f9(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) => + [a1, a2, a3, a4, a5, a6, a7, a8, a9].map((value) => value.toString().toParser()).toSequenceParser(); + Parser> f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) => + ref9(f9, a1, a2, a3, a4, a5, a6, a7, a8, 9); + Parser> f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) => + ref8(f8, a1, a2, a3, a4, a5, a6, a7, 8); + Parser> f6(int a1, int a2, int a3, int a4, int a5, int a6) => ref7(f7, a1, a2, a3, a4, a5, a6, 7); + Parser> f5(int a1, int a2, int a3, int a4, int a5) => ref6(f6, a1, a2, a3, a4, a5, 6); + Parser> f4(int a1, int a2, int a3, int a4) => ref5(f5, a1, a2, a3, a4, 5); + Parser> f3(int a1, int a2, int a3) => ref4(f4, a1, a2, a3, 4); + Parser> f2(int a1, int a2) => ref3(f3, a1, a2, 3); + Parser> f1(int a1) => ref2(f2, a1, 2); + Parser> f0() => ref1(f1, 1); + Parser> start() => ref0(f0); + expect(resolve(start()), null); //isParseSuccess('123456789', '123456789'.split('')) + }); + test('references untyped', () { + Parser> f9(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) => + [a1, a2, a3, a4, a5, a6, a7, a8, a9].map((value) => value.toString().toParser()).toSequenceParser(); + Parser> f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) => + ref(f9, a1, a2, a3, a4, a5, a6, a7, a8, 9); + Parser> f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) => ref(f8, a1, a2, a3, a4, a5, a6, a7, 8); + Parser> f6(int a1, int a2, int a3, int a4, int a5, int a6) => ref(f7, a1, a2, a3, a4, a5, a6, 7); + Parser> f5(int a1, int a2, int a3, int a4, int a5) => ref(f6, a1, a2, a3, a4, a5, 6); + Parser> f4(int a1, int a2, int a3, int a4) => ref(f5, a1, a2, a3, a4, 5); + Parser> f3(int a1, int a2, int a3) => ref(f4, a1, a2, a3, 4); + Parser> f2(int a1, int a2) => ref(f3, a1, a2, 3); + Parser> f1(int a1) => ref(f2, a1, 2); + Parser> f0() => ref(f1, 1); + Parser> start() => ref(f0); + expect(resolve(start()), null); //isParseSuccess('123456789', '123456789'.split('')) + }); + test('resolved parser', () { + expect(resolve(number()), null); //isParseSuccess('1', 1) + expect(resolve(numberList()), null); //isParseSuccess('1,2', [1, 2]) + }); + test('resolved parser with arguments', () { + expect(resolve(numberList()), null); //isParseSuccess('1,2', [1, 2]) + expect(resolve(numberList(';')), null); //isParseSuccess('3;4;5', [3, 4, 5]) + }); + test('direct recursion, 此处应该为X', () { + Parser create() => ref0(create); + resolve(create()); + // expect(() => resolve(create()), throwsStateError); + }); + test('reference', () { + Parser> list() => [ + (ref0(number) & char(',') & ref0(list)).map((values) => [values[0], ...values[2]]), + ref0(number).map((value) => [value]), + ].toChoiceParser(); + final parser = resolve>(list()); + expect(parser, null); //isParseSuccess('1', [1]) + expect(parser, null); //isParseSuccess('1,2', [1, 2]) + expect(parser, null); //isParseSuccess('1,2,2', [1, 2, 2]) + }); + }); + group('definition', () { + final grammarDefinition = ListGrammarDefinition(); + final parserDefinition = ListParserDefinition(); + final tokenDefinition = TokenizedListGrammarDefinition(); + final typedReferenceDefinition = TypedReferencesGrammarDefinition(); + final untypedReferenceDefinition = UntypedReferencesGrammarDefinition(); + final deprecatedUntypedReferenceDefinition = DeprecatedUntypedReferencesGrammarDefinition(); + final buggedDefinition = BuggedGrammarDefinition(); + + test('reference without parameters', () { + final firstReference = ref0(grammarDefinition.start); + final secondReference = ref0(grammarDefinition.start); + expect(firstReference != secondReference, null); //isNot(same(secondReference)) + expect(firstReference == secondReference, null); //isTrue + }); + test('reference with different production', () { + final firstReference = ref0(grammarDefinition.start); + final secondReference = ref0(grammarDefinition.element); + expect(firstReference != secondReference, null); //isNot(same(secondReference)) + expect(firstReference == secondReference, null); //isFalse + }); + test('reference with same parameters', () { + final firstReference = ref1(typedReferenceDefinition.f1, 42); + final secondReference = ref1(typedReferenceDefinition.f1, 42); + expect(firstReference != secondReference, null); //isNot(same(secondReference)) + expect(firstReference == secondReference, null); //isTrue + }); + test('reference with different parameters', () { + final firstReference = ref1(typedReferenceDefinition.f1, 42); + final secondReference = ref1(typedReferenceDefinition.f1, 43); + expect(firstReference != secondReference, null); //isNot(same(secondReference)) + expect(firstReference == secondReference, null); //isFalse + }); + test('reference with multiple arguments', () { + final parser = typedReferenceDefinition.build(); + expect(parser, null); //isParseSuccess('12345', ['1', '2', '3', '4', '5']) + }); + test('reference with multiple arguments (untyped)', () { + final parser = untypedReferenceDefinition.build(); + expect(parser, null); //isParseSuccess('12345', ['1', '2', '3', '4', '5']) + }); + test('reference with multiple arguments (untyped, deprecated)', () { + final parser = deprecatedUntypedReferenceDefinition.build(); + expect(parser, null); //isParseSuccess('12345', ['1', '2', '3', '4', '5']) + }); + test('invalid building, 此处应该为X', () { + grammarDefinition.build(arguments: [1, 2, 3]); + // expect(() => grammarDefinition.build(arguments: [1, 2, 3]), throwsStateError); + }); + test('reference unsupported methods-0, 此处应该为X', () { + final reference = ref0(grammarDefinition.start); + reference.copy(); + // expect(() => reference.copy(), throwsUnsupportedError); + }); + test('reference unsupported methods-1, 此处应该为X', () { + final reference = ref0(grammarDefinition.start); + reference.parse(''); + // expect(() => reference.parse(''), throwsUnsupportedError); + }); + + test('grammar', () { + final parser = grammarDefinition.build(); + expect(parser, null); //isParseSuccess('1,2', ['1', ',', '2']) + }); + test('parser', () { + final parser = parserDefinition.build(); + expect(parser, null); + expect(parser, null); + }); + test('token', () { + final parser = tokenDefinition.build(); + expect(parser, null); + expect(parser, null); + }); + test('direct recursion, 此处应该为X', () { + buggedDefinition.build(start: buggedDefinition.directRecursion1); + // expect(() => buggedDefinition.build(start: buggedDefinition.directRecursion1), throwsStateError); + }); + + test('indirect recursion-0, 此处应该为X', () { + buggedDefinition.build(start: buggedDefinition.indirectRecursion1); + // expect(() => buggedDefinition.build(start: buggedDefinition.indirectRecursion1), throwsStateError); + }); + test('indirect recursion-1, 此处应该为X', () { + buggedDefinition.build(start: buggedDefinition.indirectRecursion2); + // expect(() => buggedDefinition.build(start: buggedDefinition.indirectRecursion2), throwsStateError); + }); + test('indirect recursion-2, 此处应该为X', () { + buggedDefinition.build(start: buggedDefinition.indirectRecursion3); + // expect(() => buggedDefinition.build(start: buggedDefinition.indirectRecursion3), throwsStateError); + }); + + test('delegation', () { + expect(buggedDefinition.build(start: buggedDefinition.delegation1), null); // isA() + expect(buggedDefinition.build(start: buggedDefinition.delegation2), null); //isA() + expect(buggedDefinition.build(start: buggedDefinition.delegation3), null); //isA() + }); + test('lambda example', () { + final definition = LambdaGrammarDefinition(); + final parser = definition.build(); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + }); + test('expression example', () { + final definition = ExpressionGrammarDefinition(); + final parser = definition.build(); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/e_and_parser.dart b/ohos/lz_petitparser_test_os/lib/pages/e_and_parser.dart new file mode 100644 index 0000000000000000000000000000000000000000..5dcb0cce1872b4755abd79b5ec09858e7df609bd --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/e_and_parser.dart @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import 'package:petitparser/petitparser.dart'; + +///petitparser 支持解析器的组合。 +///可以将多个解析器组合成一个更复杂的解析器。 +class EAndParser extends StatefulWidget { + const EAndParser({super.key}); + + @override + State createState() => _EAndParserState(); +} + +class _EAndParserState extends State { + var resultStr = ''; + final invalidStr = 'Invalid input'; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('构建解析器'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16), + child: Column( + children: [ + Text('待解析数据"1 + 2" 和 "3 - 1"'), + SizedBox(height: 10), + TextButton( + onPressed: () { + _buildParser(); + setState(() {}); + }, + child: Text('开始解析')), + Text('解析结果:"'), + SizedBox(height: 10), + Container( + color: const Color.fromARGB(255, 224, 224, 224), + child: Text(resultStr), + ), + ], + ), + ), + )); + } + + void _buildParser() { + resultStr = ''; + // 创建一个解析器,用于解析一个数字字符并将其转换为整数 + final digitParser = digit().flatten().map(int.parse); + + // 创建一个解析器,用于解析 '+' 字符并忽略其两边的空白字符 + final addParser = char('+').trim(); + + // 创建一个解析器,用于解析 '-' 字符并忽略其两边的空白字符 + final subtractParser = char('-').trim(); + + // 使用 `seq` 方法将 `digitParser` 和 `addParser` 组合成一个解析器 + // 这个解析器可以解析形如 "[数字] + [数字]" 的字符串 + final addExpressionParser = digitParser.seq(addParser).seq(digitParser); + + // 使用 `seq` 方法将 `digitParser` 和 `subtractParser` 组合成一个解析器 + // 这个解析器可以解析形如 "[数字] - [数字]" 的字符串 + final subtractExpressionParser = digitParser.seq(subtractParser).seq(digitParser); + + // 使用 `or` 方法将 `addExpressionParser` 和 `subtractExpressionParser` 组合成一个解析器 + // 这个解析器可以解析形如 "[数字] + [数字]" 或 "[数字] - [数字]" 的字符串 + final expressionParser = addExpressionParser.or(subtractExpressionParser); + + // 使用 `expressionParser` 来解析字符串 '1 + 2' + final addResult = expressionParser.parse('1 + 2'); + if (addResult.isSuccess) { + // 如果解析成功,打印出两个数字的和 + final values = addResult.value; + final firstNumber = values[0]; + final secondNumber = values[2]; + resultStr = '$firstNumber\n\n$secondNumber'; + print('The sum is ${firstNumber + secondNumber}'); + } else { + resultStr = 'Invalid input'; + // 如果解析失败,打印 'Invalid input' + print('Invalid input'); + } + + // 使用 `expressionParser` 来解析字符串 '3 - 1' + final subtractResult = expressionParser.parse('3 - 1'); + if (subtractResult.isSuccess) { + // 如果解析成功,打印出两个数字的差 + final values = subtractResult.value; + final firstNumber = values[0]; + final secondNumber = values[2]; + resultStr = '$resultStr\n\n$firstNumber\n\n$secondNumber'; + print('The difference is ${firstNumber - secondNumber}'); + } else { + resultStr = '$resultStr\n\n Invalid input'; + // 如果解析失败,打印 'Invalid input' + print('Invalid input'); + } + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/e_build_parser.dart b/ohos/lz_petitparser_test_os/lib/pages/e_build_parser.dart new file mode 100644 index 0000000000000000000000000000000000000000..c437ad469bcb15de585aab8101e3d246373b4856 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/e_build_parser.dart @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import 'package:petitparser/petitparser.dart'; + +///这个解析器,用于解析形如 "[数字] + [数字]" 的字符串。 +class EBuildParser extends StatefulWidget { + const EBuildParser({super.key}); + + @override + State createState() => _EBuildParserState(); +} + +class _EBuildParserState extends State { + var resultStr = ''; + final invalidStr = 'Invalid input'; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('构建解析器'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16), + child: Column( + children: [ + Text('待解析数据"1 + 2"'), + SizedBox(height: 10), + TextButton( + onPressed: () { + _buildParser(); + setState(() {}); + }, + child: Text('开始解析')), + Text('解析结果:"'), + SizedBox(height: 10), + Container( + color: const Color.fromARGB(255, 224, 224, 224), + child: Text(resultStr), + ), + ], + ), + ), + )); + } + +//**首先创建了一个 digitParser,它会解析一个数字字符并将其转换为整数。 +//然后,我们创建了一个 operatorParser,它会解析 '+' 字符并忽略其两边的空白字符。 +//然后,我们使用 seq 方法将这两个解析器组合成一个 expressionParser, +//它会解析形如 "[数字] + [数字]" 的字符串。 +//然后,我们使用这个 expressionParser 来解析字符串 '1 + 2'。 +//如果解析成功,我们会打印出两个数字的和。 +//如果解析失败,我们会打印 'Invalid input'。 */ + List _buildParser() { + final digitParser = digit().flatten().map(int.parse); + final operatorParser = char('+').trim(); + final expressionParser = digitParser.seq(operatorParser).seq(digitParser); + + final result = expressionParser.parse('1 + 2'); + if (result.isSuccess) { + final values = result.value; + final firstNumber = values[0]; + final secondNumber = values[2]; + resultStr = '$firstNumber\n\n$secondNumber'; + return [firstNumber.toString(), secondNumber.toString()]; + } else { + resultStr = 'Invalid input'; + return ['Invalid input']; + } + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/e_error_parser.dart b/ohos/lz_petitparser_test_os/lib/pages/e_error_parser.dart new file mode 100644 index 0000000000000000000000000000000000000000..a4f488710f99d9b83f93923f38cc8f8e592d6d39 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/e_error_parser.dart @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import 'package:petitparser/petitparser.dart'; + +///petitparser 支持错误恢复和错误报告。 +///可以使用 FailureParser 来创建一个总是失败的解析器,或者使用 or 方法来处理解析失败的情况。 +class EErrorParser extends StatefulWidget { + const EErrorParser({super.key}); + + @override + State createState() => _EErrorParserState(); +} + +class _EErrorParserState extends State { + var resultStr = ''; + final invalidStr = 'Invalid input'; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('错误处理'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16), + child: Column( + children: [ + Text('待解析数据:"1 +a"'), + SizedBox(height: 10), + TextButton( + onPressed: () { + _buildParser(); + setState(() {}); + }, + child: Text('开始解析')), + Text('解析结果:"'), + SizedBox(height: 10), + Container( + color: const Color.fromARGB(255, 224, 224, 224), + child: Text(resultStr), + ), + ], + ), + ), + )); + } + + void _buildParser() { + // 创建一个解析器,用于解析一个数字字符并将其转换为整数 + final digitParser = digit().flatten().map(int.parse); + + // 创建一个解析器,用于解析 '+' 字符并忽略其两边的空白字符 + final operatorParser = char('+').trim(); + + // 使用 `seq` 方法将 `digitParser` 和 `operatorParser` 组合成一个解析器 + // 这个解析器可以解析形如 "[数字] + [数字]" 的字符串 + final expressionParser = digitParser.seq(operatorParser).seq(digitParser); + + // 创建一个总是失败的解析器,当解析失败时,它将返回一个错误消息 + final failureParser = failure('解析出错:Invalid input'); + + // 使用 `or` 方法将 `expressionParser` 和 `failureParser` 组合成一个新的解析器 + // 这个新的解析器在 `expressionParser` 解析失败时,会尝试使用 `failureParser` 进行解析 + final parser = expressionParser.or(failureParser); + + // 使用新的解析器来解析字符串 '1 + a' + // 这个字符串是无效的,因为它包含一个非数字字符 'a' + final result = parser.parse('1 + a'); + if (result.isFailure) { + resultStr = result.message; + // 如果解析失败,打印出错误消息 + print(result.message); + } else { + // 如果解析成功,打印出两个数字的和 + final values = result.value; + final firstNumber = values[0]; + final secondNumber = values[2]; + resultStr = '$firstNumber\n\n$secondNumber'; + print('The sum is ${firstNumber + secondNumber}'); + } + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/e_extension_parser.dart b/ohos/lz_petitparser_test_os/lib/pages/e_extension_parser.dart new file mode 100644 index 0000000000000000000000000000000000000000..324ddd5e70e5b1548ce044868bf129461b356547 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/e_extension_parser.dart @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import 'package:petitparser/petitparser.dart'; + +//扩展解析器:你可以通过继承 Parser 类或使用 DelegateParser 类来创建自定义的解析器。 +// 创建一个扩展解析器,用于解析形如 "[数字] + [数字]" 的字符串并计算它们的和 +class SumParser extends DelegateParser { + SumParser(Parser delegate) : super(delegate); + + @override + Result parseOn(Context context) { + final result = delegate.parseOn(context); + if (result.isSuccess) { + final values = result.value; + final firstNumber = values[0]; + final secondNumber = values[2]; + final sum = firstNumber + secondNumber; + return result.success(sum); + } else { + return result; + } + } + + @override + Parser copy() { + return SumParser(super.delegate); + } +} + +class EExtensionParser extends StatefulWidget { + const EExtensionParser({super.key}); + + @override + State createState() => _EExtensionParserState(); +} + +class _EExtensionParserState extends State { + var resultStr = ''; + final invalidStr = 'Invalid input'; + final parserStr = '1 + 2'; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('扩展解析器'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16), + child: Column( + children: [ + const Text( + '扩展解析器,用于解析形如 "[数字] + [数字]" \n的字符串并计算它们的和', + maxLines: 3, + style: TextStyle(overflow: TextOverflow.clip), + ), + Text('解析字符串:"$parserStr"'), + SizedBox(height: 10), + TextButton( + onPressed: () { + _buildParser(); + setState(() {}); + }, + child: Text('开始解析')), + Text('解析结果:"'), + SizedBox(height: 10), + Container( + color: const Color.fromARGB(255, 224, 224, 224), + child: Text(resultStr), + ), + ], + ), + ), + )); + } + + void _buildParser() { + // 创建一个解析器,用于解析一个数字字符并将其转换为整数 + final digitParser = digit().flatten().map(int.parse); + + // 创建一个解析器,用于解析 '+' 字符并忽略其两边的空白字符 + final operatorParser = char('+').trim(); + + // 使用 `seq` 方法将 `digitParser` 和 `operatorParser` 组合成一个解析器 + // 这个解析器可以解析形如 "[数字] + [数字]" 的字符串 + final expressionParser = digitParser.seq(operatorParser).seq(digitParser); + + // 创建一个 `SumParser` 实例 + final sumParser = SumParser(expressionParser); + + // 使用 `sumParser` 来解析字符串 '1 + 2' + final result = sumParser.parse('1 + 2'); + if (result.isSuccess) { + resultStr = result.value.toString(); + // 如果解析成功,打印出两个数字的和 + print('The sum is ${result.value}'); + } else { + resultStr = invalidStr; + // 如果解析失败,打印 'Invalid input' + print('Invalid input'); + } + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/e_lookahead.dart b/ohos/lz_petitparser_test_os/lib/pages/e_lookahead.dart new file mode 100644 index 0000000000000000000000000000000000000000..139cc8b6894d1ffbefbe69c402dded56871c678f --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/e_lookahead.dart @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import 'package:petitparser/petitparser.dart'; + +///预测性解析:petitparser 支持预测性解析,它可以在解析时查看输入的未来部分,而不消耗它。 +///petitparser 的所有解析器都是预测性的,因为它们都可以查看输入的未来部分,而不消耗它。 +///这是因为 petitparser 使用的是 LL(*) 解析算法,它可以无限制地向前看输入,以决定如何进行解析。 +class ElookaheadParser extends StatefulWidget { + const ElookaheadParser({super.key}); + + @override + State createState() => _ElookaheadParserState(); +} + +class _ElookaheadParserState extends State { + var resultStr = ''; + final invalidStr = 'Invalid input'; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('预测性解析'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16), + child: Column( + children: [ + Text('待解析数据"ab" 、"ac"、"ad"'), + SizedBox(height: 10), + TextButton( + onPressed: () { + _buildParser(); + setState(() {}); + }, + child: Text('开始解析')), + Text('解析结果:"'), + SizedBox(height: 10), + Container( + color: const Color.fromARGB(255, 224, 224, 224), + child: Text(resultStr), + ), + ], + ), + ), + )); + } + + void _buildParser() { + resultStr = ''; + // 创建一个解析器,它期望看到一个 'a',后面是 'b' 或 'c' + final parser = char('a').seq(char('b').or(char('c'))); + + // 应该成功解析 "ab",并返回 ['a', 'b'] + final result1 = parser.parse('ab'); + if (result1.isSuccess) { + resultStr = result1.value.toString(); + print('Parsed successfully: ${result1.value}'); + } else { + resultStr = 'Parse failed: ${result1.message}'; + print('Parse failed: ${result1.message}'); + } + + // 应该成功解析 "ac",并返回 ['a', 'c'] + final result2 = parser.parse('ac'); + if (result2.isSuccess) { + resultStr = '$resultStr\n\n${result2.value}'; + print('Parsed successfully: ${result2.value}'); + } else { + resultStr = '$resultStr\n\nParse failed: ${result2.message}'; + print('Parse failed: ${result2.message}'); + } + + // 应该无法解析 "ad",因为它期望在 "a" 后面看到的是 "b" 或 "c" + final result3 = parser.parse('ad'); + if (result3.isSuccess) { + resultStr = '$resultStr\n\n${result3.value}'; + print('Parsed successfully: ${result3.value}'); + } else { + resultStr = '$resultStr\n\nParse failed: ${result3.message}'; + print('Parse failed: ${result3.message}'); + } + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/e_optimization.dart b/ohos/lz_petitparser_test_os/lib/pages/e_optimization.dart new file mode 100644 index 0000000000000000000000000000000000000000..2d85b180b5b784d363fbf21caa7cef534244c589 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/e_optimization.dart @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import 'package:petitparser/petitparser.dart'; + +///上下文文敏感解析,可以使用 Parser.callCC 方法来改变解析的行为。 +class EOptimizationParser extends StatefulWidget { + const EOptimizationParser({super.key}); + + @override + State createState() => _EOptimizationParserState(); +} + +class _EOptimizationParserState extends State { + var resultStr = ''; + final invalidStr = 'Invalid input'; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('解析优化'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16), + child: Column( + children: [ + Text('待解析数据"abc"'), + SizedBox(height: 10), + TextButton( + onPressed: () { + _buildParser(); + setState(() {}); + }, + child: Text('开始解析')), + Text('解析结果:"'), + SizedBox(height: 10), + Container( + color: const Color.fromARGB(255, 224, 224, 224), + child: Text(resultStr), + ), + ], + ), + ), + )); + } + + void _buildParser() { + resultStr = ''; + // 创建一个解析器,它期望看到一个 'a' 或 'b' 或 'c' + final parser = char('a').or(char('b')).or(char('c')); + + // 解析输入,并记录所需时间 + var start = DateTime.now(); + parser.parse('dedfgijklmnopqrstuvwxyzabc'); + var end = DateTime.now(); + resultStr = '优化前所需时间:${end.difference(start)}\n\n'; + print('Before optimization: ${end.difference(start)}'); + + // 优化解析器:使用预编译的解析器 + final optimizedParser = parser.end().flatten().trim(); + + // 再次解析输入,并记录所需时间 + start = DateTime.now(); + optimizedParser.parse('abc'); + end = DateTime.now(); + resultStr = resultStr + '优化后所需时间:${end.difference(start)}'; + print('After optimization: ${end.difference(start)}'); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/e_parser_acion.dart b/ohos/lz_petitparser_test_os/lib/pages/e_parser_acion.dart new file mode 100644 index 0000000000000000000000000000000000000000..23313e366551f2f5f0b73a3979a51699a9cd9ee1 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/e_parser_acion.dart @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import 'package:petitparser/petitparser.dart'; + +import 'custom_dialog.dart'; + +///解析各种格式的数据,包括XML、JSON、HTTML、CSS +///可以使用 map 方法来对解析结果进行转换,或者使用 token 方法来获取解析结果的详细信息(如文本、行号、列号等)。 +class EParserAction extends StatefulWidget { + const EParserAction({super.key}); + + @override + State createState() => _EParserActionState(); +} + +class _EParserActionState extends State { + var resultStr = ''; + final invalidStr = 'Invalid input'; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('解析动作'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16), + child: Center( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _buttonWidget(() { + _jsonParser(); + }, '解析JSON数据'), + _buttonWidget(() { + _xmlParser(); + }, '解析XML数据'), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _buttonWidget(() { + _htmlParser(); + }, '解析HTML数据'), + _buttonWidget(() { + _cssParser(); + }, '解析CSS数据'), + ], + ), + ], + ), + ), + ), + )); + } + + Widget _buttonWidget(VoidCallback onTap, String title) { + return TextButton( + onPressed: onTap, + child: Container( + padding: EdgeInsets.all(20), + child: Text(title), + )); + } + + void _jsonParser() { + // 创建一个 JSON 解析器 + final parser = char('{') + .seq(letter().plus().flatten().trim()) + .seq(char(':')) + .seq(any().star().flatten().trim()) + .seq(char('}')) + .map((value) { + // 将解析结果转换为 Map + return {value[1]: value[3]}; + }); + + // 定义一个简单的 JSON 字符串 + final jsonString = '{"name": "John"}'; + + // 使用解析器来解析 JSON 字符串 + final result = parser.parse(jsonString); + if (result.isSuccess) { + // 解析成功 + CustomDialog('{"name": "John"}', result.value.toString()); + print('Parsed JSON: ${result.value}'); + } else { + // 解析失败 + CustomDialogFailed( + title: '解析失败', + message: result.message, + ); + print('Parse failed: ${result.message}'); + } + } + + void _xmlParser() { + // 创建一个 XML 解析器 + final parser = char('<') + .seq(letter().plus().flatten()) + .seq(char('>')) + .seq(any().starLazy(char('<')).flatten()) + .seq(char('<').seq(char('/')).seq(letter().plus().flatten()).seq(char('>'))) + .map((value) { + // 将解析结果转换为 Map + return {value[1]: value[3]}; + }); + + // 定义一个简单的 XML 字符串 + final xmlString = 'John'; + + // 使用解析器来解析 XML 字符串 + final result = parser.parse(xmlString); + if (result.isSuccess) { + // 解析成功 + CustomDialog('John', result.value.toString()); + print('Parsed XML: ${result.value}'); + } else { + // 解析失败 + CustomDialogFailed( + title: '解析失败', + message: result.message, + ); + print('Parse failed: ${result.message}'); + } + } + + void _htmlParser() { + // 创建一个 HTML 解析器 + final parser = char('<') + .seq(letter().plus().flatten()) + .seq(char('>')) + .seq(any().starLazy(char('<')).flatten()) + .seq(char('<').seq(char('/')).seq(letter().plus().flatten()).seq(char('>'))) + .map((value) { + // 将解析结果转换为 Map + return {value[1]: value[3]}; + }); + + // 定义一个简单的 HTML 字符串 + final htmlString = '

Hello, World!

'; + + // 使用解析器来解析 HTML 字符串 + final result = parser.parse(htmlString); + if (result.isSuccess) { + // 解析成功 + CustomDialog('

Hello, World!

', result.value.toString()); + print('Parsed HTML: ${result.value}'); + } else { + // 解析失败 + CustomDialogFailed( + title: '解析失败', + message: result.message, + ); + print('Parse failed: ${result.message}'); + } + } + + void _cssParser() { + // 创建一个 CSS 解析器 + final parser = letter() + .plus() + .flatten() + .trim() // 解析选择器 + .seq(char('{')) // 解析 '{' 符号 + .seq(letter().plus().flatten().trim()) // 解析属性名 + .seq(char(':')) // 解析 ':' 符号 + .seq(any().starLazy(char('}')).flatten().trim()) // 解析属性值 + .seq(char('}')) // 解析 '}' 符号 + .map((value) { + // 将解析结果转换为 Map + return { + value[0]: {value[2]: value[4]} + }; + }); + + // 定义一个简单的 CSS 字符串 + final cssString = 'h1 { color: blue; }'; + + // 使用解析器来解析 CSS 字符串 + final result = parser.parse(cssString); + if (result.isSuccess) { + // 解析成 + CustomDialog('h1 { color: blue; }', result.value.toString()); + print('Parsed CSS: ${result.value}'); + } else { + // 解析失败 + CustomDialogFailed( + title: '解析失败', + message: result.message, + ); + print('Parse failed: ${result.message}'); + } + } +} + +void _lookahead() { + // 创建一个解析器,它期望看到一个 'a',后面不是 'c' + final parser = char('a').seq(char('c').not()); + + // 应该成功解析 "ac",并返回 ['a', 'd'] + final result1 = parser.parse('ad'); + if (result1.isSuccess) { + print('Parsed successfully: ${result1.value}'); + } else { + print('Parse failed: ${result1.message}'); + } + + // 应该无法解析 "ac",因为它期望在 "a" 后面看到的不是 "c" + final result2 = parser.parse('ac'); + if (result2.isSuccess) { + print('Parsed successfully: ${result2.value}'); + } else { + print('Parse failed: ${result2.message}'); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/e_reuse_parser.dart b/ohos/lz_petitparser_test_os/lib/pages/e_reuse_parser.dart new file mode 100644 index 0000000000000000000000000000000000000000..d79dcc70966aa07676250116e4de988e537a3394 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/e_reuse_parser.dart @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import 'package:petitparser/petitparser.dart'; + +///这个重用解析器,用于解析形如 "[数字] + [数字]" 的字符串。 +class EReuseParser extends StatefulWidget { + const EReuseParser({super.key}); + + @override + State createState() => _EReuseParserState(); +} + +class _EReuseParserState extends State { + var resultStr = ''; + final invalidStr = 'Invalid input'; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('重用解析器'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16), + child: Column( + children: [ + Text('待解析数据"1 + 2" 和 "3 + 4"'), + SizedBox(height: 10), + TextButton( + onPressed: () { + _buildParser(); + setState(() {}); + }, + child: Text('开始解析')), + Text('解析结果:"'), + SizedBox(height: 10), + Container( + color: const Color.fromARGB(255, 224, 224, 224), + child: Text(resultStr), + ), + ], + ), + ), + )); + } + + void _buildParser() { + resultStr = ''; + // 创建一个解析器,用于解析一个数字字符并将其转换为整数 + final digitParser = digit().flatten().map(int.parse); + + // 创建一个解析器,用于解析 '+' 字符并忽略其两边的空白字符 + final addParser = char('+').trim(); + + // 使用 `seq` 方法将 `digitParser` 和 `addParser` 组合成一个解析器 + // 这个解析器可以解析形如 "[数字] + [数字]" 的字符串 + final addExpressionParser = digitParser.seq(addParser).seq(digitParser); + + // 使用 `addExpressionParser` 来解析字符串 '1 + 2' + final addResult1 = addExpressionParser.parse('1 + 2'); + if (addResult1.isSuccess) { + // 如果解析成功,打印出两个数字的和 + final values = addResult1.value; + final firstNumber = values[0]; + final secondNumber = values[2]; + resultStr = '$firstNumber\n\n$secondNumber'; + print('The sum is ${firstNumber + secondNumber}'); + } else { + resultStr = 'Invalid input'; + // 如果解析失败,打印 'Invalid input' + print('Invalid input'); + } + + // 再次使用 `addExpressionParser` 来解析字符串 '3 + 4' + // 这里我们重用了 `addExpressionParser` 解析器 + final addResult2 = addExpressionParser.parse('3 + 4'); + if (addResult2.isSuccess) { + // 如果解析成功,打印出两个数字的和 + final values = addResult2.value; + final firstNumber = values[0]; + final secondNumber = values[2]; + resultStr = '$resultStr\n\n$firstNumber\n\n$secondNumber'; + print('The sum is ${firstNumber + secondNumber}'); + } else { + resultStr = '$resultStr\n\n$invalidStr'; + // 如果解析失败,打印 'Invalid input' + print('Invalid input'); + } + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/e_sensitive.dart b/ohos/lz_petitparser_test_os/lib/pages/e_sensitive.dart new file mode 100644 index 0000000000000000000000000000000000000000..628dbdf91926057e0efd9bde5c784e9e5641d440 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/e_sensitive.dart @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import 'package:petitparser/petitparser.dart'; + +///上下文文敏感解析,可以使用 Parser.callCC 方法来改变解析的行为。 +///创建一个解析器,它期望看到一个 'a',然后用 callCC 改变解析的行为 +///如果解析成功,我们改变解析的结果,将结果字符串翻倍 +class ESensitiveParser extends StatefulWidget { + const ESensitiveParser({super.key}); + + @override + State createState() => _ESensitiveParserState(); +} + +class _ESensitiveParserState extends State { + var resultStr = ''; + final invalidStr = 'Invalid input'; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('上下文敏感解析'), + ), + body: SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(16), + child: Column( + children: [ + Text('待解析数据"a"'), + SizedBox(height: 10), + TextButton( + onPressed: () { + _buildParser(); + setState(() {}); + }, + child: Text('开始解析')), + Text('解析结果:"'), + SizedBox(height: 10), + Container( + color: const Color.fromARGB(255, 224, 224, 224), + child: Text(resultStr), + ), + ], + ), + ), + )); + } + + void _buildParser() { + resultStr = ''; + // 创建一个解析器,它期望看到一个 'a',然后用 callCC 改变解析的行为 + final parser = char('a').callCC((continuation, context) { + // 获取原本应该解析的结果 + final result = continuation(context); + + // 如果解析成功,我们改变解析的结果,将结果字符串翻倍 + if (result.isSuccess) { + return result.success(result.value + result.value, result.position); + } else { + return result; + } + }); + + // 应该成功解析 "a",并返回 "aa" + final result = parser.parse('a'); + if (result.isSuccess) { + resultStr = result.value; + print('Parsed successfully: ${result.value}'); + } else { + resultStr = 'Parse failed: ${result.message}'; + print('Parse failed: ${result.message}'); + } + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/example_test.dart b/ohos/lz_petitparser_test_os/lib/pages/example_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..925013468ad3ff71a12dc062b6ae46397d26080e --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/example_test.dart @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 'utils/matchers.dart'; + +class ExamTestPage extends TestPage { + ExamTestPage(String title, {Key? key}) : super(title, key: key) { + final identifier = letter().seq(word().star()).flatten(); + final number = char('-').optional().seq(digit().plus()).seq(char('.').seq(digit().plus()).optional()).flatten(); + final quoted = char('"').seq(char('"').neg().star()).seq(char('"')).flatten(); + final keyword = + string('return').seq(whitespace().plus().flatten()).seq(identifier.or(number).or(quoted)).map((list) => list.last); + final javadoc = string('/**').seq(string('*/').neg().star()).seq(string('*/')).flatten(); + final multiLine = string('"""').seq((string(r'\"""') | any()).starLazy(string('"""')).flatten()).seq(string('"""')).pick(1); + test('valid identifier', () { + expect(identifier, null); + expect(identifier, null); + expect(identifier, null); + expect(identifier, null); + expect(identifier, null); + }); + test('incomplete identifier', () { + expect(identifier, null); + expect(identifier, null); + expect(identifier, null); + expect(identifier, null); + }); + test('invalid identifier', () { + expect(identifier, null); + expect(identifier, null); + expect(identifier, null); + }); + test('positive number', () { + expect(number, null); + expect(number, null); + expect(number, null); + expect(number, null); + }); + test('negative number', () { + expect(number, null); + expect(number, null); + expect(number, null); + expect(number, null); + }); + test('incomplete number', () { + expect(number, null); + expect(number, null); + expect(number, null); + expect(number, null); + }); + test('invalid number', () { + expect(number, null); + expect(number, null); + expect(number, null); + expect(number, null); + expect(number, null); + }); + test('valid string', () { + expect(quoted, null); + expect(quoted, null); + expect(quoted, null); + expect(quoted, null); + }); + test('incomplete string', () { + expect(quoted, null); + expect(quoted, null); + expect(quoted, null); + expect(quoted, null); + }); + test('invalid string', () { + expect(quoted, null); + expect(quoted, null); + expect(quoted, null); + expect(quoted, null); + }); + test('return statement', () { + expect(keyword, null); + expect(isParseSuccess(keyword, 'return foo'), null); + // expect(keyword, isParseSuccess('return f', 'f')); + // expect(keyword, isParseSuccess('return foo', 'foo')); + // expect(keyword, isParseSuccess('return foo', 'foo')); + // expect(keyword, isParseSuccess('return 1', '1')); + // expect(keyword, isParseSuccess('return 1', '1')); + // expect(keyword, isParseSuccess('return -2.3', '-2.3')); + // expect(keyword, isParseSuccess('return -2.3', '-2.3')); + // expect(keyword, isParseSuccess('return "a"', '"a"')); + // expect(keyword, isParseSuccess('return "a"', '"a"')); + }); + test('invalid statement', () { + expect(keyword, null); + expect(isParseFailure(keyword, 'retur f'), null); + // expect(keyword, isParseFailure('retur f', message: '"return" expected')); + // expect(keyword, isParseFailure('return1', position: 6, message: 'whitespace expected')); + // expect(keyword, isParseFailure('return _', position: 8, message: '"\\"" expected')); + }); + test('javadoc', () { + expect(javadoc, null); + expect(isParseSuccess(javadoc, '/** foo */'), null); + // expect(javadoc, isParseSuccess('/** foo */', '/** foo */')); + // expect(javadoc, isParseSuccess('/** * * */', '/** * * */')); + }); + test('multiline', () { + expect(multiLine, null); + expect(isParseSuccess(multiLine, r'"""abc\"""def"""'), null); + // expect(multiLine, isParseSuccess(r'"""abc"""', r'abc')); + // expect(multiLine, isParseSuccess(r'"""abc\n"""', r'abc\n')); + // expect(multiLine, isParseSuccess(r'"""abc\"""def"""', r'abc\"""def')); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/expression_test.dart b/ohos/lz_petitparser_test_os/lib/pages/expression_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a2ab034adc2156fdace51437813832a5d621dfbd --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/expression_test.dart @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'dart:math' as math; + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/petitparser.dart'; +import 'package:petitparser/reflection.dart'; + +import '../common/test_page.dart'; + +Parser buildParser() { + final builder = ExpressionBuilder(); + builder.group() + ..primitive(digit().plus().seq(char('.').seq(digit().plus()).optional()).flatten().trim()) + ..wrapper(char('(').trim(), char(')').trim(), (left, value, right) => [left, value, right]) + ..wrapper(string('sqrt(').trim(), char(')').trim(), (left, value, right) => [left, value, right]); + builder.group().prefix(char('-').trim(), (op, a) => [op, a]); + builder.group() + ..postfix(string('++').trim(), (a, op) => [a, op]) + ..postfix(string('--').trim(), (a, op) => [a, op]); + builder.group().right(char('^').trim(), (a, op, b) => [a, op, b]); + builder.group() + ..left(char('*').trim(), (a, op, b) => [a, op, b]) + ..left(char('/').trim(), (a, op, b) => [a, op, b]); + builder.group() + ..left(char('+').trim(), (a, op, b) => [a, op, b]) + ..left(char('-').trim(), (a, op, b) => [a, op, b]); + return builder.build().end(); +} + +Parser buildEvaluator() { + final builder = ExpressionBuilder(); + builder.group() + ..primitive(digit().plus().seq(char('.').seq(digit().plus()).optional()).flatten().trim().map(num.parse)) + ..wrapper(char('(').trim(), char(')').trim(), (left, value, right) => value) + ..wrapper(string('sqrt(').trim(), char(')').trim(), (left, value, right) => math.sqrt(value)); + builder.group().prefix(char('-').trim(), (op, a) => -a); + builder.group() + ..postfix(string('++').trim(), (a, op) => ++a) + ..postfix(string('--').trim(), (a, op) => --a); + builder.group().right(char('^').trim(), (a, op, b) => math.pow(a, b)); + builder.group() + ..left(char('*').trim(), (a, op, b) => a * b) + ..left(char('/').trim(), (a, op, b) => a / b); + builder.group() + ..left(char('+').trim(), (a, op, b) => a + b) + ..left(char('-').trim(), (a, op, b) => a - b); + return builder.build().end(); +} + +class ExpressionTestPage extends TestPage { + ExpressionTestPage(String title, {Key? key}) : super(title, key: key) { + const epsilon = 1e-5; + final parser = buildParser(); + final evaluator = buildEvaluator(); + test('number', () { + expect(evaluator.parse('0').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('0.0').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1.2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('34').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('34.7').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('56.78').value, null); // closeTo(0, epsilon) + }); + test('number negative', () { + expect(evaluator.parse('-1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('-1.2').value, null); // closeTo(0, epsilon) + }); + test('number parse', () { + expect(parser.parse('0').value, '0'); + expect(parser.parse('-1').value, ['-', '1']); + }); + test('add', () { + expect(evaluator.parse('1 + 2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('2 + 1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 + 2.3').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('2.3 + 1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 + -2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('-2 + 1').value, null); // closeTo(0, epsilon) + }); + test('add many', () { + expect(evaluator.parse('1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 + 2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 + 2 + 3').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 + 2 + 3 + 4').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 + 2 + 3 + 4 + 5').value, null); // closeTo(0, epsilon) + }); + test('add parse', () { + expect(parser.parse('1 + 2 + 3').value, [ + ['1', '+', '2'], + '+', + '3' + ]); + }); + test('sub', () { + expect(evaluator.parse('1 - 2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1.2 - 1.2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 - -2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('-1 - -2').value, null); // closeTo(0, epsilon) + }); + test('sub many', () { + expect(evaluator.parse('1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 - 2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 - 2 - 3').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 - 2 - 3 - 4').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 - 2 - 3 - 4 - 5').value, null); // closeTo(0, epsilon) + }); + test('sub parse', () { + expect(parser.parse('1 - 2 - 3').value, [ + ['1', '-', '2'], + '-', + '3' + ]); + }); + test('mul', () { + expect(evaluator.parse('2 * 3').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('2 * -4').value, null); // closeTo(0, epsilon) + }); + test('mul many', () { + expect(evaluator.parse('1 * 2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 * 2 * 3').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 * 2 * 3 * 4').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 * 2 * 3 * 4 * 5').value, null); // closeTo(0, epsilon) + }); + test('mul parse', () { + expect(parser.parse('1 * 2 * 3').value, [ + ['1', '*', '2'], + '*', + '3' + ]); + }); + test('div', () { + expect(evaluator.parse('12 / 3').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('-16 / -4').value, null); // closeTo(0, epsilon) + }); + test('div many', () { + expect(evaluator.parse('100 / 2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('100 / 2 / 2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('100 / 2 / 2 / 5').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('100 / 2 / 2 / 5 / 5').value, null); // closeTo(0, epsilon) + }); + test('mul parse', () { + expect(parser.parse('1 / 2 / 3').value, [ + ['1', '/', '2'], + '/', + '3' + ]); + }); + test('pow', () { + expect(evaluator.parse('2 ^ 3').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('-2 ^ 3').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('-2 ^ -3').value, null); // closeTo(0, epsilon) + }); + test('pow many', () { + expect(evaluator.parse('4 ^ 3').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('4 ^ 3 ^ 2').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('4 ^ 3 ^ 2 ^ 1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('4 ^ 3 ^ 2 ^ 1 ^ 0').value, null); // closeTo(0, epsilon) + }); + test('pow parse', () { + expect(parser.parse('1 ^ 2 ^ 3').value, [ + '1', + '^', + ['2', '^', '3'] + ]); + }); + test('parens', () { + expect(evaluator.parse('(1)').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('(1 + 2)').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('((1))').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('((1 + 2))').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('2 * (3 + 4)').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('(2 + 3) * 4').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('6 / (2 + 4)').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('(2 + 6) / 2').value, null); // closeTo(0, epsilon) + }); + test('parens', () { + expect(parser.parse('(1)').value, ['(', '1', ')']); + expect(parser.parse('(1 + 2)').value, [ + '(', + ['1', '+', '2'], + ')' + ]); + expect(parser.parse('((1))').value, [ + '(', + ['(', '1', ')'], + ')' + ]); + expect(parser.parse('((1 + 2))').value, [ + '(', + [ + '(', + ['1', '+', '2'], + ')' + ], + ')' + ]); + expect(parser.parse('2 * (3 + 4)').value, [ + '2', + '*', + [ + '(', + ['3', '+', '4'], + ')' + ] + ]); + expect(parser.parse('(2 + 3) * 4').value, [ + [ + '(', + ['2', '+', '3'], + ')' + ], + '*', + '4' + ]); + expect(parser.parse('6 / (2 + 4)').value, [ + '6', + '/', + [ + '(', + ['2', '+', '4'], + ')' + ] + ]); + expect(parser.parse('(2 + 6) / 2').value, [ + [ + '(', + ['2', '+', '6'], + ')' + ], + '/', + '2' + ]); + }); + test('sqrt', () { + expect(evaluator.parse('sqrt(4)').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('sqrt(1 + 3)').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('1 + sqrt(16)').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('sqrt(sqrt(16))').value, null); // closeTo(0, epsilon) + }); + test('sqrt parse', () { + expect(parser.parse('sqrt(4)').value, ['sqrt(', '4', ')']); + expect(parser.parse('sqrt(1 + 3)').value, [ + 'sqrt(', + ['1', '+', '3'], + ')' + ]); + expect(parser.parse('1 + sqrt(16)').value, [ + '1', + '+', + ['sqrt(', '16', ')'] + ]); + expect(parser.parse('sqrt(sqrt(16))').value, [ + 'sqrt(', + ['sqrt(', '16', ')'], + ')' + ]); + }); + test('priority', () { + expect(evaluator.parse('2 * 3 + 4').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('2 + 3 * 4').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('6 / 3 + 4').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('2 + 6 / 2').value, null); // closeTo(0, epsilon) + }); + test('priority parse', () { + expect(parser.parse('2 * 3 + 4').value, [ + ['2', '*', '3'], + '+', + '4' + ]); + expect(parser.parse('2 + 3 * 4').value, [ + '2', + '+', + ['3', '*', '4'] + ]); + }); + test('postfix add', () { + expect(evaluator.parse('0++').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('0++++').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('0++++++').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('0+++1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('0+++++1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('0+++++++1').value, null); // closeTo(0, epsilon) + }); + test('postfix add parse', () { + expect(parser.parse('0++').value, ['0', '++']); + expect(parser.parse('0++++').value, [ + ['0', '++'], + '++' + ]); + expect(parser.parse('0++++++').value, [ + [ + ['0', '++'], + '++' + ], + '++' + ]); + expect(parser.parse('0+++1').value, [ + ['0', '++'], + '+', + '1' + ]); + expect(parser.parse('0+++++1').value, [ + [ + ['0', '++'], + '++' + ], + '+', + '1' + ]); + expect(parser.parse('0+++++++1').value, [ + [ + [ + ['0', '++'], + '++' + ], + '++' + ], + '+', + '1' + ]); + }); + test('postfix sub', () { + expect(evaluator.parse('1--').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('2----').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('3------').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('2---1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('3-----1').value, null); // closeTo(0, epsilon) + expect(evaluator.parse('4-------1').value, null); // closeTo(0, epsilon) + }); + test('postfix sub parse', () { + expect(parser.parse('0--').value, ['0', '--']); + expect(parser.parse('0----').value, [ + ['0', '--'], + '--' + ]); + expect(parser.parse('0------').value, [ + [ + ['0', '--'], + '--' + ], + '--' + ]); + expect(parser.parse('0---1').value, [ + ['0', '--'], + '-', + '1' + ]); + expect(parser.parse('0-----1').value, [ + [ + ['0', '--'], + '--' + ], + '-', + '1' + ]); + expect(parser.parse('0-------1').value, [ + [ + [ + ['0', '--'], + '--' + ], + '--' + ], + '-', + '1' + ]); + }); + test('negate', () { + expect(evaluator.parse('1').value, null); //closeTo(1, epsilon) + expect(evaluator.parse('-1').value, null); //closeTo(-1, epsilon) + expect(evaluator.parse('--1').value, null); //closeTo(1, epsilon) + expect(evaluator.parse('---1').value, null); //closeTo(-1, epsilon) + }); + test('negate parse', () { + expect(parser.parse('1').value, '1'); + expect(parser.parse('-1').value, ['-', '1']); + expect(parser.parse('--1').value, [ + '-', + ['-', '1'] + ]); + expect(parser.parse('---1').value, [ + '-', + [ + '-', + ['-', '1'] + ] + ]); + }); + test('linter', () { + expect(linter(parser), null); //isEmpty + expect(linter(evaluator), null); //isEmpty + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/function_list.dart b/ohos/lz_petitparser_test_os/lib/pages/function_list.dart new file mode 100644 index 0000000000000000000000000000000000000000..9c9ac40f12ed8a74e2b076bc7e3473fcbd294750 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/function_list.dart @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/material.dart'; +import '/pages/e_error_parser.dart'; +import '/pages/e_parser_acion.dart'; + +import 'e_and_parser.dart'; +import 'e_build_parser.dart'; +import 'e_extension_parser.dart'; +import 'e_lookahead.dart'; +import 'e_optimization.dart'; +import 'e_reuse_parser.dart'; +import 'e_sensitive.dart'; + +//, 组合解析器, 重用解析器, 扩展解析器, 错误处理,解析动作, 预测性解析, 上下文敏感解析, 解析优化 +class FunctionList extends StatelessWidget { + final functionList = ["构建解析器", "组合解析器", "重用解析器", "扩展解析器", "错误处理", "预测性解析", "上下文敏感解析"]; // + final pages = [ + EBuildParser(), + EAndParser(), + EReuseParser(), + EExtensionParser(), + EErrorParser(), + // EParserAction(), + ElookaheadParser(), + ESensitiveParser(), + // EOptimizationParser(), + ]; + + FunctionList({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('petitparser功能演示'), + ), + body: ListView.builder( + itemCount: functionList.length, + itemBuilder: (context, index) { + return GestureDetector( + onTap: () { + Navigator.push(context, MaterialPageRoute(builder: (_) { + return pages[index]; + })); + }, + child: ListTile( + title: Text(functionList[index]), + ), + ); + }, + ), + ); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/generated/sequence_test.dart b/ohos/lz_petitparser_test_os/lib/pages/generated/sequence_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..8602cde2a8174b746d6c6d711abad1c3240a546c --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/generated/sequence_test.dart @@ -0,0 +1,842 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../../common/test_page.dart'; +// import '../utils/assertions.dart'; +import '../utils/matchers.dart'; + +class SequenceTestPage extends TestPage { + SequenceTestPage(String title, {Key? key}) : super(title, key: key) { + group('seq2', () { + final parser = seq2(char('a'), char('b')); + final sequence = Sequence2('a', 'b'); + + test('success', () { + expect(parser, null); + expect(isParseSuccess(parser, 'ab'), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(parser, null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + expect(parser, null); + }); + }); + group('map2', () { + final parser = seq2(char('a'), char('b')).map2((a, b) => '$a$b'); + test('success', () { + expect(isParseSuccess(parser, 'ab*', position: 2), null); + expect(parser, null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(parser, null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(parser, null); + }); + }); + group('Sequence2', () { + final sequence = Sequence2('a', 'b'); + final other = Sequence2('b', 'a'); + test('accessors', () { + expect(sequence.first, 'a'); + expect(sequence.second, 'b'); + expect(sequence.last, 'b'); + }); + test('map', () { + expect(sequence.map((a, b) { + expect(a, 'a'); + expect(b, 'b'); + return 42; + }), 42); + }); + test('equals', () { + expect(sequence, sequence); + expect(sequence != other, null); + expect(other != sequence, null); + expect(other, other); + }); + test('hashCode', () { + expect(sequence.hashCode, sequence.hashCode); + expect(sequence.hashCode != other.hashCode, null); + expect(other.hashCode != sequence.hashCode, null); + expect(other.hashCode, other.hashCode); + }); + test('toString', () { + expect(sequence.toString().endsWith('(a, b)'), null); //endsWith('(a, b)') + expect(other.toString().endsWith('(b, a)'), null); //endsWith('(b, a)') + }); + }); + group('seq3', () { + final parser = seq3(char('a'), char('b'), char('c')); + final sequence = Sequence3('a', 'b', 'c'); + // //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abc'), null); + expect(parser, null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', message: '"a" expected', position: 0), null); + expect(parser, null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + }); + group('map3', () { + final parser = seq3(char('a'), char('b'), char('c')).map3((a, b, c) => '$a$b$c'); + // //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abc'), null); + expect(isParseSuccess(parser, 'abc*', position: 3), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + expect(parser, null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + }); + group('Sequence3', () { + final sequence = Sequence3('a', 'b', 'c'); + final other = Sequence3('c', 'b', 'a'); + test('accessors', () { + expect(sequence.first, 'a'); + expect(sequence.second, 'b'); + expect(sequence.third, 'c'); + expect(sequence.last, 'c'); + }); + test('map', () { + expect(sequence.map((a, b, c) { + expect(a, 'a'); + expect(b, 'b'); + expect(c, 'c'); + return 42; + }), 42); + }); + test('equals', () { + expect(sequence, sequence); + expect(sequence != other, null); + expect(other != sequence, null); + expect(other, other); + }); + test('hashCode', () { + expect(sequence.hashCode, sequence.hashCode); + expect(sequence.hashCode, null); + expect(other.hashCode, null); + expect(other.hashCode, other.hashCode); + }); + test('toString', () { + expect(sequence.toString().endsWith('(a, b, c)'), null); + expect(other.toString().endsWith('(c, b, a)'), null); + }); + }); + group('seq4', () { + final parser = seq4(char('a'), char('b'), char('c'), char('d')); + final sequence = Sequence4('a', 'b', 'c', 'd'); + // //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcd'), null); + expect(parser, null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + expect(parser, null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(parser, null); + }); + }); + group('map4', () { + final parser = seq4(char('a'), char('b'), char('c'), char('d')).map4((a, b, c, d) => '$a$b$c$d'); + // //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcd'), null); + expect(isParseSuccess(parser, 'abcd*', position: 4), null); + + expect(parser, null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + expect(parser, null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + expect(parser, null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + expect(parser, null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(parser, null); + }); + }); + group('Sequence4', () { + final sequence = Sequence4('a', 'b', 'c', 'd'); + final other = Sequence4('d', 'c', 'b', 'a'); + test('accessors', () { + expect(sequence.first, 'a'); + expect(sequence.second, 'b'); + expect(sequence.third, 'c'); + expect(sequence.fourth, 'd'); + expect(sequence.last, 'd'); + }); + test('map', () { + expect(sequence.map((a, b, c, d) { + expect(a, 'a'); + expect(b, 'b'); + expect(c, 'c'); + expect(d, 'd'); + return 42; + }), 42); + }); + test('equals', () { + expect(sequence, sequence); + expect(sequence != other, null); + expect(other != sequence, null); + expect(other, other); + }); + test('hashCode', () { + expect(sequence.hashCode, sequence.hashCode); + expect(sequence.hashCode != other.hashCode, null); + expect(other.hashCode != sequence.hashCode, null); + expect(other.hashCode, other.hashCode); + }); + test('toString', () { + expect(sequence.toString().endsWith('(a, b, c, d)'), null); + expect(other.toString().endsWith('(d, c, b, a)'), null); + }); + }); + group('seq5', () { + final parser = seq5(char('a'), char('b'), char('c'), char('d'), char('e')); + final sequence = Sequence5('a', 'b', 'c', 'd', 'e'); + // //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcde'), null); + expect(isParseSuccess(parser, 'abcde*', position: 5), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + expect(parser, null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(parser, null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + }); + group('map5', () { + final parser = seq5(char('a'), char('b'), char('c'), char('d'), char('e')).map5((a, b, c, d, e) => '$a$b$c$d$e'); + //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcde'), null); + expect(isParseSuccess(parser, 'abcde*', position: 5), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + }); + group('Sequence5', () { + final sequence = Sequence5('a', 'b', 'c', 'd', 'e'); + final other = Sequence5('e', 'd', 'c', 'b', 'a'); + test('accessors', () { + expect(sequence.first, 'a'); + expect(sequence.second, 'b'); + expect(sequence.third, 'c'); + expect(sequence.fourth, 'd'); + expect(sequence.fifth, 'e'); + expect(sequence.last, 'e'); + }); + test('map', () { + expect(sequence.map((a, b, c, d, e) { + expect(a, 'a'); + expect(b, 'b'); + expect(c, 'c'); + expect(d, 'd'); + expect(e, 'e'); + return 42; + }), 42); + }); + test('equals', () { + expect(sequence, sequence); + expect(sequence != other, null); + expect(other != sequence, null); + expect(other, other); + }); + test('hashCode', () { + expect(sequence.hashCode, sequence.hashCode); + expect(sequence.hashCode != other.hashCode, null); + expect(other.hashCode != sequence.hashCode, null); + expect(other.hashCode, other.hashCode); + }); + test('toString', () { + expect(sequence.toString().endsWith('(a, b, c, d, e)'), null); + expect(other.toString().endsWith('(e, d, c, b, a)'), null); + }); + }); + group('seq6', () { + final parser = seq6(char('a'), char('b'), char('c'), char('d'), char('e'), char('f')); + final sequence = Sequence6('a', 'b', 'c', 'd', 'e', 'f'); + //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcdef'), null); + expect(isParseSuccess(parser, 'abcdef*', position: 6), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + test('failure at 5', () { + expect(isParseFailure(parser, 'abcde', position: 5, message: '"f" expected'), null); + expect(isParseFailure(parser, 'abcde*', position: 5, message: '"f" expected'), null); + }); + }); + group('map6', () { + final parser = + seq6(char('a'), char('b'), char('c'), char('d'), char('e'), char('f')).map6((a, b, c, d, e, f) => '$a$b$c$d$e$f'); + //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcdef'), null); + expect(isParseSuccess(parser, 'abcdef*', position: 6), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + test('failure at 5', () { + expect(isParseFailure(parser, 'abcde', position: 5, message: '"f" expected'), null); + expect(isParseFailure(parser, 'abcde*', position: 5, message: '"f" expected'), null); + }); + }); + group('Sequence6', () { + final sequence = Sequence6('a', 'b', 'c', 'd', 'e', 'f'); + final other = Sequence6('f', 'e', 'd', 'c', 'b', 'a'); + test('accessors', () { + expect(sequence.first, 'a'); + expect(sequence.second, 'b'); + expect(sequence.third, 'c'); + expect(sequence.fourth, 'd'); + expect(sequence.fifth, 'e'); + expect(sequence.sixth, 'f'); + expect(sequence.last, 'f'); + }); + test('map', () { + expect(sequence.map((a, b, c, d, e, f) { + expect(a, 'a'); + expect(b, 'b'); + expect(c, 'c'); + expect(d, 'd'); + expect(e, 'e'); + expect(f, 'f'); + return 42; + }), 42); + }); + test('equals', () { + expect(sequence, sequence); + expect(sequence != other, null); + expect(other != sequence, null); + expect(other, other); + }); + test('hashCode', () { + expect(sequence.hashCode, sequence.hashCode); + expect(sequence.hashCode != other.hashCode, null); + expect(other.hashCode != sequence.hashCode, null); + expect(other.hashCode, other.hashCode); + }); + test('toString', () { + expect(sequence.toString().endsWith('(a, b, c, d, e, f)'), null); + expect(other.toString().endsWith('(f, e, d, c, b, a)'), null); + }); + }); + group('seq7', () { + final parser = seq7(char('a'), char('b'), char('c'), char('d'), char('e'), char('f'), char('g')); + final sequence = Sequence7('a', 'b', 'c', 'd', 'e', 'f', 'g'); + //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcdefg'), null); + expect(isParseSuccess(parser, 'abcdefg*', position: 7), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + test('failure at 5', () { + expect(isParseFailure(parser, 'abcde', position: 5, message: '"f" expected'), null); + expect(isParseFailure(parser, 'abcde*', position: 5, message: '"f" expected'), null); + }); + test('failure at 6', () { + expect(isParseFailure(parser, 'abcdef', position: 6, message: '"g" expected'), null); + expect(isParseFailure(parser, 'abcdef*', position: 6, message: '"g" expected'), null); + }); + }); + group('map7', () { + final parser = seq7(char('a'), char('b'), char('c'), char('d'), char('e'), char('f'), char('g')) + .map7((a, b, c, d, e, f, g) => '$a$b$c$d$e$f$g'); + //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcdefg'), null); + expect(isParseSuccess(parser, 'abcdefg*', position: 7), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + test('failure at 5', () { + expect(isParseFailure(parser, 'abcde', position: 5, message: '"f" expected'), null); + expect(isParseFailure(parser, 'abcde*', position: 5, message: '"f" expected'), null); + }); + test('failure at 6', () { + expect(isParseFailure(parser, 'abcdef', position: 6, message: '"g" expected'), null); + expect(isParseFailure(parser, 'abcdef*', position: 6, message: '"g" expected'), null); + }); + }); + group('Sequence7', () { + final sequence = Sequence7('a', 'b', 'c', 'd', 'e', 'f', 'g'); + final other = Sequence7('g', 'f', 'e', 'd', 'c', 'b', 'a'); + test('accessors', () { + expect(sequence.first, 'a'); + expect(sequence.second, 'b'); + expect(sequence.third, 'c'); + expect(sequence.fourth, 'd'); + expect(sequence.fifth, 'e'); + expect(sequence.sixth, 'f'); + expect(sequence.seventh, 'g'); + expect(sequence.last, 'g'); + }); + test('map', () { + expect(sequence.map((a, b, c, d, e, f, g) { + expect(a, 'a'); + expect(b, 'b'); + expect(c, 'c'); + expect(d, 'd'); + expect(e, 'e'); + expect(f, 'f'); + expect(g, 'g'); + return 42; + }), 42); + }); + test('equals', () { + expect(sequence, sequence); + expect(sequence != other, null); + expect(other != sequence, null); + expect(other, other); + }); + test('hashCode', () { + expect(sequence.hashCode, sequence.hashCode); + expect(sequence.hashCode != other.hashCode, null); + expect(other.hashCode != sequence.hashCode, null); + expect(other.hashCode, other.hashCode); + }); + test('toString', () { + expect(sequence.toString().endsWith('(a, b, c, d, e, f, g)'), null); + expect(other.toString().endsWith('(g, f, e, d, c, b, a)'), null); + }); + }); + group('seq8', () { + final parser = seq8(char('a'), char('b'), char('c'), char('d'), char('e'), char('f'), char('g'), char('h')); + final sequence = Sequence8('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'); + //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcdefgh'), null); + expect(isParseSuccess(parser, 'abcdefgh*', position: 8), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + test('failure at 5', () { + expect(isParseFailure(parser, 'abcde', position: 5, message: '"f" expected'), null); + expect(isParseFailure(parser, 'abcde*', position: 5, message: '"f" expected'), null); + }); + test('failure at 6', () { + expect(isParseFailure(parser, 'abcdef', position: 6, message: '"g" expected'), null); + expect(isParseFailure(parser, 'abcdef*', position: 6, message: '"g" expected'), null); + }); + test('failure at 7', () { + expect(isParseFailure(parser, 'abcdefg', position: 7, message: '"h" expected'), null); + expect(isParseFailure(parser, 'abcdefg*', position: 7, message: '"h" expected'), null); + }); + }); + group('map8', () { + final parser = seq8(char('a'), char('b'), char('c'), char('d'), char('e'), char('f'), char('g'), char('h')) + .map8((a, b, c, d, e, f, g, h) => '$a$b$c$d$e$f$g$h'); + //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcdefgh'), null); + expect(isParseSuccess(parser, 'abcdefgh*', position: 8), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + test('failure at 5', () { + expect(isParseFailure(parser, 'abcde', position: 5, message: '"f" expected'), null); + expect(isParseFailure(parser, 'abcde*', position: 5, message: '"f" expected'), null); + }); + test('failure at 6', () { + expect(isParseFailure(parser, 'abcdef', position: 6, message: '"g" expected'), null); + expect(isParseFailure(parser, 'abcdef*', position: 6, message: '"g" expected'), null); + }); + test('failure at 7', () { + expect(isParseFailure(parser, 'abcdefg', position: 7, message: '"h" expected'), null); + expect(isParseFailure(parser, 'abcdefg*', position: 7, message: '"h" expected'), null); + }); + }); + group('Sequence8', () { + final sequence = Sequence8('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'); + final other = Sequence8('h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'); + test('accessors', () { + expect(sequence.first, 'a'); + expect(sequence.second, 'b'); + expect(sequence.third, 'c'); + expect(sequence.fourth, 'd'); + expect(sequence.fifth, 'e'); + expect(sequence.sixth, 'f'); + expect(sequence.seventh, 'g'); + expect(sequence.eighth, 'h'); + expect(sequence.last, 'h'); + }); + test('map', () { + expect(sequence.map((a, b, c, d, e, f, g, h) { + expect(a, 'a'); + expect(b, 'b'); + expect(c, 'c'); + expect(d, 'd'); + expect(e, 'e'); + expect(f, 'f'); + expect(g, 'g'); + expect(h, 'h'); + return 42; + }), 42); + }); + test('equals', () { + expect(sequence, sequence); + expect(sequence != other, null); + expect(other != sequence, null); + expect(other, other); + }); + test('hashCode', () { + expect(sequence.hashCode, sequence.hashCode); + expect(sequence.hashCode != other.hashCode, null); + expect(other.hashCode != sequence.hashCode, null); + expect(other.hashCode, other.hashCode); + }); + test('toString', () { + expect(sequence.toString(), null); + expect(other.toString().endsWith('(h, g, f, e, d, c, b, a)'), null); + }); + }); + group('seq9', () { + final parser = seq9(char('a'), char('b'), char('c'), char('d'), char('e'), char('f'), char('g'), char('h'), char('i')); + final sequence = Sequence9('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'); + //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcdefghi'), null); + expect(isParseSuccess(parser, 'abcdefghi*', position: 9), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + test('failure at 5', () { + expect(isParseFailure(parser, 'abcde', position: 5, message: '"f" expected'), null); + expect(isParseFailure(parser, 'abcde*', position: 5, message: '"f" expected'), null); + }); + test('failure at 6', () { + expect(isParseFailure(parser, 'abcdef', position: 6, message: '"g" expected'), null); + expect(isParseFailure(parser, 'abcdef*', position: 6, message: '"g" expected'), null); + }); + test('failure at 7', () { + expect(isParseFailure(parser, 'abcdefg', position: 7, message: '"h" expected'), null); + expect(isParseFailure(parser, 'abcdefg*', position: 7, message: '"h" expected'), null); + }); + test('failure at 8', () { + expect(isParseFailure(parser, 'abcdefgh', position: 8, message: '"i" expected'), null); + expect(isParseFailure(parser, 'abcdefgh*', position: 8, message: '"i" expected'), null); + }); + }); + group('map9', () { + final parser = seq9(char('a'), char('b'), char('c'), char('d'), char('e'), char('f'), char('g'), char('h'), char('i')) + .map9((a, b, c, d, e, f, g, h, i) => '$a$b$c$d$e$f$g$h$i'); + //expectParserInvariants(parser); + test('success', () { + expect(isParseSuccess(parser, 'abcdefghi'), null); + expect(isParseSuccess(parser, 'abcdefghi*', position: 9), null); + }); + test('failure at 0', () { + expect(isParseFailure(parser, '', position: 0, message: '"a" expected'), null); + expect(isParseFailure(parser, '*', position: 0, message: '"a" expected'), null); + }); + test('failure at 1', () { + expect(isParseFailure(parser, 'a', position: 1, message: '"b" expected'), null); + expect(isParseFailure(parser, 'a*', position: 1, message: '"b" expected'), null); + }); + test('failure at 2', () { + expect(isParseFailure(parser, 'ab', position: 2, message: '"c" expected'), null); + expect(isParseFailure(parser, 'ab*', position: 2, message: '"c" expected'), null); + }); + test('failure at 3', () { + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + expect(isParseFailure(parser, 'abc*', position: 3, message: '"d" expected'), null); + }); + test('failure at 4', () { + expect(isParseFailure(parser, 'abcd', position: 4, message: '"e" expected'), null); + expect(isParseFailure(parser, 'abcd*', position: 4, message: '"e" expected'), null); + }); + test('failure at 5', () { + expect(isParseFailure(parser, 'abcde', position: 5, message: '"f" expected'), null); + expect(isParseFailure(parser, 'abcde*', position: 5, message: '"f" expected'), null); + }); + test('failure at 6', () { + expect(isParseFailure(parser, 'abcdef', position: 6, message: '"g" expected'), null); + expect(isParseFailure(parser, 'abcdef*', position: 6, message: '"g" expected'), null); + }); + test('failure at 7', () { + expect(isParseFailure(parser, 'abcdefg', position: 7, message: '"h" expected'), null); + expect(isParseFailure(parser, 'abcdefg*', position: 7, message: '"h" expected'), null); + }); + test('failure at 8', () { + expect(isParseFailure(parser, 'abcdefgh', position: 8, message: '"i" expected'), null); + expect(isParseFailure(parser, 'abcdefgh*', position: 8, message: '"i" expected'), null); + }); + }); + group('Sequence9', () { + final sequence = Sequence9('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'); + final other = Sequence9('i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'); + test('accessors', () { + expect(sequence.first, 'a'); + expect(sequence.second, 'b'); + expect(sequence.third, 'c'); + expect(sequence.fourth, 'd'); + expect(sequence.fifth, 'e'); + expect(sequence.sixth, 'f'); + expect(sequence.seventh, 'g'); + expect(sequence.eighth, 'h'); + expect(sequence.ninth, 'i'); + expect(sequence.last, 'i'); + }); + test('map', () { + expect(sequence.map((a, b, c, d, e, f, g, h, i) { + expect(a, 'a'); + expect(b, 'b'); + expect(c, 'c'); + expect(d, 'd'); + expect(e, 'e'); + expect(f, 'f'); + expect(g, 'g'); + expect(h, 'h'); + expect(i, 'i'); + return 42; + }), 42); + }); + test('equals', () { + expect(sequence, sequence); + expect(sequence != other, null); + expect(other != sequence, null); + expect(other, other); + }); + test('hashCode', () { + expect(sequence.hashCode, sequence.hashCode); + expect(sequence.hashCode != other.hashCode, null); + expect(other.hashCode != sequence.hashCode, null); + expect(other.hashCode, other.hashCode); + }); + test('toString', () { + expect(sequence.toString(), null); + expect(other.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/indent_test.dart b/ohos/lz_petitparser_test_os/lib/pages/indent_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..59e169da408667c40c56062c19fffb96ccc60532 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/indent_test.dart @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/core.dart'; +import 'package:petitparser/definition.dart'; +import 'package:petitparser/indent.dart'; +import 'package:petitparser/parser.dart'; +// import 'package:test/test.dart'; + +import '../common/test_page.dart'; +// import 'utils/matchers.dart'; + +class IndentList extends GrammarDefinition { + final indent = Indent(); + + @override + Parser start() => [ + ref0(newlines).optional(), + ref0(things), + ref0(newlines).optional(), + endOfInput(), + ].toSequenceParser().pick(1); + + Parser things() => [ + indent.same, + ref0(object) | ref0(line), + ].toSequenceParser().pick(1).star(); + + Parser object() => [ + ref0(key), + ref0(block) | ref0(inline), + ].toSequenceParser().map((values) => {values[0]: values[1]}); + + Parser key() => [ + pattern('^ \t\r\n:').plus().flatten(), + indent.parser.star(), + char(':'), + indent.parser.star(), + ].toSequenceParser().pick(0); + + Parser block() => [ + ref0(newlines), + indent.increase, + ref0(things), + indent.decrease, + ].toSequenceParser().pick(2); + + Parser inline() => ref0(line).map((value) => [value]); + + Parser line() => [ + ref0(newline).neg().plus().flatten(), + ref0(newlines).optional(), + ].toSequenceParser().pick(0); + + Parser newline() => Token.newlineParser(); + + Parser newlines() => [ + indent.parser.star(), + ref0(newline), + ].toSequenceParser().plus(); +} + +class IndentTestPage extends TestPage { + IndentTestPage(String title, {Key? key}) : super(title, key: key) { + group('definition', () { + final definition = IndentList(); + final parser = definition.build(); + + expect(definition.indent.stack, null); //isEmpty + expect(definition.indent.current, ''); + test('empty', () { + expect(parser, null); + expect(parser, null); + expect(parser, null); + + expect(parser, null); + expect(parser, null); + expect(parser, null); + + expect(parser, null); + expect(parser, null); + expect(parser, null); + }); + test('newline before', () { + expect(parser, null); + expect(parser, null); + expect(parser, null); + + expect(parser, null); + expect(parser, null); + expect(parser, null); + }); + test('newline after', () { + expect(parser, null); + expect(parser, null); + expect(parser, null); + + expect(parser, null); + expect(parser, null); + expect(parser, null); + }); + test('single indent', () { + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + }); + test('same indent', () { + expect(parser, null); + expect(parser, null); + expect(parser, null); + expect(parser, null); + }); + test('different indent', () { + expect(parser, null); + expect(parser, null); + }); + test('missing indent', () { + expect(parser, null); + }); + test('unexpected indent', () { + expect(parser, null); + }); + test('same level', () { + expect(parser, null); + // expect(parser, isParseSuccess('a\nb\nc', ['a', 'b', 'c'])); + }); + test('inlined values', () { + expect(parser, null); + // expect( + // parser, + // isParseSuccess('a:1\nb: 2\nc :3', [ + // { + // 'a': ['1'] + // }, + // { + // 'b': ['2'] + // }, + // { + // 'c': ['3'] + // } + // ])); + }); + test('increasing', () { + expect(parser, null); + // expect( + // parser, + // isParseSuccess('a:\n b:\n c', [ + // { + // 'a': [ + // { + // 'b': ['c'] + // } + // ] + // } + // ])); + }); + test('decreasing', () { + expect(parser, null); + // expect( + // parser, + // isParseSuccess('a:\n\tb\nc', [ + // { + // 'a': ['b'] + // }, + // 'c' + // ])); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/matcher_test.dart b/ohos/lz_petitparser_test_os/lib/pages/matcher_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a0bc829f4c05345a7e93b3dbc97653f50a1835e6 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/matcher_test.dart @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; + +class MatcherTestPage extends TestPage { + MatcherTestPage(String title, {Key? key}) : super(title, key: key) { + test('parse()', () { + final parser = char('a'); + expect(parser.parse('a').isSuccess, null); + expect(parser.parse('b').isSuccess, null); + }); + test('accept()', () { + final parser = char('a'); + expect(parser.accept('a'), null); + expect(parser.accept('b'), null); + }); + group('matches', () { + const input = 'a123b456'; + final parser = digit().repeat(2, 2).flatten(); + test('matches()', () { + // ignore: deprecated_member_use_from_same_package + expect(parser.matches(input), ['12', '23', '45', '56']); + }); + test('matchesSkipping()', () { + // ignore: deprecated_member_use_from_same_package + expect(parser.matchesSkipping(input), ['12', '45']); + }); + group('allMatches', () { + final parser = digit().seq(digit()).flatten(); + test('allMatches()', () { + expect(parser.allMatches(input), ['12', '45']); + }); + test('allMatches(start: 3)', () { + expect(parser.allMatches(input, start: 3), ['45']); + }); + test('allMatches(overlapping: true)', () { + expect(parser.allMatches(input, overlapping: true), ['12', '23', '45', '56']); + }); + test('allMatches(start: 3, overlapping: true)', () { + expect(parser.allMatches(input, start: 3, overlapping: true), ['45', '56']); + }); + }); + }); + group('pattern', () { + const input = 'a123b45'; + final pattern = digit().seq(digit()).toPattern(); + test('allMatches()', () { + final matches = pattern.allMatches(input); + expect(matches.map((matcher) => matcher.pattern), [pattern, pattern]); + expect(matches.map((matcher) => matcher.input), [input, input]); + expect(matches.map((matcher) => matcher.start), [1, 5]); + expect(matches.map((matcher) => matcher.end), [3, 7]); + expect(matches.map((matcher) => matcher.groupCount), [0, 0]); + expect(matches.map((matcher) => matcher[0]), ['12', '45']); + expect(matches.map((matcher) => matcher.group(0)), ['12', '45']); + expect(matches.map((matcher) => matcher.groups([0, 1])), [ + ['12', null], + ['45', null], + ]); + }); + test('allMatches() (empty match)', () { + final pattern = digit().star().toPattern(); + final matches = pattern.allMatches(input); + expect(matches.map((matcher) => matcher[0]), ['', '123', '', '45', '']); + }); + test('matchAsPrefix()', () { + final match1 = pattern.matchAsPrefix(input); + expect(match1, null); + final match2 = pattern.matchAsPrefix(input, 2)!; + expect(match2.pattern, pattern); + expect(match2.input, input); + expect(match2.start, 2); + expect(match2.end, 4); + expect(match2.groupCount, 0); + expect(match2[0], '23'); + expect(match2.group(0), '23'); + expect(match2.groups([0, 1]), ['23', null]); + }); + test('startsWith()', () { + expect(input.startsWith(pattern), null); + expect(input.startsWith(pattern, 1), null); + expect(input.startsWith(pattern, 2), null); + expect(input.startsWith(pattern, 3), null); + }); + test('indexOf()', () { + expect(input.indexOf(pattern), 1); + expect(input.indexOf(pattern), 1); + expect(input.indexOf(pattern, 1), 1); + expect(input.indexOf(pattern, 2), 2); + expect(input.indexOf(pattern, 3), 5); + }); + test('lastIndexOf()', () { + expect(input.lastIndexOf(pattern), 5); + expect(input.lastIndexOf(pattern, 0), -1); + expect(input.lastIndexOf(pattern, 1), 1); + expect(input.lastIndexOf(pattern, 2), 2); + expect(input.lastIndexOf(pattern, 3), 2); + }); + test('contains()', () { + expect(input.contains(pattern), null); + }); + test('replaceFirst()', () { + expect(input.replaceFirst(pattern, '!'), 'a!3b45'); + }); + test('replaceFirstMapped()', () { + expect(input.replaceFirstMapped(pattern, (match) => '!${match[0]}!'), 'a!12!3b45'); + }); + test('replaceAll()', () { + expect(input.replaceAll(pattern, '!'), 'a!3b!'); + }); + test('replaceAllMapped()', () { + expect(input.replaceAllMapped(pattern, (match) => '!${match[0]}!'), 'a!12!3b!45!'); + }); + test('split()', () { + expect(input.split(pattern), ['a', '3b', '']); + }); + test('splitMapJoin()', () { + expect(input.splitMapJoin(pattern, onMatch: (match) => '!${match[0]}!', onNonMatch: (nonMatch) => '?$nonMatch?'), + '?a?!12!?3b?!45!??'); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/parser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/parser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..d9c5e509ff9eebc1c42a6caf70786c9073d91df8 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/parser_test.dart @@ -0,0 +1,1002 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +// import 'generated/sequence_test.dart' as sequence_test; +// import 'utils/assertions.dart'; +import 'utils/matchers.dart'; + +class ParsetTestPage extends TestPage { + ParsetTestPage(String title, {Key? key}) : super(title, key: key) { + group('action', () { + group('cast', () { + test('default', () { + final parser = digit().map(int.parse).cast(); + expect(parser, null); + }); + }); + group('castList', () { + test('default', () { + final parser = digit().map(int.parse).repeat(3).castList(); + expect(parser, null); + }); + }); + group('callCC', () { + test('delegation', () { + final parser = digit().callCC((continuation, context) => continuation(context)); + expect(parser, null); + }); + test('diversion', () { + final parser = digit().callCC((continuation, context) => letter().parseOn(context)); + expect(parser, null); + }); + test('resume', () { + final continuations = []; + final contexts = []; + final parser = digit().callCC((continuation, context) { + continuations.add(continuation); + contexts.add(context); + // we have to return something for now + return context.failure('Abort'); + }); + // execute the parser twice to collect the continuations + expect(parser.parse('1').isSuccess, null); //isFalse + expect(parser.parse('a').isSuccess, null); //isFalse + // later we can execute the captured continuations + expect(continuations[0](contexts[0]).isSuccess, null); //isTrue + expect(continuations[1](contexts[1]).isSuccess, null); //isFalse + // of course the continuations can be resumed multiple times + expect(continuations[0](contexts[0]).isSuccess, null); //isTrue + expect(continuations[1](contexts[1]).isSuccess, null); //isFalse + }); + test('success', () { + final parser = digit().callCC((continuation, context) => context.success('success')); + expect(parser, null); + }); + test('failure', () { + final parser = digit().callCC((continuation, context) => context.failure('failure')); + expect(parser, null); + }); + }); + group('flatten', () { + // expectParserInvariants(any().flatten()); + test('default', () { + final parser = digit().repeat(2, unbounded).flatten(); + expect(parser, null); + }); + test('with message', () { + final parser = digit().repeat(2, unbounded).flatten('gimme a number'); + expect(parser, null); + }); + }); + group('where', () { + test('default', () { + final parser = any().where((value) => value == '*'); + expect(parser, null); + }); + test('with failure message', () { + final parser = digit() + .plus() + .flatten() + .map(int.parse) + .where((value) => value % 7 == 0, failureMessage: (value) => '$value is not divisible by 7'); + expect(parser, null); + }); + test('with failure position', () { + final inner = any() & any(); + final parser = inner.where((value) => value[0] == value[1], failurePosition: (tokens) => 1); + expect(parser, null); + }); + test('with failure message and position', () { + final inner = any() & any(); + final parser = inner.where((list) => list[0] == list[1], + failureMessage: (list) => '${list[0]} != ${list[1]}', failurePosition: (list) => 1); + expect(parser, null); + }); + }); + group('map', () { + test('default', () { + final parser = digit().map((each) => each.codeUnitAt(0) - '0'.codeUnitAt(0)); + expect(parser, null); + }); + }); + group('permute', () { + test('from start', () { + final parser = digit().seq(letter()).permute([1, 0]); + expect(parser, null); + }); + test('from end', () { + final parser = digit().seq(letter()).permute([-1, 0]); + expect(parser, null); + }); + test('repeated', () { + final parser = digit().seq(letter()).permute([1, 1]); + expect(parser, null); + }); + }); + group('pick', () { + test('from start', () { + final parser = digit().seq(letter()).pick(1); + expect(parser, null); + }); + test('from end', () { + final parser = digit().seq(letter()).pick(-1); + expect(parser, null); + }); + }); + group('token', () { + test('default', () { + final parser = digit().plus().token(); + expect(parser, null); + final token = parser.parse('123').value; + expect(token.value, ['1', '2', '3']); + expect(token.buffer, '123'); + expect(token.start, 0); + expect(token.stop, 3); + expect(token.input, '123'); + expect(token.length, 3); + expect(token.line, 1); + expect(token.column, 1); + expect(token.toString(), 'Token[1:1]: [1, 2, 3]'); + }); + const buffer = '1\r12\r\n123\n1234'; + final parser = any().map((value) => value.codeUnitAt(0)).token().star(); + final result = parser.parse(buffer).value; + test('value', () { + final expected = [49, 13, 49, 50, 13, 10, 49, 50, 51, 10, 49, 50, 51, 52]; + expect(result.map((token) => token.value), expected); + }); + test('buffer', () { + final expected = List.filled(buffer.length, buffer); + expect(result.map((token) => token.buffer), expected); + }); + test('start', () { + final expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + expect(result.map((token) => token.start), expected); + }); + test('stop', () { + final expected = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]; + expect(result.map((token) => token.stop), expected); + }); + test('length', () { + final expected = List.filled(buffer.length, 1); + expect(result.map((token) => token.length), expected); + }); + test('line', () { + final expected = [1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]; + expect(result.map((token) => token.line), expected); + }); + test('column', () { + final expected = [1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; + expect(result.map((token) => token.column), expected); + }); + test('input', () { + final expected = ['1', '\r', '1', '2', '\r', '\n', '1', '2', '3', '\n', '1', '2', '3', '4']; + expect(result.map((token) => token.input), expected); + }); + test('map', () { + final expected = ['49', '13', '49', '50', '13', '10', '49', '50', '51', '10', '49', '50', '51', '52']; + expect(result.map((token) => token.map((value) => value.toString())).map((token) => token.value), expected); + }); + group('join', () { + test('normal', () { + final joined = Token.join(result); + expect(joined, null); + }); + test('reverse order', () { + final joined = Token.join(result.reversed); + expect(joined, null); + }); + test('empty, 此处应该为X', () { + Token.join([]); + // expect(() => Token.join([]), throwsArgumentError); + }); + test('different buffer, 此处应该为X', () { + const token = [Token(12, '12', 0, 2), Token(32, '32', 0, 2)]; + Token.join(token); + // expect(() => Token.join(token), throwsArgumentError); + }); + }); + test('unique', () { + expect({...result}.length, result.length); + }); + test('equals', () { + for (var i = 0; i < result.length; i++) { + for (var j = 0; j < 1; j++) { + final condition = i == j ? true : false; + expect(result[i] == result[j], condition); + expect(result[i].hashCode == result[j].hashCode, condition); + } + } + }); + }); + group('trim', () { + test('default', () { + final parser = char('a').trim(); + expect(parser, null); + }); + test('custom both', () { + final parser = char('a').trim(char('*')); + expect(parser, null); + }); + test('custom left and right', () { + final parser = char('a').trim(char('*'), char('#')); + expect(parser, null); + }); + }); + }); + group('character', () { + group('anyOf', () { + final parser = anyOf('uncopyrightable'); + test('default', () { + expect(parser, null); + }); + }); + group('noneOf', () { + final parser = noneOf('uncopyrightable'); + test('default', () { + expect(parser, null); + }); + }); + group('char', () { + test('with string', () { + final parser = char('a'); + expect(parser, null); + }); + test('with message', () { + final parser = char('a', 'lowercase a'); + expect(parser, null); + }); + test('char invalid, 此处应该为X', () { + char('ab'); + // expect(() => char('ab'), throwsArgumentError); + }); + { + '\\x00': '\x00', + '\\b': '\b', + '\\t': '\t', + '\\n': '\n', + '\\v': '\v', + '\\f': '\f', + '\\r': '\r', + '\\"': '"', + "\\'": "'", + '\\\\': '\\', + '☠': '\u2620', + ' ': ' ', + }.forEach((key, value) { + test('char("$key")', () { + final parser = char(value); + expect(parser, null); + }); + }); + }); + group('charIgnoringCase', () { + test('with lowercase string', () { + final parser = charIgnoringCase('a'); + expect(parser, null); + }); + test('with uppercase string', () { + final parser = charIgnoringCase('A'); + expect(parser, null); + }); + test('with custom message', () { + final parser = charIgnoringCase('a', 'upper or lower'); + expect(parser, null); + }); + test('with single char', () { + final parser = charIgnoringCase('1'); + expect(parser, null); + }); + test('char invalid, 此处应该为X', () { + charIgnoringCase('ab'); + // expect(() => charIgnoringCase('ab'), throwsArgumentError); + }); + }); + group('digit', () { + final parser = digit(); + // expectParserInvariants(parser); + test('default', () { + expect(parser, null); + }); + }); + group('letter', () { + final parser = letter(); + test('default', () { + expect(parser, null); + }); + }); + group('lowercase', () { + final parser = lowercase(); + test('default', () { + expect(parser, null); + }); + }); + group('pattern', () { + test('with single', () { + final parser = pattern('abc'); + expect(parser, null); + }); + test('with range', () { + final parser = pattern('a-c'); + expect(parser, null); + }); + test('with overlapping range', () { + final parser = pattern('b-da-c'); + expect(parser, null); + }); + test('with adjacent range', () { + final parser = pattern('c-ea-c'); + expect(parser, null); + }); + test('with prefix range', () { + final parser = pattern('a-ea-c'); + expect(parser, null); + }); + test('with postfix range', () { + final parser = pattern('a-ec-e'); + expect(parser, null); + }); + test('with repeated range', () { + final parser = pattern('a-ea-e'); + expect(parser, null); + }); + test('with composed range', () { + final parser = pattern('ac-df-'); + expect(parser, null); + }); + test('with negated single', () { + final parser = pattern('^a'); + expect(parser, null); + }); + test('with negated range', () { + final parser = pattern('^a-c'); + expect(parser, null); + }); + test('with negate but without range', () { + final parser = pattern('^a-'); + expect(parser, null); + }); + test('with error, 此处应该为X', () { + pattern('c-a'); + // expect(() => pattern('c-a'), throwsArgumentError); + }); + group('ignore case', () { + // expectParserInvariants(patternIgnoreCase('^ad-f')); + test('with single', () { + final parser = patternIgnoreCase('abc'); + expect(parser, null); + }); + test('with range', () { + final parser = patternIgnoreCase('a-c'); + expect(parser, null); + }); + test('with overlapping range', () { + final parser = patternIgnoreCase('b-da-c'); + expect(parser, null); + }); + test('with adjacent range', () { + final parser = patternIgnoreCase('c-ea-c'); + expect(parser, null); + }); + test('with prefix range', () { + final parser = patternIgnoreCase('a-ea-c'); + expect(parser, null); + }); + test('with postfix range', () { + final parser = patternIgnoreCase('a-ec-e'); + expect(parser, null); + }); + test('with repeated range', () { + final parser = patternIgnoreCase('a-ea-e'); + expect(parser, null); + }); + test('with composed range', () { + final parser = patternIgnoreCase('ac-df-'); + expect(parser, null); + }); + test('with negated single', () { + final parser = patternIgnoreCase('^a'); + expect(parser, null); + }); + test('with negated range', () { + final parser = patternIgnoreCase('^a-c'); + expect(parser, null); + }); + test('with negate but without range', () { + final parser = patternIgnoreCase('^a-'); + expect(parser, null); + }); + test('with error, 此处应该为X', () { + patternIgnoreCase('c-a'); + // expect(() => patternIgnoreCase('c-a'), throwsArgumentError); + }); + }); + group('large ranges', () { + final parser = pattern('\u2200-\u22ff\u27c0-\u27ef\u2980-\u29ff'); + test('mathematical symbols', () { + expect(parser, null); + }); + }); + group('without anything', () { + final parser = pattern(''); + test('test', () { + for (var i = 0; i <= 1; i++) { + final character = String.fromCharCode(i); + expect(parser, null); + } + }); + }); + group('with everything', () { + final parser = pattern('\x00-\uffff'); + test('test', () { + for (var i = 0; i <= 1; i++) { + final character = String.fromCharCode(i); + expect(parser, null); + } + }); + }); + }); + group('range', () { + final parser = range('e', 'o'); + test('default', () { + expect(parser, null); + }); + test('invalid, 此处应该为X', () { + range('o', 'e'); + // expect(() => range('o', 'e'), throwsArgumentError); + }); + }); + group('uppercase', () { + final parser = uppercase(); + test('default', () { + expect(parser, null); + }); + }); + group('whitespace', () { + final parser = whitespace(); + test('default', () { + expect(parser, null); + }); + test('unicode', () { + final whitespace = { + 9, + 10, + 11, + 12, + 13, + 32, + 133, + 160, + 5760, + 8192, + 8193, + 8194, + 8195, + 8196, + 8197, + 8198, + 8199, + 8200, + 8201, + 8202, + 8232, + 8233, + 8239, + 8287, + 12288, + 65279 + }; + for (var i = 0; i < 1; i++) { + var character = String.fromCharCode(i); + expect(parser, null); + } + }); + }); + group('word', () { + final parser = word(); + test('default', () { + expect(parser, null); + }); + }); + }); + group('combinator', () { + group('and', () { + test('default', () { + final parser = char('a').and(); + expect(parser, null); + }); + }); + group('choice', () { + test('operator', () { + final parser = char('a') | char('b'); + expect(parser, null); + }); + test('converter', () { + final parser = [char('a'), char('b')].toChoiceParser(); + expect(parser, null); + }); + test('two', () { + final parser = char('a').or(char('b')); + expect(parser, null); + }); + test('three', () { + final parser = char('a').or(char('b')).or(char('c')); + expect(parser, isParseSuccess(parser, 'a')); + }); + test('empty, 此处应该为X', () { + [].toChoiceParser(); + // expect(() => [].toChoiceParser(), throwsArgumentError); + }); + group('types', () { + test('same', () { + final first = any(); + final second = any(); + expect(first is Parser, null); + // expect(first, isA>()); + + expect(second is Parser, null); + // expect(second, isA>()); + + expect(ChoiceParser([first, second]) is Parser, null); + // expect(ChoiceParser([first, second]), isA>()); + + expect([first, second].toChoiceParser() is Parser, null); + // expect([first, second].toChoiceParser(), isA>()); + // TODO(renggli): https://github.com/dart-lang/language/issues/1557 + // expect(first | second, isA>()); + // expect(first.or(second), isA>()); + }); + test('ChoiceParser(Iterable> children, {FailureJoiner? failureJoiner})', () { + final first = any().map(int.parse); + final second = any().map(double.parse); + expect(first is Parser, null); + // expect(first, isA>()); + + expect(second is Parser, null); + // expect(second, isA>()); + + expect(ChoiceParser([first, second]) is Parser, null); + // expect(ChoiceParser([first, second]), isA>()); + + expect([first, second].toChoiceParser() is Parser, null); + // expect([first, second].toChoiceParser(), isA>()); + // TODO(renggli): https://github.com/dart-lang/language/issues/1557 + // expect(first | second, isA>()); + // expect(first.or(second), isA>()); + }); + }); + group('failure joining', () { + const failureA0 = Failure('A0', 0, 'A0'); + const failureA1 = Failure('A1', 1, 'A1'); + const failureB0 = Failure('B0', 0, 'B0'); + const failureB1 = Failure('B1', 1, 'B1'); + final parsers = [ + anyOf('ab').plus() & anyOf('12').plus(), + anyOf('ac').plus() & anyOf('13').plus(), + anyOf('ad').plus() & anyOf('14').plus(), + ].map((parser) => parser.flatten()); + test('construction', () { + final defaultTwo = any().or(any()); + expect(defaultTwo.failureJoiner(failureA1, failureA0), failureA0); + final customTwo = any().or(any(), failureJoiner: selectFarthest); + expect(customTwo.failureJoiner(failureA1, failureA0), failureA1); + final customCopy = customTwo.copy(); + expect(customCopy.failureJoiner(failureA1, failureA0), failureA1); + final customThree = any().or(any(), failureJoiner: selectFarthest).or(any()); + expect(customThree.failureJoiner(failureA1, failureA0), failureA1); + }); + test('select first', () { + final parser = parsers.toChoiceParser(failureJoiner: selectFirst); + expect(selectFirst(failureA0, failureB0), failureA0); + expect(selectFirst(failureB0, failureA0), failureB0); + expect(parser, null); + }); + test('select last', () { + final parser = parsers.toChoiceParser(failureJoiner: selectLast); + expect(selectLast(failureA0, failureB0), failureB0); + expect(selectLast(failureB0, failureA0), failureA0); + expect(parser, null); + }); + test('farthest failure', () { + final parser = parsers.toChoiceParser(failureJoiner: selectFarthest); + expect(selectFarthest(failureA0, failureB0), failureB0); + expect(selectFarthest(failureA0, failureB1), failureB1); + expect(selectFarthest(failureB0, failureA0), failureA0); + expect(selectFarthest(failureB1, failureA0), failureB1); + expect(parser, null); + }); + test('farthest failure and joined', () { + final parser = parsers.toChoiceParser(failureJoiner: selectFarthestJoined); + expect(selectFarthestJoined(failureA0, failureB1), failureB1); + expect(selectFarthestJoined(failureB1, failureA0), failureB1); + expect(selectFarthestJoined(failureA0, failureB0).message, 'A0 OR B0'); + expect(selectFarthestJoined(failureB0, failureA0).message, 'B0 OR A0'); + expect(selectFarthestJoined(failureA1, failureB1).message, 'A1 OR B1'); + expect(selectFarthestJoined(failureB1, failureA1).message, 'B1 OR A1'); + expect(parser, null); + }); + }); + }); + group('not', () { + test('default', () { + final parser = char('a').not('not "a" expected'); + isParseFailure(parser, 'a', message: 'not "a" expected'); + }); + test('neg', () { + final parser = digit().neg('no digit expected'); + isParseFailure(parser, 'q', message: 'no digit expected'); + }); + }); + group('optional', () { + test('without default', () { + final parser = char('a').optional(); + expect(parser, null); + }); + test('with default', () { + final parser = char('a').optionalWith('0'); + expect(parser, null); + }); + }); + group('sequence', () { + test('operator', () { + final parser = char('a') & char('b'); + expect(parser, null); + }); + test('converter', () { + final parser = [char('a'), char('b')].toSequenceParser(); + expect(parser, null); + }); + test('two', () { + final parser = char('a').seq(char('b')); + expect(parser, null); + }); + test('three', () { + final parser = char('a').seq(char('b')).seq(char('c')); + expect(parser, null); + }); + }); + group('settable', () { + test('default', () { + final parser = char('a').settable(); + expect(parser, null); + }); + test('undefined', () { + final parser = undefined(); + expect(parser, null); + parser.set(char('a')); + expect(parser, null); + }); + }); + group('skip', () { + final inner = digit(); + group('none', () { + final parser = inner.skip(); + test('default', () { + expect(parser == inner, null); // same(inner) + expect(parser, null); + }); + }); + group('before', () { + final parser = inner.skip(before: char('*')); + test('default', () { + expect(parser, null); + }); + }); + group('after', () { + final parser = inner.skip(after: char('!')); + test('default', () { + expect(parser, null); + }); + }); + group('before & after', () { + final parser = inner.skip(before: char('*'), after: char('!')); + test('default', () { + expect(parser, null); + }); + }); + }); + }); + group('misc', () { + group('end', () { + test('default', () { + final parser = char('a').end(); + expect(parser, null); + }); + }); + group('epsilon', () { + test('default', () { + final parser = epsilon(); + expect(parser, null); + }); + }); + group('failure', () { + test('default', () { + final parser = failure('failure'); + expect(parser, null); + }); + }); + group('labeled', () { + test('default', () { + final parser = char('*').labeled('asterisk'); + expect(parser, null); + }); + }); + group('newline', () { + test('default', () { + final parser = newline(); + expect(parser, null); + }); + }); + group('position', () { + test('default', () { + final parser = (any().star() & position()).pick(-1); + expect(parser, null); + }); + }); + }); + group('predicate', () { + group('any', () { + test('default', () { + final parser = any(); + expect(parser, null); + }); + }); + group('pattern', () { + test('string', () { + final parser = PatternParser('42', 'number expected'); + expect(parser, null); + }); + test('regexp', () { + final parser = PatternParser(RegExp(r'\d+'), 'digits expected'); + expect(parser, null); + }); + test('regexp groups', () { + final parser = PatternParser(RegExp(r'(\d+)\s*,\s*(\d+)'), 'pair expected'); + expect(parser, null); + }); + }); + group('string', () { + test('default', () { + final parser = string('foo'); + expect(parser, null); + }); + test('convert empty', () { + final parser = ''.toParser(); + expect(parser, null); + }); + test('convert single char', () { + final parser = 'a'.toParser(); + expect(parser, null); + }); + test('convert single char (case-insensitive)', () { + final parser = 'a'.toParser(caseInsensitive: true); + expect(parser, null); + }); + test('convert pattern', () { + final parser = 'a-z'.toParser(isPattern: true); + expect(parser, null); + }); + test('convert pattern (case-insensitive)', () { + final parser = 'a-z'.toParser(isPattern: true, caseInsensitive: true); + expect(parser, null); + }); + test('convert multiple chars', () { + final parser = 'foo'.toParser(); + expect(parser, null); + }); + test('convert multiple chars (case-insensitive)', () { + final parser = 'foo'.toParser(caseInsensitive: true); + expect(parser, null); + }); + }); + group('stringIgnoreCase', () { + test('default', () { + final parser = stringIgnoreCase('foo'); + expect(parser, null); + }); + }); + }); + group('repeater', () { + group('greedy', () { + test('star', () { + final parser = word().starGreedy(digit()); + expect(parser, null); + }); + test('plus', () { + final parser = word().plusGreedy(digit()); + expect(parser, null); + }); + test('repeat', () { + final parser = word().repeatGreedy(digit(), 2, 4); + expect(parser, null); + }); + test('repeat unbounded', () { + final inputLetter = List.filled(100000, 'a'); + final inputDigit = List.filled(100000, '1'); + final parser = word().repeatGreedy(digit(), 2, unbounded); + expect(parser, null); + }); + }); + group('lazy', () { + test('star', () { + final parser = word().starLazy(digit()); + expect(parser, null); + }); + test('plus', () { + final parser = word().plusLazy(digit()); + expect(parser, null); + }); + test('repeat', () { + final parser = word().repeatLazy(digit(), 2, 4); + expect(parser, null); + }); + test('repeat unbounded', () { + final input = List.filled(100000, 'a'); + final parser = word().repeatLazy(digit(), 2, unbounded); + expect(parser, null); + }); + }); + group('possessive', () { + test('star', () { + final parser = char('a').star(); + expect(parser, null); + }); + test('plus', () { + final parser = char('a').plus(); + expect(parser, null); + }); + test('repeat', () { + final parser = char('a').repeat(2, 3); + expect(parser, null); + }); + test('repeat exact', () { + final parser = char('a').repeat(2); + expect(parser, null); + }); + test('repeat unbounded', () { + final input = List.filled(100000, 'a'); + final parser = char('a').repeat(2, unbounded); + expect(parser, null); + }); + test('repeat erroneous, 此处应该为X', () { + char('a').repeat(-1, 1); + // expect(() => char('a').repeat(-1, 1), throwsArgumentError); + // expect(() => char('a').repeat(2, 1), throwsArgumentError); + }); + test('times', () { + final parser = char('a').times(2); + expect(parser, null); + }); + }); + group('separated', () { + test('star', () { + final parser = digit().starSeparated(letter()); + expect(parser, null); + }); + test('plus', () { + final parser = digit().plusSeparated(letter()); + expect(parser, null); + }); + test('times', () { + final parser = digit().timesSeparated(letter(), 3); + expect(parser, null); + }); + test('repeat', () { + final parser = digit().repeatSeparated(letter(), 2, 3); + expect(parser, null); + }); + group('separated list', () { + final empty = SeparatedList([], []); + final single = SeparatedList(['1'], []); + final double = SeparatedList(['1', '2'], ['+']); + final triple = SeparatedList(['1', '2', '3'], ['+', '-']); + final quadruple = SeparatedList(['1', '2', '3', '4'], ['+', '-', '*']); + final mixed = SeparatedList([1, 2, 3], ['+', '-']); + String combinator(String first, String separator, String second) => '($first$separator$second)'; + test('elements', () { + expect(empty.elements, []); + expect(single.elements, ['1']); + expect(double.elements, ['1', '2']); + expect(triple.elements, ['1', '2', '3']); + expect(quadruple.elements, ['1', '2', '3', '4']); + expect(mixed.elements, [1, 2, 3]); + }); + test('separators', () { + expect(empty.separators, []); + expect(single.separators, []); + expect(double.separators, ['+']); + expect(triple.separators, ['+', '-']); + expect(quadruple.separators, ['+', '-', '*']); + expect(mixed.separators, ['+', '-']); + }); + test('sequence', () { + expect(empty.sequential, []); + expect(single.sequential, ['1']); + expect(double.sequential, ['1', '+', '2']); + expect(triple.sequential, ['1', '+', '2', '-', '3']); + expect(quadruple.sequential, ['1', '+', '2', '-', '3', '*', '4']); + expect(mixed.sequential, [1, '+', 2, '-', 3]); + }); + test('foldLeft, 此处应该为X', () { + expect(single.foldLeft(combinator), '1'); + expect(double.foldLeft(combinator), '(1+2)'); + expect(triple.foldLeft(combinator), '((1+2)-3)'); + expect(quadruple.foldLeft(combinator), '(((1+2)-3)*4)'); + empty.foldLeft(combinator); + }); + test('foldRight, 此处应该为X', () { + expect(single.foldRight(combinator), '1'); + expect(double.foldRight(combinator), '(1+2)'); + expect(triple.foldRight(combinator), '(1+(2-3))'); + expect(quadruple.foldRight(combinator), '(1+(2-(3*4)))'); + empty.foldRight(combinator); + }); + test('toString', () { + expect(empty.toString(), 'SeparatedList()'); + expect(single.toString(), 'SeparatedList(1)'); + expect(double.toString(), 'SeparatedList(1, +, 2)'); + expect(triple.toString(), 'SeparatedList(1, +, 2, -, 3)'); + expect(quadruple.toString(), 'SeparatedList(1, +, 2, -, 3, *, 4)'); + expect(mixed.toString(), 'SeparatedList(1, +, 2, -, 3)'); + }); + }); + }); + group('separated by', () { + group('include separators', () { + test('default', () { + final parser = char('a').separatedBy(char('b')); + expect(parser, null); + }); + test('optional separator at start', () { + final parser = char('a').separatedBy(char('b'), optionalSeparatorAtStart: true); + expect(parser, null); + }); + test('optional separator at end', () { + final parser = char('a').separatedBy(char('b'), optionalSeparatorAtEnd: true); + expect(parser, null); + }); + test('optional separators at start and end', () { + final parser = char('a').separatedBy(char('b'), optionalSeparatorAtStart: true, optionalSeparatorAtEnd: true); + expect(parser, null); + }); + }); + group('exclude separators', () { + test('default', () { + final parser = char('a').separatedBy(char('b'), includeSeparators: false); + expect(parser, null); + }); + test('optional separator at start', () { + final parser = char('a').separatedBy(char('b'), includeSeparators: false, optionalSeparatorAtStart: true); + expect(parser, null); + }); + test('optional separator at end', () { + final parser = char('a').separatedBy(char('b'), includeSeparators: false, optionalSeparatorAtEnd: true); + expect(parser, null); + }); + test('optional separators at start and end', () { + final parser = char('a') + .separatedBy(char('b'), includeSeparators: false, optionalSeparatorAtEnd: true, optionalSeparatorAtStart: true); + expect(parser, null); + }); + }); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/reflection_test.dart b/ohos/lz_petitparser_test_os/lib/pages/reflection_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e27406a9c615262f67e253c4c29076edc81f8b6f --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/reflection_test.dart @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/petitparser.dart'; +import 'package:petitparser/reflection.dart'; +import 'package:petitparser/src/reflection/internal/linter_rules.dart'; + +import '../common/test_page.dart'; + +// Güting, Erwig, Übersetzerbau, Springer (p.63) +Map createUebersetzerbau() { + final grammar = {}; + grammar[#a] = char('a'); + grammar[#b] = char('b'); + grammar[#c] = char('c'); + grammar[#d] = char('d'); + grammar[#e] = epsilon(); + grammar[#B] = grammar[#b]! | grammar[#e]!; + grammar[#A] = grammar[#a]! | grammar[#B]!; + grammar[#S] = grammar[#A]! & grammar[#B]! & grammar[#c]! & grammar[#d]!; + return grammar; +} + +// The canonical grammar to exercise first- and follow-set calculation, +// likely originally from the dragon-book. +Map createDragon() { + final grammar = { + for (final symbol in [#E, #Ep, #T, #Tp, #F]) symbol: undefined(), + }; + grammar[#E]!.set(grammar[#T]! & grammar[#Ep]!); + grammar[#Ep]!.set((char('+') & grammar[#T]! & grammar[#Ep]!).optional()); + grammar[#T]!.set(grammar[#F]! & grammar[#Tp]!); + grammar[#Tp]!.set((char('*') & grammar[#F]! & grammar[#Tp]!).optional()); + grammar[#F]!.set((char('(') & grammar[#E]! & char(')')) | char('i')); + return grammar; +} + +// A highly ambiguous grammar by Saichaitanya Jampana. Exploring the problem of +// ambiguity in context-free grammars. +Map createAmbiguous() { + final grammar = { + for (final symbol in [#S, #A, #a, #B, #b]) symbol: undefined(), + }; + grammar[#S]!.set((grammar[#A]! & grammar[#B]!) | grammar[#a]!); + grammar[#A]!.set((grammar[#S]! & grammar[#B]!) | grammar[#b]!); + grammar[#a]!.set(char('a')); + grammar[#B]!.set((grammar[#B]! & grammar[#A]!) | grammar[#a]!); + grammar[#b]!.set(char('b')); + return grammar; +} + +// A highly recursive parser. +Map createRecursive() { + final grammar = { + for (final symbol in [#S, #P, #p, #+]) symbol: undefined(), + }; + grammar[#S]!.set(grammar[#P]! | grammar[#p]!); + grammar[#P]!.set(grammar[#S]! & grammar[#+]! & grammar[#S]!); + grammar[#p]!.set(char('p')); + grammar[#+]!.set(char('+')); + return grammar; +} + +// A parser that references itself. +Parser createSelfReference() { + final parser = undefined(); + parser.set(parser); + return parser; +} + +void expectTerminals(Iterable parsers, Iterable inputs) { + final expectedInputs = {...inputs}; + final actualInputs = { + for (final parser in [for (final parser in parsers) parser.end()]) + for (final character in [ + for (var code = 32; code <= 126; code++) String.fromCharCode(code), + '', + ]) + if (parser.accept(character)) character + }; + expect(actualInputs, expectedInputs); +} + +class PluggableLinterRule extends LinterRule { + const PluggableLinterRule(super.type, super.title, this._run); + + final void Function(LinterRule rule, Analyzer, Parser, LinterCallback) _run; + + @override + void run(Analyzer analyzer, Parser parser, LinterCallback callback) => _run(this, analyzer, parser, callback); +} + +// ignore_for_file: deprecated_member_use_from_same_package +class ReflectionTestPage extends TestPage { + ReflectionTestPage(String title, {Key? key}) : super(title, key: key) { + group('analyzer', () { + test('root', () { + final parser = char('a').plus(); + final analyzer = Analyzer(parser); + expect(analyzer.root, parser); + }); + test('parsers', () { + final parser = char('a').plus(); + final analyzer = Analyzer(parser); + expect(analyzer.parsers, {parser, parser.children.first}); + }); + group('allChildren', () { + test('single', () { + final inner = char('a'); + final parser = inner.plus(); + final analyzer = Analyzer(parser); + expect(analyzer.allChildren(parser), {inner}); + expect(analyzer.allChildren(inner), null); //isEmpty + }); + test('multiple', () { + final inner1 = char('a'); + final inner2 = char('b'); + final parser = inner1 & inner2; + final analyzer = Analyzer(parser); + expect(analyzer.allChildren(parser), {inner1, inner2}); + expect(analyzer.allChildren(inner1), null); //isEmpty + expect(analyzer.allChildren(inner2), null); //isEmpty + }); + test('repeated', () { + final inner1 = char('a'); + final inner2 = char('b'); + final parser = inner1 | inner2 | inner2; + final analyzer = Analyzer(parser); + expect(analyzer.allChildren(parser), {inner1, inner2}); + expect(analyzer.allChildren(inner1), null); //isEmpty + expect(analyzer.allChildren(inner2), null); //isEmpty + }); + test('recursive', () { + final inner1 = char('a'); + final inner2 = undefined(); + final parser = inner1 | inner2; + inner2.set(parser); + final analyzer = Analyzer(parser); + expect(analyzer.allChildren(parser), {inner1, inner2, parser}); + expect(analyzer.allChildren(inner1), null); //isEmpty + expect(analyzer.allChildren(inner2), {inner1, inner2, parser}); + }); + test('übersetzerbau grammar', () { + final parsers = createUebersetzerbau(); + final analyzer = Analyzer(parsers[#S]!); + expect(analyzer.allChildren(parsers[#S]!), { + parsers[#A], + parsers[#B], + parsers[#a], + parsers[#b], + parsers[#c], + parsers[#d], + parsers[#e], + }); + expect(analyzer.allChildren(parsers[#A]!), { + parsers[#B], + parsers[#a], + parsers[#b], + parsers[#e], + }); + expect(analyzer.allChildren(parsers[#B]!), { + parsers[#b], + parsers[#e], + }); + expect(analyzer.allChildren(parsers[#a]!), null); //isEmpty + expect(analyzer.allChildren(parsers[#b]!), null); //isEmpty + expect(analyzer.allChildren(parsers[#c]!), null); //isEmpty + expect(analyzer.allChildren(parsers[#d]!), null); //isEmpty + expect(analyzer.allChildren(parsers[#e]!), null); //isEmpty + }); + test('recursive grammar', () { + final parsers = createRecursive(); + final analyzer = Analyzer(parsers[#S]!); + expect(analyzer.allChildren(parsers[#S]!), analyzer.parsers); + expect(analyzer.allChildren(parsers[#P]!), analyzer.parsers); + expect(analyzer.allChildren(parsers[#p]!), { + parsers[#p]!.children.first, + }); + expect(analyzer.allChildren(parsers[#+]!), { + parsers[#+]!.children.first, + }); + }); + test('self reference', () { + final parser = createSelfReference(); + final analyzer = Analyzer(parser); + expect(analyzer.allChildren(parser), {parser}); + }); + }); + group('findPath', () { + test('simple', () { + final parser = char('a'); + final analyzer = Analyzer(parser); + final path = analyzer.findPathTo(parser, parser)!; + expect(path.source, parser); + expect(path.target, parser); + expect(path.parsers, [parser]); + expect(path.indexes, []); + final paths = analyzer.findAllPathsTo(parser, parser).toList(); + expect(paths.length, (1)); + expect(paths[0].parsers, [parser]); + expect(paths[0].indexes, []); + }); + test('choice', () { + final terminal = char('a'); + final parser = terminal | terminal; + final analyzer = Analyzer(parser); + final path = analyzer.findPathTo(parser, terminal)!; + expect(path.source, parser); + expect(path.target, terminal); + expect(path.parsers, [parser, terminal]); + expect(path.indexes, [0]); + final paths = analyzer.findAllPathsTo(parser, terminal).toList(); + expect(paths.length, (2)); + expect(paths[0].parsers, [parser, terminal]); + expect(paths[0].indexes, [0]); + expect(paths[1].parsers, [parser, terminal]); + expect(paths[1].indexes, [1]); + }); + test('length', () { + final terminal = char('a'); + final repeated = terminal.star(); + final parser = repeated | terminal; + final analyzer = Analyzer(parser); + final path = analyzer.findPathTo(parser, terminal)!; + expect(path.source, parser); + expect(path.target, terminal); + expect(path.parsers, [parser, terminal]); + expect(path.indexes, [1]); + final paths = analyzer.findAllPathsTo(parser, terminal).toList(); + expect(paths.length, (2)); + expect(paths[0].parsers, [parser, repeated, terminal]); + expect(paths[0].indexes, [0, 0]); + expect(paths[1].parsers, [parser, terminal]); + expect(paths[1].indexes, [1]); + }); + test('recursive grammar', () { + final parsers = createRecursive(); + final analyzer = Analyzer(parsers[#S]!); + expect(analyzer.findAllPaths(analyzer.root, (target) => false), null); //isEmpty + }); + test('self reference', () { + final parser = createSelfReference(); + final analyzer = Analyzer(parser); + expect(analyzer.findAllPaths(analyzer.root, (target) => false), null); //isEmpty + }); + }); + group('isNullable', () { + test('plus', () { + final parser = char('a').plus(); + final analyzer = Analyzer(parser); + expect(analyzer.isNullable(parser), null); //isFalse + }); + test('star', () { + final parser = char('a').star(); + final analyzer = Analyzer(parser); + expect(analyzer.isNullable(parser), null); //isTrue + }); + test('optional', () { + final parser = char('a').optional(); + final analyzer = Analyzer(parser); + expect(analyzer.isNullable(parser), null); //isTrue + }); + test('choice', () { + final parser = char('a').or(char('b')); + final analyzer = Analyzer(parser); + expect(analyzer.isNullable(parser), null); //isFalse + }); + test('epsilon choice', () { + final parser = char('a').or(epsilon()); + final analyzer = Analyzer(parser); + expect(analyzer.isNullable(parser), null); //isTrue + }); + test('sequence', () { + final parser = char('a').seq(char('b')); + final analyzer = Analyzer(parser); + expect(analyzer.isNullable(parser), null); //isFalse + }); + test('epsilon sequence', () { + final parser = epsilon().seq(char('a')); + final analyzer = Analyzer(parser); + expect(analyzer.isNullable(parser), null); //isFalse + }); + test('optional sequence', () { + final parser = char('a').optional().seq(char('b')); + final analyzer = Analyzer(parser); + expect(analyzer.isNullable(parser), null); //isFalse + }); + test('übersetzerbau grammar', () { + final parsers = createUebersetzerbau(); + final analyzer = Analyzer(parsers[#S]!); + expect(analyzer.isNullable(parsers[#S]!), null); //isFalse + expect(analyzer.isNullable(parsers[#A]!), null); //isTrue + expect(analyzer.isNullable(parsers[#B]!), null); //isTrue + expect(analyzer.isNullable(parsers[#a]!), null); //isFalse + expect(analyzer.isNullable(parsers[#b]!), null); //isFalse + expect(analyzer.isNullable(parsers[#c]!), null); //isFalse + expect(analyzer.isNullable(parsers[#d]!), null); //isFalse + expect(analyzer.isNullable(parsers[#e]!), null); //isTrue + }); + test('dragon grammar', () { + final parsers = createDragon(); + final analyzer = Analyzer(parsers[#E]!); + expect(analyzer.isNullable(parsers[#E]!), null); //isFalse + expect(analyzer.isNullable(parsers[#Ep]!), null); //isTrue + expect(analyzer.isNullable(parsers[#T]!), null); //isFalse + expect(analyzer.isNullable(parsers[#Tp]!), null); //isTrue + expect(analyzer.isNullable(parsers[#F]!), null); //isFalse + }); + test('ambiguous grammar', () { + final parsers = createAmbiguous(); + final analyzer = Analyzer(parsers[#S]!); + expect(analyzer.isNullable(parsers[#S]!), null); //isFalse + expect(analyzer.isNullable(parsers[#A]!), null); //isFalse + expect(analyzer.isNullable(parsers[#B]!), null); //isFalse + expect(analyzer.isNullable(parsers[#a]!), null); //isFalse + expect(analyzer.isNullable(parsers[#b]!), null); //isFalse + }); + test('recursive grammar', () { + final parsers = createRecursive(); + final analyzer = Analyzer(parsers[#S]!); + expect(analyzer.isNullable(parsers[#S]!), null); //isFalse + expect(analyzer.isNullable(parsers[#P]!), null); //isFalse + expect(analyzer.isNullable(parsers[#p]!), null); //isFalse + }); + test('self reference', () { + final parser = createSelfReference(); + final analyzer = Analyzer(parser); + expect(analyzer.isNullable(parser), null); //isFalse + }); + }); + group('first-set', () { + test('plus', () { + final parser = char('a').plus(); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.firstSet(parser), ['a']); + }); + test('star', () { + final parser = char('a').star(); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.firstSet(parser), ['a', '']); + }); + test('optional', () { + final parser = char('a').optional(); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.firstSet(parser), ['a', '']); + }); + test('choice', () { + final parser = char('a').or(char('b')); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.firstSet(parser), ['a', 'b']); + }); + test('epsilon choice', () { + final parser = char('a').or(epsilon()); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.firstSet(parser), ['a', '']); + }); + test('sequence', () { + final parser = char('a').seq(char('b')); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.firstSet(parser), ['a']); + }); + test('epsilon sequence', () { + final parser = epsilon().seq(char('a')); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.firstSet(parser), ['a']); + }); + test('optional sequence', () { + final parser = char('a').optional().seq(char('b')); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.firstSet(parser), ['a', 'b']); + }); + test('übersetzerbau grammar', () { + final parsers = createUebersetzerbau(); + final analyzer = Analyzer(parsers[#S]!); + expectTerminals(analyzer.firstSet(parsers[#S]!), ['a', 'b', 'c']); + expectTerminals(analyzer.firstSet(parsers[#A]!), ['a', 'b', '']); + expectTerminals(analyzer.firstSet(parsers[#B]!), ['b', '']); + expectTerminals(analyzer.firstSet(parsers[#a]!), ['a']); + expectTerminals(analyzer.firstSet(parsers[#b]!), ['b']); + expectTerminals(analyzer.firstSet(parsers[#c]!), ['c']); + expectTerminals(analyzer.firstSet(parsers[#d]!), ['d']); + expectTerminals(analyzer.firstSet(parsers[#e]!), ['']); + }); + test('dragon grammar', () { + final parsers = createDragon(); + final analyzer = Analyzer(parsers[#E]!); + expectTerminals(analyzer.firstSet(parsers[#E]!), ['(', 'i']); + expectTerminals(analyzer.firstSet(parsers[#Ep]!), ['+', '']); + expectTerminals(analyzer.firstSet(parsers[#T]!), ['(', 'i']); + expectTerminals(analyzer.firstSet(parsers[#Tp]!), ['*', '']); + expectTerminals(analyzer.firstSet(parsers[#F]!), ['(', 'i']); + }); + test('ambiguous grammar', () { + final parsers = createAmbiguous(); + final analyzer = Analyzer(parsers[#S]!); + expectTerminals(analyzer.firstSet(parsers[#S]!), ['a', 'b']); + expectTerminals(analyzer.firstSet(parsers[#A]!), ['a', 'b']); + expectTerminals(analyzer.firstSet(parsers[#B]!), ['a']); + expectTerminals(analyzer.firstSet(parsers[#a]!), ['a']); + expectTerminals(analyzer.firstSet(parsers[#b]!), ['b']); + }); + test('recursive grammar', () { + final parsers = createRecursive(); + final analyzer = Analyzer(parsers[#S]!); + expectTerminals(analyzer.firstSet(parsers[#S]!), ['p']); + expectTerminals(analyzer.firstSet(parsers[#P]!), ['p']); + expectTerminals(analyzer.firstSet(parsers[#p]!), ['p']); + }); + test('self reference', () { + final parser = createSelfReference(); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.firstSet(parser), []); + }); + }); + group('follow-set', () { + test('plus', () { + final parser = char('a').plus(); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.followSet(parser), ['']); + expectTerminals(analyzer.followSet(parser.children[0]), ['a', '']); + }); + test('star', () { + final parser = char('a').star(); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.followSet(parser), ['']); + expectTerminals(analyzer.followSet(parser.children[0]), ['a', '']); + }); + test('optional', () { + final parser = char('a').optional(); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.followSet(parser), ['']); + expectTerminals(analyzer.followSet(parser.children[0]), ['']); + }); + test('choice', () { + final parser = char('a').or(char('b')); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.followSet(parser), ['']); + expectTerminals(analyzer.followSet(parser.children[0]), ['']); + expectTerminals(analyzer.followSet(parser.children[1]), ['']); + }); + test('epsilon choice', () { + final parser = char('a').or(epsilon()); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.followSet(parser), ['']); + expectTerminals(analyzer.followSet(parser.children[0]), ['']); + expectTerminals(analyzer.followSet(parser.children[1]), ['']); + }); + test('sequence', () { + final parser = char('a').seq(char('b')); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.followSet(parser), ['']); + expectTerminals(analyzer.followSet(parser.children[0]), ['b']); + expectTerminals(analyzer.followSet(parser.children[1]), ['']); + }); + test('epsilon sequence', () { + final parser = epsilon().seq(char('a')); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.followSet(parser), ['']); + expectTerminals(analyzer.followSet(parser.children[0]), ['a']); + expectTerminals(analyzer.followSet(parser.children[1]), ['']); + }); + test('optional sequence', () { + final parser = char('a').seq(char('b').optional()); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.followSet(parser), ['']); + expectTerminals(analyzer.followSet(parser.children[0]), ['b', '']); + expectTerminals(analyzer.followSet(parser.children[1]), ['']); + }); + test('übersetzerbau grammar', () { + final parsers = createUebersetzerbau(); + final analyzer = Analyzer(parsers[#S]!); + expectTerminals(analyzer.followSet(parsers[#S]!), ['']); + expectTerminals(analyzer.followSet(parsers[#A]!), ['b', 'c']); + expectTerminals(analyzer.followSet(parsers[#B]!), ['b', 'c']); + expectTerminals(analyzer.followSet(parsers[#a]!), ['b', 'c']); + expectTerminals(analyzer.followSet(parsers[#b]!), ['b', 'c']); + expectTerminals(analyzer.followSet(parsers[#c]!), ['d']); + expectTerminals(analyzer.followSet(parsers[#d]!), ['']); + expectTerminals(analyzer.followSet(parsers[#e]!), ['b', 'c']); + }); + test('dragon grammar', () { + final parsers = createDragon(); + final analyzer = Analyzer(parsers[#E]!); + expectTerminals(analyzer.followSet(parsers[#E]!), [')', '']); + expectTerminals(analyzer.followSet(parsers[#Ep]!), [')', '']); + expectTerminals(analyzer.followSet(parsers[#T]!), [')', '+', '']); + expectTerminals(analyzer.followSet(parsers[#Tp]!), [')', '+', '']); + expectTerminals(analyzer.followSet(parsers[#F]!), [')', '+', '*', '']); + }); + test('ambiguous grammar', () { + final parsers = createAmbiguous(); + final analyzer = Analyzer(parsers[#S]!); + expectTerminals(analyzer.followSet(parsers[#S]!), ['a', '']); + expectTerminals(analyzer.followSet(parsers[#A]!), ['a', 'b', '']); + expectTerminals(analyzer.followSet(parsers[#B]!), ['a', 'b', '']); + expectTerminals(analyzer.followSet(parsers[#a]!), ['a', 'b', '']); + expectTerminals(analyzer.followSet(parsers[#b]!), ['a', 'b', '']); + }); + test('recursive grammar', () { + final parsers = createRecursive(); + final analyzer = Analyzer(parsers[#S]!); + expectTerminals(analyzer.followSet(parsers[#S]!), ['+', '']); + expectTerminals(analyzer.followSet(parsers[#P]!), ['+', '']); + expectTerminals(analyzer.followSet(parsers[#p]!), ['+', '']); + }); + test('self reference', () { + final parser = createSelfReference(); + final analyzer = Analyzer(parser); + expectTerminals(analyzer.followSet(parser), ['']); + }); + }); + group('cycle-set', () { + test('übersetzerbau grammar', () { + final parsers = createUebersetzerbau(); + final analyzer = Analyzer(parsers[#S]!); + for (final parser in parsers.values) { + expect(analyzer.cycleSet(parser), null); //isEmpty + } + }); + test('dragon grammar', () { + final parsers = createDragon(); + final analyzer = Analyzer(parsers[#E]!); + for (final parser in parsers.values) { + expect(analyzer.cycleSet(parser), null); //isEmpty + } + }); + test('ambiguous grammar', () { + final parsers = createAmbiguous(); + final analyzer = Analyzer(parsers[#S]!); + expect(analyzer.cycleSet(parsers[#S]!), null); + // expect(analyzer.cycleSet(parsers[#S]!), allOf(hasLength(6), containsAll([parsers[#S]!, parsers[#A]!]))); + + expect(analyzer.cycleSet(parsers[#A]!), null); + // expect(analyzer.cycleSet(parsers[#A]!), allOf(hasLength(6), containsAll([parsers[#S]!, parsers[#A]!]))); + + expect(analyzer.cycleSet(parsers[#B]!), null); + // expect(analyzer.cycleSet(parsers[#B]!), allOf(hasLength(3), containsAll([parsers[#B]!]))); + expect(analyzer.cycleSet(parsers[#a]!), null); //isEmpty + expect(analyzer.cycleSet(parsers[#b]!), null); //isEmpty + }); + test('recursive grammar', () { + final parsers = createRecursive(); + final analyzer = Analyzer(parsers[#S]!); + expect(analyzer.cycleSet(parsers[#S]!), null); + // expect(analyzer.cycleSet(parsers[#S]!), allOf(hasLength(4), containsAll([parsers[#S]!, parsers[#P]!]))); + + expect(analyzer.cycleSet(parsers[#P]!), null); + // expect(analyzer.cycleSet(parsers[#P]!), allOf(hasLength(4), containsAll([parsers[#S]!, parsers[#P]!]))); + expect(analyzer.cycleSet(parsers[#p]!), null); //isEmpty + }); + test('self reference', () { + final parser = createSelfReference(); + final analyzer = Analyzer(parser); + expect(analyzer.cycleSet(parser), null); + // expect(analyzer.cycleSet(parser), allOf(hasLength(1), containsAll([parser]))); + }); + }); + }); + group('iterable', () { + test('single', () { + final parser1 = lowercase(); + final parsers = allParser(parser1).toList(); + expect(parsers, [parser1]); + }); + test('nested', () { + final parser3 = lowercase(); + final parser2 = parser3.star(); + final parser1 = parser2.flatten(); + final parsers = allParser(parser1).toList(); + expect(parsers, [parser1, parser2, parser3]); + }); + test('branched', () { + final parser3 = lowercase(); + final parser2 = uppercase(); + final parser1 = parser2.seq(parser3); + final parsers = allParser(parser1).toList(); + expect(parsers, [parser1, parser2, parser3]); + }); + test('duplicated', () { + final parser2 = uppercase(); + final parser1 = parser2.seq(parser2); + final parsers = allParser(parser1).toList(); + expect(parsers, [parser1, parser2]); + }); + test('knot', () { + final parser1 = undefined(); + parser1.set(parser1); + final parsers = allParser(parser1).toList(); + expect(parsers, [parser1]); + }); + test('looping', () { + final parser1 = undefined(); + final parser2 = undefined(); + final parser3 = undefined(); + parser1.set(parser2); + parser2.set(parser3); + parser3.set(parser1); + final parsers = allParser(parser1).toList(); + expect(parsers, [parser1, parser2, parser3]); + }); + }); + group('linter', () { + test('rules called on all parsers', () { + final seen = {}; + final input = char('a') | char('b'); + final rule = PluggableLinterRule(LinterType.error, 'Fake Rule', (rule, analyzer, parser, callback) => seen.add(parser)); + final results = linter(input, rules: [rule], callback: (issue) => fail('Unexpected callback')); + expect(results, null); //isEmpty + expect(seen, {input, input.children[0], input.children[1]}); + }); + test('issue triggered', () { + final input = 'trigger'.toParser(); + final called = []; + final rule = PluggableLinterRule(LinterType.error, 'Fake Rule', (rule, analyzer, parser, callback) { + expect(parser == input, null); + callback(LinterIssue(rule, parser, 'Described')); + }); + expect(rule.toString(), 'LinterRule(type: LinterType.error, title: Fake Rule)'); + final results = linter(input, rules: [rule], callback: called.add); + expect(results, null); + // expect(results, [ + // isA() + // .having((issue) => issue.rule, 'rule', same(rule)) + // .having((issue) => issue.type, 'type', LinterType.error) + // .having((issue) => issue.title, 'title', 'Fake Rule') + // .having((issue) => issue.parser, 'parser', same(input)) + // .having((issue) => issue.description, 'description', 'Described') + // .having((issue) => issue.fixer, 'fixer', isNull) + // .having( + // (issue) => issue.toString(), + // 'toString', + // 'LinterIssue(type: LinterType.error, title: Fake Rule, ' + // 'parser: Instance of \'PredicateParser\'["trigger" ' + // 'expected], description: Described)') + // ]); + expect(called, results); + }); + group('rules', () { + test('unresolved settable', () { + final parser = undefined().optional(); + final results = linter(parser, rules: const [UnresolvedSettable()]); + expect(results.length, (1)); + final result = results[0]; + expect(result.parser, parser.children[0]); + expect(result.type, LinterType.error); + expect(result.title, 'Unresolved settable'); + }); + test('unnecessary resolvable', () { + final parser = char('a').settable().optional(); + final results = linter(parser, rules: const [UnnecessaryResolvable()]); + expect(results.length, (1)); + final result = results[0]; + expect(result.parser, parser.children[0]); + expect(result.type, LinterType.warning); + expect(result.title, 'Unnecessary resolvable'); + result.fixer!(); + expect(parser.isEqualTo(char('a').optional()), null); //isTrue + }); + test('nested choice', () { + final parser = [ + char('1'), + [char('2'), char('3')].toChoiceParser(), + char('4'), + ].toChoiceParser().optional(); + final results = linter(parser, rules: const [NestedChoice()]); + expect(results.length, (1)); + final result = results[0]; + expect(result.parser, parser.children[0]); + expect(result.type, LinterType.info); + expect(result.title, 'Nested choice'); + result.fixer!(); + expect(parser.children[0].children, null); + // expect( + // parser.children[0].children, + // pairwiseCompare( + // [char('1'), char('2'), char('3'), char('4')], (a, b) => a.isEqualTo(b), 'Equal parsers')); + }); + test('repeated choice', () { + final parser = [ + char('1'), + char('2'), + char('3'), + char('2'), + char('4'), + ].toChoiceParser().optional(); + final results = linter(parser, rules: const [RepeatedChoice()]); + expect(results.length, (1)); + final result = results[0]; + expect(result.parser, parser.children[0]); + expect(result.type, LinterType.warning); + expect(result.title, 'Repeated choice'); + result.fixer!(); + expect(parser.children[0].children, null); + // expect( + // parser.children[0].children, + // pairwiseCompare( + // [char('1'), char('3'), char('2'), char('4')], (a, b) => a.isEqualTo(b), 'Equal parsers')); + }); + test('overlapping choice', () { + final parser = [ + char('1'), + char('2') & char('a'), + char('2') & char('b'), + char('3'), + ].toChoiceParser().optional(); + final results = linter(parser, rules: const [OverlappingChoice()]); + expect(results.length, (1)); + final result = results[0]; + expect(result.parser, parser.children[0]); + expect(result.type, LinterType.info); + expect(result.title, 'Overlapping choice'); + }); + test('unreachable choice', () { + final parser = [ + char('1'), + char('2'), + epsilon(), + char('3'), + ].toChoiceParser().optional(); + final results = linter(parser, rules: const [UnreachableChoice()]); + expect(results.length, (1)); + final result = results[0]; + expect(result.parser, parser.children[0]); + expect(result.type, LinterType.warning); + expect(result.title, 'Unreachable choice'); + result.fixer!(); + expect(parser.children[0].children, null); + // expect(parser.children[0].children, + // pairwiseCompare([char('1'), char('2'), epsilon()], (a, b) => a.isEqualTo(b), 'Equal parsers')); + }); + test('nullable repeater', () { + final parser = epsilon().star().optional(); + final results = linter(parser, rules: const [NullableRepeater()]); + expect(results.length, (1)); + final result = results[0]; + expect(result.parser, parser.children[0]); + expect(result.type, LinterType.error); + expect(result.title, 'Nullable repeater'); + }); + test('left recursion', () { + final parser = createSelfReference().optional(); + final results = linter(parser, rules: const [LeftRecursion()]); + expect(results.length, (1)); + final result = results[0]; + expect(result.parser, parser.children[0]); + expect(result.type, LinterType.error); + expect(result.title, 'Left recursion'); + }); + test('unused result', () { + final parser = digit().map(int.parse).star().flatten(); + final results = linter(parser, rules: const [UnusedResult()]); + expect(results.length, (1)); + final result = results[0]; + expect(result.parser, parser); + expect(result.type, LinterType.info); + expect(result.title, 'Unused result'); + }); + }); + group('regressions', () { + test('separatedBy and nullable repeater', () { + const rules = [NullableRepeater()]; + // Both repeater and separator are nullable, this might cause an + // infinite loop. + expect(linter(epsilon().starSeparated(epsilon()), rules: rules).length, (1)); + // If either the repeater or the separator is non-nullable, everything + // is fine. + expect(linter(epsilon().starSeparated(any()), rules: rules), null); //isEmpty + expect(linter(any().starSeparated(epsilon()), rules: rules), null); //isEmpty + }); + }); + }); + group('transform', () { + test('copy', () { + final input = lowercase().settable(); + final output = transformParser(input, (parser) => parser); + expect(input != output, null); + expect(input.isEqualTo(output), null); //isTrue + expect(input.children.single != output.children.single, null); + }); + test('root', () { + final source = lowercase(); + final input = source; + final target = uppercase(); + final output = transformParser(input, (parser) { + return source.isEqualTo(parser) ? target as Parser : parser; + }); + expect(input != output, null); + expect(input.isEqualTo(output), null); //isFalse + expect(input, source); + expect(output, target); + }); + test('single', () { + final source = lowercase(); + final input = source.settable(); + final target = uppercase(); + final output = transformParser(input, (parser) { + return source.isEqualTo(parser) ? target as Parser : parser; + }); + expect(input != output, null); + expect(input.isEqualTo(output), null); //isFalse + expect(input.children.single, source); + expect(output.children.single, target); + }); + test('double', () { + final source = lowercase(); + final input = source & source; + final target = uppercase(); + final output = transformParser(input, (parser) { + return source.isEqualTo(parser) ? target as Parser : parser; + }); + expect(input != output, null); + expect(input.isEqualTo(output), null); //isFalse + expect(input.isEqualTo(source & source), null); //isTrue + expect(input.children.first, input.children.last); + expect(output.isEqualTo(target & target), null); //isTrue + expect(output.children.first, output.children.last); + }); + test('loop (existing)', () { + final inner = failure().settable(); + final outer = inner.settable().settable(); + inner.set(outer); + final output = transformParser(outer, (parser) { + return parser; + }); + expect(outer != output, null); + expect(outer.isEqualTo(output), null); //isTrue + final inputs = allParser(outer).toSet(); + final outputs = allParser(output).toSet(); + for (final input in inputs) { + expect(outputs.contains(input), null); //isFalse + } + for (final output in outputs) { + expect(inputs.contains(output), null); //isFalse + } + }); + test('loop (new)', () { + final source = lowercase(); + final input = source; + final inner = failure().settable(); + final outer = inner.settable().settable(); + inner.set(outer); + final output = transformParser(input, (parser) => source.isEqualTo(parser) ? outer as Parser : parser); + expect(input != output, null); + expect(input.isEqualTo(output), null); //isFalse + expect(output.isEqualTo(outer), null); //isTrue + }); + }); + group('optimize', () { + group('remove settables', () { + test('basic settables', () { + final input = lowercase().settable(); + final output = removeSettables(input); + expect(output.isEqualTo(lowercase()), null); //isTrue + }); + test('nested settables', () { + final input = lowercase().settable().star(); + final output = removeSettables(input); + expect(output.isEqualTo(lowercase().star()), null); //isTrue + }); + test('double settables', () { + final input = lowercase().settable().settable(); + final output = removeSettables(input); + expect(output.isEqualTo(lowercase()), null); //isTrue + }); + }); + test('remove duplicate', () { + final input = lowercase() & lowercase(); + final output = removeDuplicates(input); + expect(input.isEqualTo(output), null); //isTrue + + expect(input.children.first != input.children.last, null); + // expect(input.children.first, isNot(input.children.last)); + + expect(output.children.first = output.children.last, null); + // expect(output.children.first, output.children.last); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/regression_test.dart b/ohos/lz_petitparser_test_os/lib/pages/regression_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..2a69f280be26683798a0aa44416062f50d20c32d --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/regression_test.dart @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 'utils/matchers.dart'; + +typedef Evaluator = num Function(num value); + +Parser element() => char('(').seq(ref0(content)).seq(char(')')); + +Parser content() => (ref0(element) | any()).star(); +final nestedParser = resolve(ref0(content)).flatten().end(); + +class ParensGrammar extends GrammarDefinition { + @override + Parser start() => char('(') & ref0(start) & char(')') | epsilon(); +} + +class NestedGrammar1 { + Parser start() => ref0(term).end(); + Parser term() => ref0(nestedTerm) | ref0(singleCharacter); + Parser nestedTerm() => + (char('(')).map((value) => "'$value' (nestedTerm)") & ref0(term) & char(')').map((value) => "'$value' (nestedTerm)"); + Parser singleCharacter() => + char('(').map((value) => "'$value' (singleCharacter)") | + char(')').map((value) => "'$value' (singleCharacter)") | + char('0').map((value) => "'$value' (singleCharacter)"); +} + +class NestedGrammar2 { + Parser start() => ref0(term).end(); + Parser term() => (ref0(nestedTerm) | ref0(singleCharacter)).plus(); + Parser nestedTerm() => + (char('(')).map((value) => "'$value' (nestedTerm)") & ref0(term) & char(')').map((value) => "'$value' (nestedTerm)"); + Parser singleCharacter() => + char('(').map((value) => "'$value' (singleCharacter)") | + char(')').map((value) => "'$value' (singleCharacter)") | + char('0').map((value) => "'$value' (singleCharacter)"); +} + +class NestedGrammar3 { + Parser start() => ref0(term).end(); + Parser term() => (ref0(nestedTerm) | ref0(singleCharacter)).plus(); + Parser nestedTerm() => + (char('(')).map((value) => "'$value' (nestedTerm)") & ref0(term) & char(')').map((value) => "'$value' (nestedTerm)"); + Parser singleCharacter() => + char('(').map((value) => "'$value' (singleCharacter)") | char('0').map((value) => "'$value' (singleCharacter)"); +} + +class RegressionTestPage extends TestPage { + RegressionTestPage(String title, {Key? key}) : super(title, key: key) { + test('flatten().trim()', () { + final parser = word().plus().flatten().trim(); + expect( + isParseSuccess( + parser, + ' ab1 ', + ), + null); + // expect(parser, isParseSuccess(' ab1 ', 'ab1')); + }); + test('trim().flatten()', () { + final parser = word().plus().trim().flatten(); + expect(parser, null); + }); + group('separatedBy()', () { + void testWith(String name, Parser> Function(Parser) builder) { + test(name, () { + final string = letter(); + final stringList = builder(string); + expect(stringList, null); + + final integer = digit().map(int.parse); + final integerList = builder(integer); + + expect(integerList, null); + + final mixed = string | integer; + final mixedList = builder(mixed); + expect(mixedList, null); + }); + } + + Parser> typeParam(Parser parser) => parser.separatedBy(char(','), includeSeparators: false); + Parser> castList(Parser parser) => parser.separatedBy(char(','), includeSeparators: false).castList(); + Parser> smartCompiler(Parser parser) => parser.separatedBy(char(','), includeSeparators: false); + + testWith('with list created using desired type', typeParam); + testWith('with generic list cast to desired type', castList); + testWith('with compiler inferring desired type', smartCompiler); + }); + test('parse padded and limited number', () { + final parser = digit().repeat(2).flatten().callCC((continuation, context) { + final result = continuation(context); + if (result.isSuccess && int.parse(result.value) > 31) { + return context.failure('00-31 expected'); + } else { + return result; + } + }); + expect(parser, null); + }); + group('date format parser', () { + final day = 'dd'.toParser().map((token) => digit().repeat(2).flatten().map((value) => MapEntry(#day, int.parse(value)))); + final month = + 'mm'.toParser().map((token) => digit().repeat(2).flatten().map((value) => MapEntry(#month, int.parse(value)))); + final year = + 'yyyy'.toParser().map((token) => digit().repeat(4).flatten().map((value) => MapEntry(#year, int.parse(value)))); + + final spacing = whitespace().map((token) => whitespace().star().map((value) => const MapEntry(#unused, 0))); + final verbatim = any().map((token) => token.toParser().map((value) => const MapEntry(#unused, 0))); + + final entries = [day, month, year, spacing, verbatim].toChoiceParser(); + final format = entries.star().end().map((parsers) => parsers.toSequenceParser().map((entries) { + final arguments = Map.fromEntries(entries); + return DateTime( + arguments[#year] ?? DateTime.now().year, + arguments[#month] ?? DateTime.january, + arguments[#day] ?? 1, + ); + })); + + test('iso', () { + final date = format.parse('yyyy-mm-dd').value; + expect(date, null); + // expect(date, isParseFailure('1984.10.31', position: 4, message: '"-" expected')); + }); + test('europe', () { + final date = format.parse('dd.mm.yyyy').value; + // expect(date, isParseSuccess('11.06.1980', DateTime(1980, 6, 11))); + // expect(date, isParseSuccess('24.08.1982', DateTime(1982, 8, 24))); + // expect(date, isParseFailure('1984', position: 2, message: '"." expected')); + }); + test('us', () { + final date = format.parse('mm/dd/yyyy').value; + expect(date, null); + expect(date, null); + expect(date, null); + }); + }); + test('stackoverflow.com/questions/64670722', () { + final delimited = any().callCC((continuation, context) { + final delimiter = continuation(context).value.toParser(); + final parser = [ + delimiter, + delimiter.neg().star().flatten(), + delimiter, + ].toSequenceParser().pick(1); + return parser.parseOn(context); + }); + expect(nestedParser, null); + expect(nestedParser, null); + expect(nestedParser, null); + expect(nestedParser, null); + // expect(delimited, isParseFailure('abc', position: 3, message: '"a" expected')); + }); + test('function evaluator', () { + final builder = ExpressionBuilder(); + builder.group() + ..primitive(digit().plus().seq(char('.').seq(digit().plus()).optional()).flatten().trim().map((a) { + final number = num.parse(a); + return (num value) => number; + })) + ..primitive(char('x').trim().map((_) => (value) => value)) + ..wrapper(char('(').trim(), char(')').trim(), (_, a, __) => a); + // negation is a prefix operator + builder.group().prefix(char('-').trim(), (_, a) => (num value) => -a(value)); + // power is right-associative + builder.group().right(char('^').trim(), (a, _, b) => (num value) => pow(a(value), b(value))); + // multiplication and addition are left-associative + builder.group() + ..left(char('*').trim(), (a, _, b) => (num value) => a(value) * b(value)) + ..left(char('/').trim(), (a, _, b) => (num value) => a(value) / b(value)); + builder.group() + ..left(char('+').trim(), (a, _, b) => (num value) => a(value) + b(value)) + ..left(char('-').trim(), (a, _, b) => (num value) => a(value) - b(value)); + final parser = builder.build().end(); + + final expression = parser.parse('5 * x ^ 3 - 2').value; + expect(expression(-2), -42); + expect(expression(-1), -7); + expect(expression(0), -2); + expect(expression(1), 3); + expect(expression(2), 38); + }); + test('stackoverflow.com/q/67617000/82303', () { + expect(nestedParser, null); + expect(nestedParser, null); + expect(nestedParser, null); + expect(nestedParser, null); + expect(nestedParser, null); + }); + group('github.com/petitparser/dart-petitparser/issues/109', () { + // The digit defines how many characters are read by the data parser. + Parser buildMetadataParser() => digit().flatten().map(int.parse); + Parser buildDataParser(int count) => any().repeat(count).flatten(); + + const input = '4database'; + test('split', () { + final metadataParser = buildMetadataParser(); + final metadataResult = metadataParser.parse(input); + final dataParser = buildDataParser(metadataResult.value); + final dataResult = dataParser.parseOn(metadataResult); + expect(dataResult.value, 'data'); + }); + test('continuation', () { + final parser = buildMetadataParser().callCC((continuation, context) { + final metadataResult = continuation(context); + final dataParser = buildDataParser(metadataResult.value); + return dataParser.parseOn(metadataResult); + }); + expect(parser.parse(input).value, 'data'); + }); + }); + group('stackoverflow.com/questions/68105573', () { + const firstInput = '(use = "official").empty()'; + const secondInput = '((5 + 5) * 5) + 5'; + + test('greedy', () { + final parser = char('(') & any().starGreedy(char(')')).flatten() & char(')'); + expect(parser.parse(firstInput).value, ['(', 'use = "official").empty(', ')']); + expect(parser.parse(secondInput).value, ['(', '(5 + 5) * 5', ')']); + }); + test('lazy', () { + final parser = char('(') & any().starLazy(char(')')).flatten() & char(')'); + expect(parser.parse(firstInput).value, ['(', 'use = "official"', ')']); + expect(parser.parse(secondInput).value, ['(', '(5 + 5', ')']); + }); + test('recursive', () { + final inner = undefined(); + final parser = char('(') & inner.starLazy(char(')')).flatten() & char(')'); + inner.set(parser | any()); + expect(parser.parse(firstInput).value, ['(', 'use = "official"', ')']); + expect(parser.parse(secondInput).value, ['(', '(5 + 5) * 5', ')']); + }); + test('recursive (better)', () { + final inner = undefined(); + final parser = char('(') & inner.star().flatten() & char(')'); + inner.set(parser | pattern('^)')); + expect(parser.parse(firstInput).value, ['(', 'use = "official"', ')']); + expect(parser.parse(secondInput).value, ['(', '(5 + 5) * 5', ')']); + }); + }); + group('github.com/petitparser/dart-petitparser/issues/112', () { + final inner = digit() & digit(); + test('original', () { + final parser = inner.callCC((continuation, context) { + final result = continuation(context); + if (result.isSuccess && result.value[0] != result.value[1]) { + return context.failure('values do not match'); + } else { + return result; + } + }); + expect(isParseSuccess(parser, '11'), null); //['1', '1'] + // expect(parser, isParseSuccess('22', ['2', '2'])); + // expect(parser, isParseSuccess('33', ['3', '3'])); + expect(parser, null); + }); + test('where', () { + final parser = inner.where((value) => value[0] == value[1], failureMessage: (value) => 'values do not match'); + expect(parser, null); + expect(isParseSuccess(parser, '33'), null); //['1', '1'] + }); + }); + test('https://github.com/petitparser/dart-petitparser/issues/121', () { + final parser = + (((letter() | char('_')) & (letter() | digit() | anyOf('_- ()')).star() & char('.').not('end of id expected'))) + .flatten(); + expect(parser, null); + expect(parser, null); + }); + test('https://github.com/petitparser/dart-petitparser/issues/126', () { + final parser = ParensGrammar().build(); + expect(parser, null); + }); + group('https://stackoverflow.com/questions/73260748', () { + test('Case 1', () { + final parser = resolve(NestedGrammar1().start()); + expect(parser, null); + }); + test('Case 2', () { + final parser = resolve(NestedGrammar2().start()); + expect(parser, null); + }); + test('Case 3', () { + final parser = resolve(NestedGrammar3().start()); + expect(parser, null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_AndParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_AndParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a835cdfc2e8cee2a2f6263a2b242c298181ae8c2 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_AndParser_test.dart @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; + +///AndParser 是一个组合解析器,它会尝试按顺序应用其所有子解析器,如果所有子解析器都成功,那么 AndParser 就会成功。 +class SAndParserTestPage extends TestPage { + SAndParserTestPage(String title, {Key? key}) : super(title, key: key) { + // 创建一个解析器,它会匹配一个数字后面跟着一个空格 + final andParser = digit().seq(char(' ')); + + // 测试解析器 + final result = andParser.parse('J a c k '); + + print(result.isSuccess); + +//-------------构造方法---------------------- + group('Constructors', () { + test('AndParser(Parser delegate)', () { + expect(AndParser(MyParser()).runtimeType, null); + expect(AndParser(MyParser()), null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(andParser.children.runtimeType, null); + expect(andParser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(AndParser(MyParser()).delegate.runtimeType, null); + expect(AndParser(MyParser()).delegate, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + andParser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(andParser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → AndParser', () { + expect(andParser.copy().runtimeType, null); + expect(andParser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(andParser.fastParseOn('789', 1).runtimeType, null); + expect(andParser.fastParseOn('789', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(andParser.hasEqualChildren(AndParser(MyParser()), Set.from([AndParser(MyParser())])).runtimeType, null); + expect(andParser.hasEqualChildren(AndParser(MyParser()), Set.from([AndParser(MyParser())])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(andParser.hasEqualProperties(AndParser(MyParser())).runtimeType, null); + expect(andParser.hasEqualProperties(AndParser(MyParser())), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(andParser.isEqualTo(andParser).runtimeType, null); + expect(andParser.isEqualTo(andParser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(andParser.parse('M a c').runtimeType, null); + expect(andParser.parse('M a c'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(andParser.parseOn(Context(' ', 0)).runtimeType, null); + expect(andParser.parseOn(Context(' ', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + andParser.replace(andParser, AndParser(MyParser())); + expect('', null); + }); + + test('toString() → String', () { + expect(andParser.toString().runtimeType, null); + expect(andParser.toString(), null); + }); + }); + } +} + +class MyParser extends Parser { + @override + Parser copy() { + return MyParser(); + } + + @override + Result parseOn(Context context) { + return Failure("abv", 1, "message"); + } + // @override + // Parser copy() { + // // TODO: implement copy + // throw UnimplementedError(); + // } + + // @override + // Result parseOn(Context context) { + // // TODO: implement parseOn + // throw UnimplementedError(); + // } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_AnyCharacterParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_AnyCharacterParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..d893f892c033eaf33cc6308b7c836d722b87501d --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_AnyCharacterParser_test.dart @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; + +import '../common/test_page.dart'; + +class SAnyCharacterParserTestPage extends TestPage { + SAnyCharacterParserTestPage(String title, {Key? key}) : super(title, key: key) { + const str = '这个类需要5.4.0版本以上才有,但我们目前的flutter SDK 因为依赖了meta 1.8.0, 所以只支持petitparser包的最高版本是5.1.0,因此无法测试这个类'; +//-------------构造方法---------------------- + group('Constructors', () { + test('AnyCharacterParser(String message)', () { + expect(str, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(str, null); + }); + + test('.message → String', () { + expect(str, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect(str, null); + }); + + test('copy() → AnyCharacterParser', () { + expect(str, null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(str, null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(str, null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(str, null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(str, null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(str, null); + }); + + test('parseOn(Context context) → Result', () { + expect(str, null); + }); + + test('replace(Parser source, Parser target) → void', () { + expect(str, null); + }); + + test('toString() → String', () { + expect(str, null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_CastListParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_CastListParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..18f9d234d5cfa8fca6084cae0aac5b11c32f5232 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_CastListParser_test.dart @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///它用于将解析结果的类型从 R 转换为 S。 +class SCastListParserTestPage extends TestPage { + SCastListParserTestPage(String title, {Key? key}) : super(title, key: key) { + // 创建一个解析器 + final andParser = digit().plus().castList().map((list) => list.map(int.parse).toList()); + +//-------------构造方法---------------------- + group('Constructors', () { + test('CastListParser(Parser delegate)', () { + expect(CastListParser(MyParser()).runtimeType, null); + expect(CastListParser(MyParser()), null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(andParser.children.runtimeType, null); + expect(andParser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(AndParser(MyParser()).delegate.runtimeType, null); + expect(AndParser(MyParser()).delegate, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect(andParser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → CastListParser', () { + expect(andParser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(andParser.fastParseOn('3210', 0), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(andParser.hasEqualChildren(AndParser(MyParser()), Set.from([AndParser(MyParser())])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(andParser.hasEqualProperties(andParser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(andParser.isEqualTo(andParser), null); + }); + + test('parse(String input, {int start = 0}) → Result>', () { + expect(andParser.parse('147258369'), null); + }); + + test('parseOn(Context context) → Result>', () { + expect(andParser.parseOn(Context('1234567', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + andParser.replace(andParser, AndParser(MyParser())); + expect('', null); + }); + + test('toString() → String', () { + expect(andParser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_CastParser_testr.dart b/ohos/lz_petitparser_test_os/lib/pages/s_CastParser_testr.dart new file mode 100644 index 0000000000000000000000000000000000000000..d6011c77ca756ce113125c3e65250071bb4ab1f8 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_CastParser_testr.dart @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///它用于将解析结果的类型从 R 转换为 S。 +class SCastParserTestPage extends TestPage { + SCastParserTestPage(String title, {Key? key}) : super(title, key: key) { + final andParser = digit().plus().flatten().cast().map(int.parse); + +//-------------构造方法---------------------- + group('Constructors', () { + test('CastParser(Parser delegate)', () { + expect(CastParser(MyParser()).runtimeType, null); + expect(CastParser(MyParser()), null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(andParser.children.runtimeType, null); + expect(andParser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(AndParser(MyParser()).delegate.runtimeType, null); + expect(AndParser(MyParser()).delegate, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect(andParser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → CastParser', () { + expect(andParser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(andParser.fastParseOn('369258', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(andParser.hasEqualChildren(AndParser(MyParser()), Set.from([AndParser(MyParser())])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(andParser.hasEqualProperties(andParser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(andParser.isEqualTo(andParser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(andParser.parse('123456'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(andParser.parseOn(const Context('123456', 1)).runtimeType, null); + expect(andParser.parseOn(const Context('123456', 1)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + andParser.replace(andParser, AndParser(MyParser())); + expect('', null); + }); + + test('toString() → String', () { + expect(andParser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_CharacterPredicate_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_CharacterPredicate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..d01002a8c9b9e579a11ee579aa7244bfa72cf5fb --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_CharacterPredicate_test.dart @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///CharacterPredicate 是 petitparser 包中的一个抽象类,它用于表示一个字符谓词。 +///这个类定义了一个 test 方法,这个方法接收一个字符的 Unicode 编码,然后返回一个布尔值,表示这个字符是否满足某个条件。 +class SCharacterPredicateTestPage extends TestPage { + SCharacterPredicateTestPage(String title, {Key? key}) : super(title, key: key) { + // 创建一个解析器,它会匹配一个数字后面跟着一个空格 + final andParser = ChoiceParser([ + string('abc'), + string('def'), + string('ghi'), + ]); + print(andParser.parse('abc').isSuccess); // 输出:true + print(andParser.parse('def').isSuccess); // 输出:true + print(andParser.parse('ghi').isSuccess); // 输出:true + print(andParser.parse('xyz').isSuccess); // 输出:false + +//-------------构造方法---------------------- + group('Constructors', () { + test('CharacterPredicate()', () { + expect('CharacterPredicate 是 petitparser 包中的一个抽象类, 不能直接创建', null); + }); + }); + +//-------------属性---------------------- + // group('Properties', () { + // test('.children → List', () { + // expect(andParser.children.runtimeType, null); + // expect(andParser.children, null); + // }); + + // test('.delegate ↔ Parser', () { + // expect(AndParser(MyParser()).delegate.runtimeType, null); + // expect(AndParser(MyParser()).delegate, null); + // }); + // }); + +//-------------对象方法---------------------- + group('Methods', () { + test('isEqualTo(CharacterPredicate other) → bool', () { + expect(andParser.isEqualTo(andParser).runtimeType, null); + expect(andParser.isEqualTo(andParser), null); + }); + + test('test(int value) → bool', () { + expect('5.1.0版本没有此属性', null); + }); + + test('toString() → String', () { + expect(andParser.toString().runtimeType, null); + expect(andParser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_ChoiceParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_ChoiceParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..bf37707da7ec5bb3648d102521f674a11117a0fa --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_ChoiceParser_test.dart @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///ChoiceParser 是 petitparser 包中的一个类,它用于表示一个选择解析器。 +///这个解析器会尝试使用一系列的子解析器来解析输入,只要其中一个子解析器成功,它就会成功。 +///可以使用 ChoiceParser 来创建一个解析器,它可以匹配多种不同的模式。 +class SChoiceParserTestPage extends TestPage { + SChoiceParserTestPage(String title, {Key? key}) : super(title, key: key) { + final choiceParser = ChoiceParser([ + string('abc'), + string('def'), + string('ghi'), + ]); + print(choiceParser.parse('abc').isSuccess); // 输出:true + print(choiceParser.parse('def').isSuccess); // 输出:true + print(choiceParser.parse('ghi').isSuccess); // 输出:true + print(choiceParser.parse('xyz').isSuccess); // 输出:false +//-------------构造方法---------------------- + group('Constructors', () { + test('ChoiceParser(Iterable> children, {FailureJoiner? failureJoiner})', () { + expect( + ChoiceParser([ + string('abc'), + string('def'), + string('ghi'), + ]).runtimeType, + null); + expect(choiceParser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(choiceParser.children.runtimeType, null); + expect(choiceParser.children, null); + }); + + test('.failureJoiner → FailureJoiner', () { + expect(choiceParser.failureJoiner.runtimeType, null); + expect(choiceParser.failureJoiner, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + choiceParser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(choiceParser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → choiceParser', () { + expect(choiceParser.copy().runtimeType, null); + expect(choiceParser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(choiceParser.fastParseOn('258369', 1).runtimeType, null); + expect(choiceParser.fastParseOn('258369', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(choiceParser.hasEqualChildren(choiceParser, Set.from([choiceParser])).runtimeType, null); + expect(choiceParser.hasEqualChildren(choiceParser, Set.from([choiceParser])), null); + }); + + test('hasEqualProperties(covariant ChoiceParser other) → bool', () { + expect(choiceParser.hasEqualProperties(choiceParser).runtimeType, null); + expect(choiceParser.hasEqualProperties(choiceParser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(choiceParser.isEqualTo(choiceParser).runtimeType, null); + expect(choiceParser.isEqualTo(choiceParser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(choiceParser.parse('abc').runtimeType, null); + expect(choiceParser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(choiceParser.parseOn(Context('abc', 0)).runtimeType, null); + expect(choiceParser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + choiceParser.replace(choiceParser, choiceParser); + expect('', null); + }); + + test('toString() → String', () { + expect(choiceParser.toString().runtimeType, null); + expect(choiceParser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_ContinuationParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_ContinuationParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..811c86e36b1df41b5fc2560453b1e7a4ea91e091 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_ContinuationParser_test.dart @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///ContinuationParser 是 petitparser 包中的一个类,它用于创建一个解析器, +///这个解析器会在另一个解析器成功解析输入后,调用一个函数来处理解析的结果。 +///在 ContinuationParser 中,R 是原始解析结果的类型,S 是转换后的类型。 +///你需要提供一个函数,这个函数接收一个 R 类型的值,然后返回一个 S 类型的值。 + +class SContinuationParserTestPage extends TestPage { + SContinuationParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = ContinuationParser( + ChoiceParser([ + string('abc'), + string('def'), + string('ghi'), + ]), (ContinuationFunction t, Context context) { + return t(context); + }); + +//-------------构造方法---------------------- + group('Constructors', () { + test('ContinuationParser(Parser delegate, ContinuationHandler handler)', () { + expect( + ContinuationParser( + ChoiceParser([ + string('abc'), + string('def'), + string('ghi'), + ]), (ContinuationFunction t, Context context) { + return t(context); + }).runtimeType, + null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.handler → ContinuationHandler', () { + expect(parser.handler.runtimeType, null); + expect(parser.handler, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → ContinuationParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant ContinuationParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_DelegateParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_DelegateParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..def5271a6ccf35977fdc1d83ac504c6d8238ae2e --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_DelegateParser_test.dart @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///DelegateParser 是 petitparser 包中的一个类,它用于创建一个解析器,这个解析器会将解析任务委托给另一个解析器。 +///可以使用 DelegateParser 来创建一个解析器,它可以将工作委托给另一个解析器,但在解析成功后,你可以对结果进行处理。 + +class SDelegateParserTestPage extends TestPage { + SDelegateParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = IntParser(digit().plus().flatten()); + final result = parser.parse('12345'); + print(result.value); // 输出:12345 + +//-------------构造方法---------------------- + group('Constructors', () { + test('DelegateParser(Parser delegate)', () { + expect('CharacterPredicate 是 petitparser 包中的一个抽象类, 不能直接创建', null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → parser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('12345', 1).runtimeType, null); + expect(parser.fastParseOn('12345', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('12345').runtimeType, null); + expect(parser.parse('12345'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('123', 0)).runtimeType, null); + expect(parser.parseOn(Context('123', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} + +class IntParser extends DelegateParser { + IntParser(super.delegate); + + // IntParser(Parser delegate) : super(delegate); + + @override + Parser copy() { + return IntParser(super.delegate); + } + + @override + Result parseOn(Context context) { + final result = delegate.parseOn(context); + if (result.isSuccess) { + return result.success(int.parse(result.value)); + } else { + return result; + } + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_DigitCharPredicate_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_DigitCharPredicate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..9c7f61702f7d61af9bb27a99057db713e1e16123 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_DigitCharPredicate_test.dart @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///DigitCharPredicate 是 petitparser 包中的一个类,它是 CharacterPredicate 的一个实现,用于判断一个字符是否为数字。 +class SDigitCharPredicateTestPage extends TestPage { + SDigitCharPredicateTestPage(String title, {Key? key}) : super(title, key: key) { + final digitCharPredicate = DigitCharPredicate(); + print(digitCharPredicate.test('1'.codeUnitAt(0))); // 输出:true + print(digitCharPredicate.test('a'.codeUnitAt(0))); // 输出:false + +//-------------构造方法---------------------- + group('Constructors', () { + test('DigitCharPredicate()', () { + expect(DigitCharPredicate().runtimeType, null); + expect(digitCharPredicate, null); + }); + }); + +//-------------属性---------------------- + // group('Properties', () { + // test('.children → List', () { + // expect(digitCharPredicate.children.runtimeType, null); + // expect(digitCharPredicate.children, null); + // }); + + // test('.delegate ↔ Parser', () { + // expect(AndParser(MyParser()).delegate.runtimeType, null); + // expect(AndParser(MyParser()).delegate, null); + // }); + // }); + +//-------------对象方法---------------------- + group('Methods', () { + test('isEqualTo(CharacterPredicate other) → bool', () { + expect(digitCharPredicate.isEqualTo(digitCharPredicate).runtimeType, null); + expect(digitCharPredicate.isEqualTo(digitCharPredicate), null); + }); + + test('test(int value) → bool', () { + expect(digitCharPredicate.test('1'.codeUnitAt(0)).runtimeType, null); + expect(digitCharPredicate.test('1'.codeUnitAt(0)), null); + }); + + test('toString() → String', () { + expect(digitCharPredicate.toString().runtimeType, null); + expect(digitCharPredicate.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_EndOfInputParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_EndOfInputParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..3ac8d78f6cbcc1594ff7ba162f4fd1e5b54396ff --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_EndOfInputParser_test.dart @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///EndOfInputParser 是 petitparser 包中的一个类,它是 Parser 的一个实现,用于判断是否已经到达输入的末尾。 + +class SEndOfInputParserTestPage extends TestPage { + SEndOfInputParserTestPage(String title, {Key? key}) : super(title, key: key) { + // final parser = EndOfInputParser('解析错误'); + final parser = digit().seq(EndOfInputParser('')); + print(parser.parse('1').isSuccess); // 输出:true + print(parser.parse('12').isSuccess); // 输出:false + /**在这个例子中,我们首先创建了一个解析器,它会匹配一个数字字符,然后期望输入结束(使用 end() 方法创建了一个 EndOfInputParser)。 + * 然后,我们使用这个解析器来解析两个输入:'1' 和 '12'。对于 '1',解析成功,因为匹配了一个数字字符后,输入结束。 + * 对于 '12',解析失败,因为匹配了一个数字字符后,输入并未结束。 */ + +//-------------构造方法---------------------- + group('Constructors', () { + test('EndOfInputParser(String message)', () { + expect(EndOfInputParser('').runtimeType, null); + expect(EndOfInputParser(''), null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.message → String', () { + expect(EndOfInputParser('').message.runtimeType, null); + expect(EndOfInputParser('').message, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → EndOfInputParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('1').runtimeType, null); + expect(parser.parse('1'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(const Context('6', 0)).runtimeType, null); + expect(parser.parseOn(const Context('6', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_EpsilonParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_EpsilonParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..5aae81c54ccbde44423053d814003c4a0b2fc00a --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_EpsilonParser_test.dart @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///EpsilonParser 是 petitparser 包中的一个类,它是一个特殊的解析器,总是成功并返回一个固定的值,但不消耗输入。 + +class SEpsilonParserTestPage extends TestPage { + SEpsilonParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = EpsilonParser('Hello, World!'); + final result = parser.parse(''); + print(result.isSuccess); // 输出:true + print(result.value); // 输出:Hello, World! + +//-------------构造方法---------------------- + group('Constructors', () { + test('EpsilonParser(R result)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.result → R', () { + expect(parser.result.runtimeType, null); + expect(parser.result, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → EpsilonParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant EpsilonParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_FailureParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_FailureParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..deccfe6ad33af1ef09dc092bcf6fd80c3e0bc27a --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_FailureParser_test.dart @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///FailureParser 是 Flutter 中 PetitParser 包的一个类,它是一个特殊的解析器,始终失败并返回一个特定的消息。 +///这可以用来覆盖默认的错误消息,或者在构建复杂的解析器时提供更具体的错误消息。 + +class SFailureParserTestPage extends TestPage { + SFailureParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = FailureParser('Expected a digit'); + +//-------------构造方法---------------------- + group('Constructors', () { + test('FailureParser(String message)', () { + expect(FailureParser('解析错误提醒').runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.message → String', () { + expect(parser.message.runtimeType, null); + expect(parser.message, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → FailureParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant FailureParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_FlattenParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_FlattenParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..7d20de4a2233300535eb68c80c632c163af9b609 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_FlattenParser_test.dart @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///FlattenParser 是 Flutter 中 PetitParser 包中的一个类,它的作用是将一个解析器返回的结果转化为字符串。 + +class SFlattenParserTestPage extends TestPage { + SFlattenParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = digit().plus().flatten(); + var result = parser.parse('12345'); + + if (result.isSuccess) { + print('Parsed value: ${result.value}'); + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('FlattenParser(Parser delegate, [String? message])', () { + expect(FlattenParser(MyParser()).runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(FlattenParser(MyParser()).delegate.runtimeType, null); + expect(FlattenParser(MyParser()).delegate, null); + }); + + test('.message → String', () { + expect(FlattenParser(MyParser(), 'abc').message.runtimeType, null); + expect(FlattenParser(MyParser(), 'abc').message, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → FlattenParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant FlattenParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_GreedyRepeatingParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_GreedyRepeatingParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ad618553731f4de6ea9b4a27ad0f4510dfa59913 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_GreedyRepeatingParser_test.dart @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///GreedyRepeatingParser 是 Flutter 中 PetitParser 包的一个类,它用于创建一个贪婪的重复解析器。 +///这种解析器尝试尽可能多地匹配输入,直到无法再匹配为止。 + +class SGreedyRepeatingParserTestPage extends TestPage { + SGreedyRepeatingParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = word().repeatGreedy(digit(), 1, 3) as GreedyRepeatingParser; + + var result = parser.parse('abc123'); + + if (result.isSuccess) { + print('Parsed value: ${result.value}'); + } + /**在这个例子中,我们创建了一个解析器,它尝试解析一到三个单词字符 (word() 解析器), + * 并且尽可能地忽略任何数字 (digit() 解析器)。 + * 当我们解析字符串 'abc123' 时,解析器会尽可能多地匹配单词字符,并忽略后面的数字。 + * 因此,打印的结果将是 ['a', 'b', 'c']。 */ + +//-------------构造方法---------------------- + group('Constructors', () { + test('GreedyRepeatingParser(Parser parser, Parser limit, int min, int max)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.limit ↔ Parser', () { + expect(parser.limit.runtimeType, null); + expect(parser.limit, null); + }); + + test('.max → int', () { + expect(parser.max.runtimeType, null); + expect(parser.max, null); + }); + + test('.min → int', () { + expect(parser.min.runtimeType, null); + expect(parser.min, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → GreedyRepeatingParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant RepeatingParser> other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result>', () { + expect(parser.parse('a').runtimeType, null); + expect(parser.parse('a'), null); + }); + + test('parseOn(Context context) → Result>', () { + expect(parser.parseOn(Context('a', 0)).runtimeType, null); + expect(parser.parseOn(Context('a', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_LabelParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_LabelParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c05e7584062b4c4217b031d14f26e1c823842681 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_LabelParser_test.dart @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///LabelParser 是 PetitParser 包中的一个类,它用于为解析器结果添加标签。 +///这样,当解析成功时,你可以通过标签获取解析结果。 +///然而,你常不会直接使用 LabelParser,而是使用 Parser 的 permute() 方法来创建带有标签的解析器。 + +class SLabelParserTestPage extends TestPage { + SLabelParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = LabelParser(MyParser(), 'a'); + +//-------------构造方法---------------------- + group('Constructors', () { + test('LabelParser(Parser delegate, String label)', () { + expect(LabelParser(MyParser(), 'a').runtimeType, null); + expect(LabelParser(MyParser(), 'a'), null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.label → String', () { + expect(parser.label.runtimeType, null); + expect(parser.label, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → LabelParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_LabeledParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_LabeledParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..75e16f32f1d68ce8ec0aa1f9d14530bd30f23c1e --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_LabeledParser_test.dart @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///LabeledParser 是 Flutter 中 PetitParser 包的一个类,它用于给解析器添加标签。 +///这样,当解析成功时,可以通过标签获取解析结果。 + +class SLabeledParserTestPage extends TestPage { + SLabeledParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = LabelParser(MyParser(), 'a'); + +//-------------构造方法---------------------- + group('Constructors', () { + test('LabeledParser()', () { + expect('LabeledParser 是 petitparser 包中的一个抽象类, 不能直接创建', null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.label → String', () { + expect(parser.label.runtimeType, null); + expect(parser.label, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → parser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_LazyRepeatingParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_LazyRepeatingParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e5a8448d6bc72618b3eebfe9fc77edb8e4896a40 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_LazyRepeatingParser_test.dart @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///LazyRepeatingParser 是 PetitParser 包中的一个类,它表示一个懒加载的重复解析器。 +///这种解析器会尽可能多地匹配输入,但在匹配失败时会回退并尝试其他可能的匹配。 +///它与 GreedyRepeatingParser 的主要区别在于,LazyRepeatingParser 会尽可能少地匹配输入。 + +class SLazyRepeatingParserTestPage extends TestPage { + SLazyRepeatingParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = word().repeatLazy(digit(), 1, 3) as LazyRepeatingParser; + + var result = parser.parse('abc123'); + if (result.isSuccess) { + print('Parsed value: ${result.value}'); + } + /**在这个例子中,我们创建了一个解析器,它尝试解析一到三个单词字符 (word() 解析器), + * 并且尽可能地忽略任何数字 (digit() 解析器)。 + * 当我们解析字符串 'abc123' 时,解析器会尽可能少地匹配单词字符,并忽略后面的数字。 + * 因此,打印的结果将是 ['a']。 */ + +//-------------构造方法---------------------- + group('Constructors', () { + test('LazyRepeatingParser(Parser parser, Parser limit, int min, int max)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.limit ↔ Parser', () { + expect(parser.limit.runtimeType, null); + expect(parser.limit, null); + }); + + test('.max → int', () { + expect(parser.max.runtimeType, null); + expect(parser.max, null); + }); + + test('.min → int', () { + expect(parser.min.runtimeType, null); + expect(parser.min, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → LazyRepeatingParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant RepeatingParser> other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_LetterCharPredicate_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_LetterCharPredicate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..25ba1db516c8a97110d9aa2ff282f08d053c3f92 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_LetterCharPredicate_test.dart @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///LetterCharPredicate 是 PetitParser 包中的一个类,它是 CharacterPredicate 的实现。 +///这个类用于检查一个字符是否是字母。 +///它的 test 方法接受一个字符的 Unicode 码点,并返回该字符是否是字母。 + +class SLetterCharPredicateTestPage extends TestPage { + SLetterCharPredicateTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = const LetterCharPredicate(); + + print(parser.test('a'.codeUnitAt(0))); // 打印: true + print(parser.test('1'.codeUnitAt(0))); // 打印: false + + /**在这个例子中,我们创建了一个 LetterCharPredicate 对象,并测试了两个字符 'a' 和 '1'。 + * 对于 'a',test 方法返回 true,因为 'a' 是一个字母;对于 '1',test 方法返回 false, + * 因为 '1' 不是一个字母。 */ + +//-------------构造方法---------------------- + group('Constructors', () { + test('LetterCharPredicate()', () { + expect(LetterCharPredicate().runtimeType, null); + expect(LetterCharPredicate(), null); + }); + }); + +//-------------属性---------------------- + +//-------------对象方法---------------------- + group('Methods', () { + test('isEqualTo(CharacterPredicate other) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('test(int value) → bool', () { + expect(parser.test('a'.codeUnitAt(0)).runtimeType, null); + expect(parser.test('a'.codeUnitAt(0)), null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_LimitedRepeatingParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_LimitedRepeatingParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a5d8937b519a125506f83037d9d0b10816aa03cc --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_LimitedRepeatingParser_test.dart @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; +import 's_DelegateParser_test.dart'; + +///LimitedRepeatingParser 是 PetitParser 包中的一个类,它表示一个有限重复的解析器。 +///这种解析器会尝试匹配输入,直到达到指定的次数或者无法匹配为止。 + +class SLimitedRepeatingParserTestPage extends TestPage { + SLimitedRepeatingParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = MyLimitedRepeatingParser(MyParser(), IntParser(digit().plus().flatten()), 1, 5); + + var result = parser.parse('abc123'); + if (result.isSuccess) { + print('Parsed value: ${result.value}'); + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('LimitedRepeatingParser(Parser delegate, Parser limit, int min, int max)', () { + expect('LimitedRepeatingParser 是 petitparser 包中的一个抽象类, 不能直接创建', null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.limit ↔ Parser', () { + expect(parser.limit.runtimeType, null); + expect(parser.limit, null); + }); + + test('.max → int', () { + expect(parser.max.runtimeType, null); + expect(parser.max, null); + }); + + test('.min → int', () { + expect(parser.min.runtimeType, null); + expect(parser.min, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → Parser>', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant RepeatingParser> other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} + +class MyLimitedRepeatingParser extends LimitedRepeatingParser { + MyLimitedRepeatingParser(super.delegate, super.limit, super.min, super.max); + @override + Parser copy() { + return MyLimitedRepeatingParser(super.delegate, super.limit, super.min, super.max); + } + + @override + Result parseOn(Context context) { + final result = delegate.parseOn(context); + if (result.isSuccess) { + return result.success((result.value)); + } else { + // throw UnimplementedError(); + } + return const Failure('ab', 1, 'ab'); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_ListParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_ListParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..4088380f040be5a511e205bdf90d15e86d511533 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_ListParser_test.dart @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; +import 's_DelegateParser_test.dart'; + +///以某种方式解析事物列表的抽象解析器。 + +class SListParserTestPage extends TestPage { + SListParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = MyListParser([MyParser()]); + + var result = parser.parse('abc123'); + if (result.isSuccess) { + print('Parsed value: ${result.value}'); + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('ListParser(Iterable> children)', () { + expect('ListParser 是 petitparser 包中的一个抽象类, 不能直接创建', null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → parser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} + +class MyListParser extends ListParser { + MyListParser(super.children); + + @override + Parser copy() { + return MyListParser(super.children); + } + + @override + Result parseOn(Context context) { + return const Success('12', 1, 3); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_LowercaseCharPredicate_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_LowercaseCharPredicate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..2249eacae94d2f6d67b2d1f100239e4bb906a031 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_LowercaseCharPredicate_test.dart @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +class SLowercaseCharPredicateTestPage extends TestPage { + SLowercaseCharPredicateTestPage(String title, {Key? key}) : super(title, key: key) { + const parser = LowercaseCharPredicate(); + +//-------------构造方法---------------------- + group('Constructors', () { + test('LowercaseCharPredicate()', () { + expect(LowercaseCharPredicate().runtimeType, null); + expect(LowercaseCharPredicate(), null); + }); + }); + +//-------------属性---------------------- + +//-------------对象方法---------------------- + group('Methods', () { + test('isEqualTo(CharacterPredicate other) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('test(int value) → bool', () { + expect(parser.test('a'.codeUnitAt(0)).runtimeType, null); + expect(parser.test('a'.codeUnitAt(0)), null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_MapParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_MapParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..533918774d0ffb8090a26fa4bdf1b318d2b20356 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_MapParser_test.dart @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; +import 's_DelegateParser_test.dart'; + +///一个解析器,它使用给定函数对委托的成功解析结果执行转换。 + +class SMapParserTestPage extends TestPage { + SMapParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = MapParser(MyParser(), (int num) { + return num.toString(); + }); +//-------------构造方法---------------------- + group('Constructors', () { + test('MapParser(Parser delegate, Callback callback, {bool hasSideEffects = false})', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.callback → Callback', () { + expect(parser.callback.runtimeType, null); + expect(parser.callback, null); + }); + + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.hasSideEffects → bool', () { + expect('5.1.0版本没有此属性', null); + // expect(parser.hasSideEffects.runtimeType, null); + // expect(parser.hasSideEffects, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → MapParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant MapParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} + +class MyListParser extends ListParser { + MyListParser(super.children); + + @override + Parser copy() { + return MyListParser(super.children); + } + + @override + Result parseOn(Context context) { + return const Success('12', 1, 3); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_NewlineParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_NewlineParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..32f20426724c6d5c1df50deb861974ae18d4fbc1 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_NewlineParser_test.dart @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///FlattenParser 是 Flutter 中 PetitParser 包中的一个类,它的作用是将一个解析器返回的结果转化为字符串。 + +class SNewlineParserTestPage extends TestPage { + SNewlineParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = NewlineParser('abcde new line'); +//-------------构造方法---------------------- + group('Constructors', () { + test('NewlineParser(String message)', () { + expect(NewlineParser('new line').runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.message → String', () { + expect(parser.message.runtimeType, null); + expect(parser.message, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → NewlineParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_NotParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_NotParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ec853a89b9738ba935f757fec6d8cb8e23565155 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_NotParser_test.dart @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///非谓词,只要其委托不成功,解析器就会成功,但不消耗任何输入 + +class SNotParserTestPage extends TestPage { + SNotParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = NotParser(MyParser(), 'abcde new line'); +//-------------构造方法---------------------- + group('Constructors', () { + test('NotParser(Parser delegate, String message)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.message → String', () { + expect(parser.message.runtimeType, null); + expect(parser.message, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → NotParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant NotParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_OptionalParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_OptionalParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..53a517bab0bfd1a919fe115ec271f96de0a68a29 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_OptionalParser_test.dart @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///一个解析器,可以选择解析其委托,或者回答 null。 + +class SOptionalParserTestPage extends TestPage { + SOptionalParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = OptionalParser(MyParser(), 'abcde new line'); +//-------------构造方法---------------------- + group('Constructors', () { + test('OptionalParser(Parser delegate, R otherwise)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.otherwise → R', () { + expect(parser.otherwise.runtimeType, null); + expect(parser.otherwise, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → OptionalParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant OptionalParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_Parser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_Parser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..8e2e307bb454bda011814b03ea522d3b1e045b38 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_Parser_test.dart @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///一个解析器,可以选择解析其委托,或者回答 null。 + +class SParserTestPage extends TestPage { + SParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = OptionalParser(MyParser(), 'abcde new line'); +//-------------构造方法---------------------- + group('Constructors', () { + test('Parser()', () { + expect('LimitedRepeatingParser 是 petitparser 包中的一个抽象类, 不能直接创建', null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → parser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_PatternParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_PatternParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ce8c649f88e6ec633a7a7c576fe1d2fcb477fedf --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_PatternParser_test.dart @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///使用模式匹配器进行解析的解析器。 + +class SPatternParserTestPage extends TestPage { + SPatternParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = PatternParser('abc', 'msg'); +//-------------构造方法---------------------- + group('Constructors', () { + test('PatternParser(Pattern pattern, String message)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.pattern → Pattern', () { + expect(parser.pattern.runtimeType, null); + expect(parser.pattern, null); + }); + + test('.message → String', () { + expect(parser.message.runtimeType, null); + expect(parser.message, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → PatternParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_PermuteParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_PermuteParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..96260a1e8e8bd7297360802d33959be610d4d1f2 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_PermuteParser_test.dart @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///一个解析器,它使用给定函数对委托的成功解析结果执行转换。 + +class SPermuteParserTestPage extends TestPage { + SPermuteParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = PermuteParser(MyParser(), [1]); +//-------------构造方法---------------------- + group('Constructors', () { + test('PermuteParser(Parser> delegate, List indexes)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.indexes → List', () { + expect(parser.indexes.runtimeType, null); + expect(parser.indexes, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → PermuteParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant ContinuationParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result>', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result>', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_PickParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_PickParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..1edc52ce17d876f3d52da4c50d96db7c4cb11da9 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_PickParser_test.dart @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///一个解析器,它使用给定函数对委托的成功解析结果执行转换。 + +class SPickParserTestPage extends TestPage { + SPickParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = PickParser(MyParser(), 1); +//-------------构造方法---------------------- + group('Constructors', () { + test('PickParser(Parser> delegate, int index)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List)', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.index → int', () { + expect(parser.index.runtimeType, null); + expect(parser.index, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → PickParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant PickParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_PositionParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_PositionParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..9c4df73e04527a24a84eb7280825dfac96cfb58a --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_PositionParser_test.dart @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///报告当前输入位置的解析器。 + +class SPositionParserTestPage extends TestPage { + SPositionParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = PositionParser(); +//-------------构造方法---------------------- + group('Constructors', () { + test('PositionParser()', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → PositionParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('abc', 1).runtimeType, null); + expect(parser.fastParseOn('abc', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('abc').runtimeType, null); + expect(parser.parse('abc'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('abc', 0)).runtimeType, null); + expect(parser.parseOn(Context('abc', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_PossessiveRepeatingParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_PossessiveRepeatingParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..395ac0fe3b3585a8f1b783d681e8124d102a1543 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_PossessiveRepeatingParser_test.dart @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///PossessiveRepeatingParser类是PetitParser库中的一个类,该类提供了一个“占有型”重复解析器。 +///这种解析器在解析输入时,会尽可能多地匹配输入,而不会进行回溯。这与标准的RepeatingParser不同,后者在匹配失败时会尝试回溯并减少重复的次数。 + +class SPossessiveRepeatingParserTestPage extends TestPage { + SPossessiveRepeatingParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = word().star() as PossessiveRepeatingParser; + +//-------------构造方法---------------------- + group('Constructors', () { + test('PossessiveRepeatingParser(Parser parser, int min, int max)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.max → int', () { + expect(parser.max.runtimeType, null); + expect(parser.max, null); + }); + + test('.min → int', () { + expect(parser.min.runtimeType, null); + expect(parser.min, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → PossessiveRepeatingParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant RepeatingParser> other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_PredicateParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_PredicateParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c8ad3e2267dfb1d3f904ed59523a311abd2642e5 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_PredicateParser_test.dart @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///它提供了一个基于谓词函数的解析器。 +///这种解析器在解析输入时,会对每个输入字符应用谓词函数,如果函数返回true,则匹配成功,否则匹配失败。 + +class SPredicateParserTestPage extends TestPage { + SPredicateParserTestPage(String title, {Key? key}) : super(title, key: key) { + // 创建一个解析器,它期望看到一个大写字母 + final parser = PredicateParser( + 1, + (String input) => input.codeUnitAt(0) >= 'A'.codeUnitAt(0) && input.codeUnitAt(0) <= 'Z'.codeUnitAt(0), + 'Expected a capital letter'); + + // 解析输入 + final result1 = parser.parse('A'); + final result2 = parser.parse('a'); + + // 打印结果 + print(result1.isSuccess); // 输出:true + print(result2.isSuccess); // 输出:false + if (!result2.isSuccess) { + print(result2.message); // 输出:Expected a capital letter + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('PredicateParser(int length, Predicate predicate, String message)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.length → int', () { + expect(parser.length.runtimeType, null); + expect(parser.length, null); + }); + + test('.message → String', () { + expect(parser.message.runtimeType, null); + expect(parser.message, null); + }); + + test('.predicate → Predicate', () { + expect(parser.predicate.runtimeType, null); + expect(parser.predicate, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → PredicateParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_RangeCharPredicate_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_RangeCharPredicate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ec8793f470835fd2b456da83235eef0e42c95dce --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_RangeCharPredicate_test.dart @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///它提供了一个基于字符范围的谓词。这种谓词在检查输入字符时,会判断该字符是否在指定的字符范围内。 + +class SRangeCharPredicateTestPage extends TestPage { + SRangeCharPredicateTestPage(String title, {Key? key}) : super(title, key: key) { + // 创建一个解析器,它期望看到一个大写字母 + final predicate = RangeCharPredicate('A'.codeUnitAt(0), 'Z'.codeUnitAt(0)); +//-------------构造方法---------------------- + group('Constructors', () { + test('RangeCharPredicate(int start, int stop)', () { + expect(predicate.runtimeType, null); + expect(predicate, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.start → int', () { + expect(predicate.start.runtimeType, null); + expect(predicate.start, null); + }); + + test('.stop → int', () { + expect(predicate.stop.runtimeType, null); + expect(predicate.stop, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('isEqualTo(CharacterPredicate other) → bool', () { + expect(predicate.isEqualTo(predicate).runtimeType, null); + expect(predicate.isEqualTo(predicate), null); + }); + + test('test(int value) → bool', () { + expect(predicate.test(1).runtimeType, null); + expect(predicate.test(1), null); + }); + + test('toString() → String', () { + expect(predicate.toString().runtimeType, null); + expect(predicate.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_RepeatingCharacterParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_RepeatingCharacterParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..6b077e348f294bb1e9d621d70c87f770db0d9c72 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_RepeatingCharacterParser_test.dart @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于解析重复的字符。这个解析器会尝试匹配一个字符重复多次的情况。 + +class SRepeatingCharacterParserTestPage extends TestPage { + SRepeatingCharacterParserTestPage(String title, {Key? key}) : super(title, key: key) { + const str = + '这个类需要5.4.0版本以上才有,但我们目前的flutter SDK 因为依赖了meta 1.8.0, 所以只支持petitparser包的最高版本是5.1.0,因此无法测试这个类'; // 创建一个 RepeatingCharacterParser,它会匹配字符 'a' 重复2到4次的情况 + final parser = word().repeatGreedy(digit(), 1, 3) as GreedyRepeatingParser; + + var result = parser.parse('abc123'); + + if (result.isSuccess) { + print('Parsed value: ${result.value}'); + } + /**在这个例子中,我们创建了一个解析器,它尝试解析一到三个单词字符 (word() 解析器), + * 并且尽可能地忽略任何数字 (digit() 解析器)。 + * 当我们解析字符串 'abc123' 时,解析器会尽可能多地匹配单词字符,并忽略后面的数字。 + * 因此,打印的结果将是 ['a', 'b', 'c']。 */ + +//-------------构造方法---------------------- + group('Constructors', () { + test('RepeatingCharacterParser(CharacterPredicate predicate, String message, int min, int max)', () { + expect(str, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(str, null); + }); + + test('.max → int', () { + expect(str, null); + }); + + test('.message → String', () { + expect(str, null); + }); + + test('.min → int', () { + expect(str, null); + }); + + test('.predicate → CharacterPredicate', () { + expect(str, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect(str, null); + }); + + test('copy() → RepeatingCharacterParser', () { + expect(str, null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(str, null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(str, null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(str, null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(str, null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(str, null); + }); + + test('parseOn(Context context) → Result', () { + expect(str, null); + }); + + test('replace(Parser source, Parser target) → void', () { + expect(str, null); + }); + + test('toString() → String', () { + expect(str, null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_RepeatingParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_RepeatingParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e346c5347f5085063211aef5e5f920bd7834090b --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_RepeatingParser_test.dart @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///于解析一个解析器重复多次的情况。这个解析器会尝试匹配一个解析器重复执行多次的情况。 + +class SRepeatingParserTestPage extends TestPage { + SRepeatingParserTestPage(String title, {Key? key}) : super(title, key: key) { + // 创建一个 RepeatingParser,它会匹配字符 'a' 重复2到4次的情况 + final parser = char('a').repeat(2, 4) as PossessiveRepeatingParser; + // 使用解析器去解析字符串 'aaaaa' + final result = parser.parse('aaaaa'); + + if (result.isSuccess) { + // 如果解析成功 + print('Matched: ${result.value}'); // 打印匹配的结果 + } else { + // 如果解析失败 + print('Position ${result.position}: ${result.message}'); // 打印失败的位置和信息 + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('RepeatingParser(Parser parser, int min, int max)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.max → int', () { + expect(parser.max.runtimeType, null); + expect(parser.max, null); + }); + + test('.min → int', () { + expect(parser.min.runtimeType, null); + expect(parser.min, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → RepeatingCharacterParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant RepeatingParser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_ResolvableParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_ResolvableParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..3f5f03f60ea2523e7f7342dc8b8dd5006a3dd830 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_ResolvableParser_test.dart @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于解析那些在解析时可能尚未定义的解析器。这个解析器非常有用,特别是在处理递归语法结构时。 + +class SResolvableParserTestPage extends TestPage { + SResolvableParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = undefined(); + +//-------------构造方法---------------------- + group('Constructors', () { + test('ResolvableParser()', () { + // expect(parser.runtimeType, null); + expect('ResolvableParser为抽象类,不能直接创建', null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → parser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('resolve() → Parser', () { + expect(parser.resolve().runtimeType, null); + expect(parser.resolve(), null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SeparatedList_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SeparatedList_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..271842dc58c396bbad106d5867c1f94121c9ad37 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SeparatedList_test.dart @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于解析一个由特定分隔符分隔的元素列表。 + +class SSeparatedListTestPage extends TestPage { + SSeparatedListTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = SeparatedList(['1,1', '2'], [char(',')]); + +//-------------构造方法---------------------- + group('Constructors', () { + test('SeparatedList(List elements, List separators)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.elements → List', () { + expect(parser.elements.runtimeType, null); + expect(parser.elements, null); + }); + + test('.separators → List', () { + expect(parser.separators.runtimeType, null); + expect(parser.separators, null); + }); + + test('.sequential → Iterable', () { + expect(parser.sequential.runtimeType, null); + expect(parser.sequential, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('foldLeft(R callback(R left, S seperator, R right)) → R', () { + expect( + parser.foldLeft((int left, int seperator, String right) { + return right; + }).runtimeType, + null); + expect(parser.foldLeft((int left, int seperator, String right) { + return right; + }), null); + }); + + test('foldRight(R callback(R left, S seperator, R right)) → R', () { + expect( + parser.foldRight((int left, int seperator, String right) { + return right; + }).runtimeType, + null); + expect(parser.foldRight((int left, int seperator, String right) { + return right; + }), null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SeparatedRepeatingParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SeparatedRepeatingParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c5d8284ddc362446fef0a05e4b91818f4e8ca736 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SeparatedRepeatingParser_test.dart @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///于解析由特定分隔符分隔的元素列表,这个列表的长度在给定的范围内。 + +class SSeparatedRepeatingParserTestPage extends TestPage { + SSeparatedRepeatingParserTestPage(String title, {Key? key}) : super(title, key: key) { + //创建一个 SeparatedRepeatingParser,它会匹配由逗号分隔的数字字符,且这个列表的长度在2到4之间 + final parser = SeparatedRepeatingParser(digit(), char(','), 2, 4); + final result = parser.parse('1,2,3,4'); + + if (result.isSuccess) { + print('Matched: ${result.value}'); + } else { + print('Position ${result.position}: ${result.message}'); + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('SeparatedRepeatingParser(Parser delegate, Parser separator, int min, int max)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.max → int', () { + expect(parser.max.runtimeType, null); + expect(parser.max, null); + }); + + test('.min → int', () { + expect(parser.min.runtimeType, null); + expect(parser.min, null); + }); + + test('.separator ↔ Parser', () { + expect(parser.separator.runtimeType, null); + expect(parser.separator, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SeparatedRepeatingParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant RepeatingParser> other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser2_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser2_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..15d2385df702c2af1c7dc126d252483935afaa12 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser2_test.dart @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于按顺序解析两个解析器。只有当这两个解析器都成功匹配时,SequenceParser2才会成功。 + +class SSequenceParser2TestPage extends TestPage { + SSequenceParser2TestPage(String title, {Key? key}) : super(title, key: key) { + final parser = SequenceParser2(char('a'), char('b')); + final result = parser.parse('ab'); + + if (result.isSuccess) { + print('匹配成功: ${result.value}'); + } else { + print('位置 ${result.position}: ${result.message}'); + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('SequenceParser2(Parser parser1, Parser parser2)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.parser1 ↔ Parser', () { + expect(parser.parser1.runtimeType, null); + expect(parser.parser1, null); + }); + + test('.parser2 ↔ Parser', () { + expect(parser.parser2.runtimeType, null); + expect(parser.parser2, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SequenceParser2', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result<(R1, R2)>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result<(R1, R2)>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser3_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser3_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..7ebac4aa1fe6ea70acd4694a0db51f51dbeea703 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser3_test.dart @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于按顺序解析三个解析器。只有当这三个解析器都成功匹配时,SequenceParser3才会成功。 + +class SSequenceParser3TestPage extends TestPage { + SSequenceParser3TestPage(String title, {Key? key}) : super(title, key: key) { + // 创建一个 SequenceParser3,它会按顺序匹配字符 'a'、'b' 和 'c' + final parser = SequenceParser3(char('a'), char('b'), char('c')); + final result = parser.parse('abc'); + + if (result.isSuccess) { + print('匹配成功: ${result.value}'); + } else { + print('位置 ${result.position}: ${result.message}'); + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('SequenceParser3(Parser parser1, Parser parser2, Parser parser3)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.parser1 ↔ Parser', () { + expect(parser.parser1.runtimeType, null); + expect(parser.parser1, null); + }); + + test('.parser2 ↔ Parser', () { + expect(parser.parser2.runtimeType, null); + expect(parser.parser2, null); + }); + + test('.parser3 ↔ Parser', () { + expect(parser.parser3.runtimeType, null); + expect(parser.parser3, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SequenceParser3', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result<(R1, R2, R3)>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result<(R1, R2, R3)>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser4_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser4_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..f874b3c95637972b38860a245fb2e053a20fd236 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser4_test.dart @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于按顺序解析四个解析器。只有当这四个解析器都成功匹配时,SequenceParser4才会成功。 + +class SSequenceParser4TestPage extends TestPage { + SSequenceParser4TestPage(String title, {Key? key}) : super(title, key: key) { + final parser = + SequenceParser4(char('a'), char('b'), char('c'), char('d')); // 创建一个 SequenceParser4,它会按顺序匹配字符 'a'、'b'、'c' 和 'd' + final result = parser.parse('abcd'); // 使用解析器去解析字符串 'abcd' + + if (result.isSuccess) { + // 如果解析成功 + print('匹配成功: ${result.value}'); // 打印匹配的结果 + } else { + // 如果解析失败 + print('位置 ${result.position}: ${result.message}'); // 打印失败的位置和信息 + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('GSequenceParser4', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.parser1 ↔ Parser', () { + expect(parser.parser1.runtimeType, null); + expect(parser.parser1, null); + }); + + test('.parser2 ↔ Parser', () { + expect(parser.parser2.runtimeType, null); + expect(parser.parser2, null); + }); + + test('.parser3 ↔ Parser', () { + expect(parser.parser3.runtimeType, null); + expect(parser.parser3, null); + }); + + test('.parser4 ↔ Parser', () { + expect(parser.parser4.runtimeType, null); + expect(parser.parser4, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SequenceParser4', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result<(R1, R2, R3, R4)>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result<(R1, R2, R3, R4)>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser5_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser5_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..098803e46f58a1d207f54e7648b3917d5e96ea1a --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser5_test.dart @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于按顺序解析五个解析器。只有当这五个解析器都成功匹配时,SequenceParser5才会成功。 + +class SSequenceParser5TestPage extends TestPage { + SSequenceParser5TestPage(String title, {Key? key}) : super(title, key: key) { + final parser = SequenceParser5( + char('a'), char('b'), char('c'), char('d'), char('e')); // 创建一个 SequenceParser5,它会按顺序匹配字符 'a'、'b'、'c'、'd' 和 'e' + final result = parser.parse('abcde'); // 使用解析器去解析字符串 'abcde' + + if (result.isSuccess) { + // 如果解析成功 + print('匹配成功: ${result.value}'); // 打印匹配的结果 + } else { + // 如果解析失败 + print('位置 ${result.position}: ${result.message}'); // 打印失败的位置和信息 + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('SequenceParser5(Parser parser1, Parser parser2, Parser parser3, Parser parser4, Parser parser5)', + () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.parser1 ↔ Parser', () { + expect(parser.parser1.runtimeType, null); + expect(parser.parser1, null); + }); + + test('.parser2 ↔ Parser', () { + expect(parser.parser2.runtimeType, null); + expect(parser.parser2, null); + }); + + test('.parser3 ↔ Parser', () { + expect(parser.parser3.runtimeType, null); + expect(parser.parser3, null); + }); + + test('.parser4 ↔ Parser', () { + expect(parser.parser4.runtimeType, null); + expect(parser.parser4, null); + }); + test('.parser5 ↔ Parser', () { + expect(parser.parser5.runtimeType, null); + expect(parser.parser5, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SequenceParser5', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result<(R1, R2, R3, R4, R5)>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result<(R1, R2, R3, R4, R5)>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser6_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser6_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..0cf90cdd61e6cd12e7dc761b564bb6b15fed0311 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser6_test.dart @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///GreedyRepeatingParser 是 Flutter 中 PetitParser 包的一个类,它用于创建一个贪婪的重复解析器。 +///这种解析器尝试尽可能多地匹配输入,直到无法再匹配为止。001 + +class SSequenceParser6TestPage extends TestPage { + SSequenceParser6TestPage(String title, {Key? key}) : super(title, key: key) { + final parser = SequenceParser6(char('a'), char('b'), char('c'), char('d'), char('e'), + char('f')); // 创建一个 SequenceParser6,它会按顺序匹配字符 'a'、'b'、'c'、'd'、'e' 和 'f' + final result = parser.parse('abcdef'); // 使用解析器去解析字符串 'abcdef' + + if (result.isSuccess) { + // 如果解析成功 + print('匹配成功: ${result.value}'); // 打印匹配的结果 + } else { + // 如果解析失败 + print('位置 ${result.position}: ${result.message}'); // 打印失败的位置和信息 + } + +//-------------构造方法---------------------- + group('Constructors', () { + test( + 'SequenceParser6(Parser parser1, Parser parser2, Parser parser3, Parser parser4, Parser parser5, Parser parser6)', + () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.parser1 ↔ Parser', () { + expect(parser.parser1.runtimeType, null); + expect(parser.parser1, null); + }); + + test('.parser2 ↔ Parser', () { + expect(parser.parser2.runtimeType, null); + expect(parser.parser2, null); + }); + + test('.parser3 ↔ Parser', () { + expect(parser.parser3.runtimeType, null); + expect(parser.parser3, null); + }); + + test('.parser4 ↔ Parser', () { + expect(parser.parser4.runtimeType, null); + expect(parser.parser4, null); + }); + + test('.parser5 ↔ Parser', () { + expect(parser.parser5.runtimeType, null); + expect(parser.parser5, null); + }); + + test('.parser6 ↔ Parser', () { + expect(parser.parser6.runtimeType, null); + expect(parser.parser6, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SequenceParser6', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result<(R1, R2, R3, R4, R5, R6)>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result<(R1, R2, R3, R4, R5, R6)>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser7_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser7_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a43e11eded4b224eda7ccb973159fcc4fd6e3f9d --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser7_test.dart @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于按顺序解析七个解析器。只有当这七个解析器都成功匹配时,SequenceParser7才会成功。 + +class SSequenceParser7TestPage extends TestPage { + SSequenceParser7TestPage(String title, {Key? key}) : super(title, key: key) { + final parser = SequenceParser7(char('a'), char('b'), char('c'), char('d'), char('e'), char('f'), char('g')); + final result = parser.parse('abcdefg'); + + if (result.isSuccess) { + print('匹配成功: ${result.value}'); + } else { + print('位置 ${result.position}: ${result.message}'); + } + +//-------------构造方法---------------------- + group('Constructors', () { + test( + 'SequenceParser7(Parser parser1, Parser parser2, Parser parser3, Parser parser4, Parser parser5, Parser parser6, Parser parser7)', + () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.parser1 ↔ Parser', () { + expect(parser.parser1.runtimeType, null); + expect(parser.parser1, null); + }); + + test('.parser2 ↔ Parser', () { + expect(parser.parser2.runtimeType, null); + expect(parser.parser2, null); + }); + + test('.parser3 ↔ Parser', () { + expect(parser.parser3.runtimeType, null); + expect(parser.parser3, null); + }); + + test('.parser4 ↔ Parser', () { + expect(parser.parser4.runtimeType, null); + expect(parser.parser4, null); + }); + + test('.parser5 ↔ Parser', () { + expect(parser.parser5.runtimeType, null); + expect(parser.parser5, null); + }); + + test('.parser6 ↔ Parser', () { + expect(parser.parser6.runtimeType, null); + expect(parser.parser6, null); + }); + + test('.parser7 ↔ Parser', () { + expect(parser.parser7.runtimeType, null); + expect(parser.parser7, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SequenceParser7', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result<(R1, R2, R3, R4, R5, R6, R7)>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result<(R1, R2, R3, R4, R5, R6, R7)>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser8_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser8_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..d1d28261292ff9fa60f33fe65b3a25f9bbe2014f --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser8_test.dart @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于按顺序解析八个解析器。只有当这八个解析器都成功匹配时,SequenceParser8才会成功。 + +class SSequenceParser8TestPage extends TestPage { + SSequenceParser8TestPage(String title, {Key? key}) : super(title, key: key) { + final parser = SequenceParser8(char('a'), char('b'), char('c'), char('d'), char('e'), char('f'), char('g'), + char('h')); // 创建一个 SequenceParser8,它会按顺序匹配字符 'a'、'b'、'c'、'd'、'e'、'f'、'g' 和 'h' + final result = parser.parse('abcdefgh'); // 使用解析器去解析字符串 'abcdefgh' + + if (result.isSuccess) { + // 如果解析成功 + print('匹配成功: ${result.value}'); // 打印匹配的结果 + } else { + // 如果解析失败 + print('位置 ${result.position}: ${result.message}'); // 打印失败的位置和信息 + } + +//-------------构造方法---------------------- + group('Constructors', () { + test( + 'SequenceParser8(Parser parser1, Parser parser2, Parser parser3, Parser parser4, Parser parser5, Parser parser6, Parser parser7, Parser parser8)', + () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.parser1 ↔ Parser', () { + expect(parser.parser1.runtimeType, null); + expect(parser.parser1, null); + }); + + test('.parser2 ↔ Parser', () { + expect(parser.parser2.runtimeType, null); + expect(parser.parser2, null); + }); + + test('.parser3 ↔ Parser', () { + expect(parser.parser3.runtimeType, null); + expect(parser.parser3, null); + }); + + test('.parser4 ↔ Parser', () { + expect(parser.parser4.runtimeType, null); + expect(parser.parser4, null); + }); + + test('.parser5 ↔ Parser', () { + expect(parser.parser5.runtimeType, null); + expect(parser.parser5, null); + }); + + test('.parser6 ↔ Parser', () { + expect(parser.parser6.runtimeType, null); + expect(parser.parser6, null); + }); + + test('.parser7 ↔ Parser', () { + expect(parser.parser7.runtimeType, null); + expect(parser.parser7, null); + }); + + test('.parser8 ↔ Parser', () { + expect(parser.parser8.runtimeType, null); + expect(parser.parser8, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SequenceParser8', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result<(R1, R2, R3, R4, R5, R6, R7, R8)>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result<(R1, R2, R3, R4, R5, R6, R7, R8)>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser9_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser9_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ce2186a122a6d025e437e2bec5a5c1b6f8a4f657 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser9_test.dart @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///GreedyRepeatingParser 是 Flutter 中 PetitParser 包的一个类,它用于创建一个贪婪的重复解析器。 +///这种解析器尝试尽可能多地匹配输入,直到无法再匹配为止。001 + +class SSequenceParser9TestPage extends TestPage { + SSequenceParser9TestPage(String title, {Key? key}) : super(title, key: key) { + final parser = SequenceParser9(char('a'), char('b'), char('c'), char('d'), char('e'), char('f'), char('g'), char('h'), + char('i')); // 创建一个 SequenceParser9,它会按顺序匹配字符 'a'、'b'、'c'、'd'、'e'、'f'、'g'、'h' 和 'i' + final result = parser.parse('abcdefghi'); // 使用解析器去解析字符串 'abcdefghi' + + if (result.isSuccess) { + // 如果解析成功 + print('匹配成功: ${result.value}'); // 打印匹配的结果 + } else { + // 如果解析失败 + print('位置 ${result.position}: ${result.message}'); // 打印失败的位置和信息 + } + +//-------------构造方法---------------------- + group('Constructors', () { + test( + 'SequenceParser9(Parser parser1, Parser parser2, Parser parser3, Parser parser4, Parser parser5, Parser parser6, Parser parser7, Parser parser8, Parser parser9)', + () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.parser1 ↔ Parser', () { + expect(parser.parser1.runtimeType, null); + expect(parser.parser1, null); + }); + + test('.parser2 ↔ Parser', () { + expect(parser.parser2.runtimeType, null); + expect(parser.parser2, null); + }); + + test('.parser3 ↔ Parser', () { + expect(parser.parser3.runtimeType, null); + expect(parser.parser3, null); + }); + + test('.parser4 ↔ Parser', () { + expect(parser.parser4.runtimeType, null); + expect(parser.parser4, null); + }); + + test('.parser5 ↔ Parser', () { + expect(parser.parser5.runtimeType, null); + expect(parser.parser5, null); + }); + + test('.parser6 ↔ Parser', () { + expect(parser.parser6.runtimeType, null); + expect(parser.parser6, null); + }); + + test('.parser7 ↔ Parser', () { + expect(parser.parser7.runtimeType, null); + expect(parser.parser7, null); + }); + + test('.parser8 ↔ Parser', () { + expect(parser.parser8.runtimeType, null); + expect(parser.parser8, null); + }); + + test('.parser9 ↔ Parser', () { + expect(parser.parser9.runtimeType, null); + expect(parser.parser9, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SequenceParser9', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result<(R1, R2, R3, R4, R5, R6, R7, R8, R9)>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result<(R1, R2, R3, R4, R5, R6, R7, R8, R9)>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..24e60e86491abdd09fd39537bd6f17e1d56b7a9a --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SequenceParser_test.dart @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于按顺序解析一系列的解析器。只有当所有的解析器都成功匹配时,SequenceParser 才会成功。 + +class SSequenceParserTestPage extends TestPage { + SSequenceParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = SequenceParser([char('a'), char('b'), char('c')]); + final result = parser.parse('abc'); + + if (result.isSuccess) { + print('Matched: ${result.value}'); + } else { + print('Position ${result.position}: ${result.message}'); + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('SequenceParser(Iterable> children)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SequenceParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SettableParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SettableParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ed48102561359245d50965b2984453093cbc6017 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SettableParser_test.dart @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///GSettableParser是一个特殊类型的解析器,它允许你在运行时改变它的行为。 +///这在构建递归下降解析器时非常有用,因为你可以先创建一个空的SettableParser, +///然后在定义解析器的其余部分之后,再设置它的实际行为。 + +class SSettableParserTestPage extends TestPage { + SSettableParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = SettableParser(MyParser()); // 创建一个 SettableParser + +//-------------构造方法---------------------- + group('Constructors', () { + test('SettableParser(Parser delegate)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → SettableParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('resolve() → Parser', () { + expect(parser.resolve().runtimeType, null); + expect(parser.resolve(), null); + }); + + test('set(Parser parser) → void', () { + parser.set(parser); + expect('', null); + }); + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SingleCharPredicate_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SingleCharPredicate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c9d0ecf1bbf5838262f1946ef5428f4024b4126f --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SingleCharPredicate_test.dart @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///SingleCharPredicate是一个字符解析器,它接受一个字符谓词函数来确定是否匹配一个字符。 +///这个谓词函数接受一个字符的Unicode代码点作为输入,并返回一个布尔值来表示是否匹配。 + +class SSingleCharPredicateTestPage extends TestPage { + SSingleCharPredicateTestPage(String title, {Key? key}) : super(title, key: key) { + const parser = SingleCharPredicate(1); + +//-------------构造方法---------------------- + group('Constructors', () { + test('SingleCharPredicate(int value)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.value → int', () { + expect(parser.value.runtimeType, null); + expect(parser.value, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('isEqualTo(CharacterPredicate other) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('test(int value) → bool', () { + expect(parser.test(1).runtimeType, null); + expect(parser.test(1), null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SingleCharacterParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SingleCharacterParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..d245e3b96fabffdf449a2b8869d887175994a67d --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SingleCharacterParser_test.dart @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///用于匹配单个字符。它是PetitParser库中的许多字符解析器的基础。 + +class SSingleCharacterParserTestPage extends TestPage { + SSingleCharacterParserTestPage(String title, {Key? key}) : super(title, key: key) { + const str = '这个类需要5.4.0版本以上才有,但我们目前的flutter SDK 因为依赖了meta 1.8.0, 所以只支持petitparser包的最高版本是5.1.0,因此无法测试这个类'; + +//-------------构造方法---------------------- + group('Constructors', () { + test('SingleCharacterParser(CharacterPredicate predicate, String message)', () { + expect(str, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(str, null); + }); + + test('.message → String', () { + expect(str, null); + }); + + test('.predicate → CharacterPredicate', () { + expect(str, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect(str, null); + }); + + test('copy() → SingleCharacterParser', () { + expect(str, null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(str, null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(str, null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(str, null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(str, null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(str, null); + }); + + test('parseOn(Context context) → Result', () { + expect(str, null); + }); + + test('replace(Parser source, Parser target) → void', () { + expect(str, null); + }); + + test('toString() → String', () { + expect(str, null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_SkipParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_SkipParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..4a6e5713bfd1523d4a92e2e4116514ed23558e2f --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_SkipParser_test.dart @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///SkipParser 是一个解析器,它会跳过输入中的一部分。 +///它会尝试匹配并消耗输入,但是它不会在结果中返回这部分输入。 +///这在希望忽略某些输入(如空格或注释)时非常有用。 + +class SSkipParserTestPage extends TestPage { + SSkipParserTestPage(String title, {Key? key}) : super(title, key: key) { + const str = '这个类需要5.4.0版本以上才有,但我们目前的flutter SDK 因为依赖了meta 1.8.0, 所以只支持petitparser包的最高版本是5.1.0,因此无法测试这个类'; +//-------------构造方法---------------------- + group('Constructors', () { + test('SkipParser(Parser delegate, {required Parser before, required Parser after})', () { + expect(str, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.after ↔ Parser', () { + expect(str, null); + }); + + test('.before ↔ Parser', () { + expect(str, null); + }); + + test('.children → List', () { + expect(str, null); + }); + + test('.delegate ↔ Parser', () { + expect(str, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect(str, null); + }); + + test('copy() → SkipParser', () { + expect(str, null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(str, null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(str, null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(str, null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(str, null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(str, null); + }); + + test('parseOn(Context context) → Result', () { + expect(str, null); + }); + + test('replace(Parser source, Parser target) → void', () { + expect(str, null); + }); + + test('toString() → String', () { + expect(str, null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_TokenParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_TokenParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..dd16b198eb5710dd863227e7d28459a23d9b28ba --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_TokenParser_test.dart @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///TokenParser(Parser delegate) 是一个解析器, +///它会返回一个 Token 对象,该对象包含了匹配到的值,以及这个值在输入中的开始和结束位置。 + +class STokenParserTestPage extends TestPage { + STokenParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = TokenParser(MyParser()); + +//-------------构造方法---------------------- + group('Constructors', () { + test('TokenParser(Parser delegate)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → TokenParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result>', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result>', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_TrimmingParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_TrimmingParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..db8d1100d5c39f5c04c68183a98e96ccdfa31edf --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_TrimmingParser_test.dart @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///TrimmingParser 是一个解析器,它会在解析之前和之后跳过空白字符。 +///这在你想要忽略输入中的空格或者换行符时非常有用。1 + +class STrimmingParserTestPage extends TestPage { + STrimmingParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = char('a').trim() as TrimmingParser; // 创建一个 TrimmingParser,它会匹配字符 'a' 并跳过前后的空白字符 + final result = parser.parse(' a '); // 使用解析器去解析字符串 ' a ' + + if (result.isSuccess) { + // 如果解析成功 + print('匹配成功: ${result.value}'); // 打印匹配的结果 + } else { + // 如果解析失败 + print('位置 ${result.position}: ${result.message}'); // 打印失败的位置和信息 + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('TrimmingParser(Parser delegate, Parser left, Parser right)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.left ↔ Parser', () { + expect(parser.left.runtimeType, null); + expect(parser.left, null); + }); + + test('.right ↔ Parser', () { + expect(parser.right.runtimeType, null); + expect(parser.right, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → TrimmingParser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualChildren(covariant Parser other, Set seen) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_UppercaseCharPredicate_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_UppercaseCharPredicate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..5bbb744644cea901863abb9420a8028da80227bb --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_UppercaseCharPredicate_test.dart @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///UppercaseCharPredicate是一个字符谓词,用于检查一个字符是否为大写字母。 + +class SUppercaseCharPredicateTestPage extends TestPage { + SUppercaseCharPredicateTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = UppercaseCharPredicate(); // 创建一个 UppercaseCharPredicate 实例 + print(parser.test('A'.codeUnitAt(0))); // 检查字符 'A' 是否为大写字母 + print(parser.test('a'.codeUnitAt(0))); // 检查字符 'a' 是否为大写字母 +//-------------构造方法---------------------- + group('Constructors', () { + test('UppercaseCharPredicate()', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + // group('Properties', () { + + // }); + +//-------------对象方法---------------------- + group('Methods', () { + test('isEqualTo(CharacterPredicate other) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('test(int value) → bool', () { + expect(parser.test(1).runtimeType, null); + expect(parser.test(1), null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_WhereParser_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_WhereParser_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e46741979820e655c0499f6b49d2756e868d094f --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_WhereParser_test.dart @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///WhereParser 是一个解析器,它接受一个谓词函数并应用到解析结果上。 +///如果谓词函数返回 true,解析就会成功,否则解析会失败。 + +class SWhereParserTestPage extends TestPage { + SWhereParserTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = + WhereParser(MyParser(), (value) => false, (value) => 'a', (value) => 1); // 创建一个 WhereParser,它会匹配数字字符并检查匹配的字符是否为 '3' + final result = parser.parse('3'); // 使用解析器去解析字符串 '3' + + if (result.isSuccess) { + // 如果解析成功 + print('匹配成功: ${result.value}'); // 打印匹配的结果 + } else { + // 如果解析失败 + print('位置 ${result.position}: ${result.message}'); // 打印失败的位置和信息 + } + +//-------------构造方法---------------------- + group('Constructors', () { + test('WhereParser(Parser parser, Predicate predicate, FailureFactory factory)', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + group('Properties', () { + test('.children → List', () { + expect(parser.children.runtimeType, null); + expect(parser.children, null); + }); + + test('.delegate ↔ Parser', () { + expect(parser.delegate.runtimeType, null); + expect(parser.delegate, null); + }); + + test('.factory → FailureFactory', () { + expect('5.1.0版本没有此属性', null); + // expect(parser.factory.runtimeType, null); + // expect(parser.factory, null); + }); + + test('.predicate → Predicate', () { + expect(parser.predicate.runtimeType, null); + expect(parser.predicate, null); + }); + }); + +//-------------对象方法---------------------- + group('Methods', () { + test('captureResultGeneric(T callback(Parser self)) → T', () { + expect( + parser.captureResultGeneric((Parser self) { + return MyParser(); + }).runtimeType, + null); + expect(parser.captureResultGeneric((Parser self) { + return MyParser(); + }), null); + }); + + test('copy() → parser', () { + expect(parser.copy().runtimeType, null); + expect(parser.copy(), null); + }); + + test('fastParseOn(String buffer, int position) → int', () { + expect(parser.fastParseOn('ab', 1).runtimeType, null); + expect(parser.fastParseOn('ab', 1), null); + }); + + test('hasEqualProperties(covariant WhereParser other) → bool', () { + expect(parser.hasEqualChildren(parser, Set.from([parser])).runtimeType, null); + expect(parser.hasEqualChildren(parser, Set.from([parser])), null); + }); + + test('hasEqualProperties(covariant Parser other) → bool', () { + expect(parser.hasEqualProperties(parser).runtimeType, null); + expect(parser.hasEqualProperties(parser), null); + }); + + test('isEqualTo(Parser other, [Set? seen]) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('parse(String input, {int start = 0}) → Result', () { + expect(parser.parse('ab').runtimeType, null); + expect(parser.parse('ab'), null); + }); + + test('parseOn(Context context) → Result', () { + expect(parser.parseOn(Context('ab', 0)).runtimeType, null); + expect(parser.parseOn(Context('ab', 0)), null); + }); + + test('replace(Parser source, Parser target) → void', () { + parser.replace(parser, parser); + expect('', null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_WhitespaceCharPredicate_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_WhitespaceCharPredicate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..fab14903b120cba43b705dd16698d708ae4b4bab --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_WhitespaceCharPredicate_test.dart @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///WhitespaceCharPredicate 是一个字符谓词,用于检查一个字符是否是空白字符。 + +class SWhitespaceCharPredicateTestPage extends TestPage { + SWhitespaceCharPredicateTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = WhitespaceCharPredicate(); // 创建一个 WhitespaceCharPredicate 实例 + print(parser.test(' '.codeUnitAt(0))); // 检查字符 ' ' 是否是空白字符 + print(parser.test('a'.codeUnitAt(0))); // 检查字符 'a' 是否是空白字符 + +//-------------构造方法---------------------- + group('Constructors', () { + test('WhitespaceCharPredicate()', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + // group('Properties', () { + + // }); + +//-------------对象方法---------------------- + group('Methods', () { + test('isEqualTo(CharacterPredicate other) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('test(int value) → bool', () { + expect(parser.test(1).runtimeType, null); + expect(parser.test(1), null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/s_WordCharPredicate_test.dart b/ohos/lz_petitparser_test_os/lib/pages/s_WordCharPredicate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a0712cbde6320e666cf137cda5ae458e4598d20a --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/s_WordCharPredicate_test.dart @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; + +import '../common/test_page.dart'; +import 's_AndParser_test.dart'; + +///WordCharPredicate 是一个字符谓词,用于检查一个字符是否是字母、数字或下划线。 + +class SWordCharPredicateTestPage extends TestPage { + SWordCharPredicateTestPage(String title, {Key? key}) : super(title, key: key) { + final parser = WordCharPredicate(); // 创建一个 WordCharPredicate 实例 + print(parser.test('a'.codeUnitAt(0))); // 检查字符 'a' 是否是字母、数字或下划线 + print(parser.test('1'.codeUnitAt(0))); // 检查字符 '1' 是否是字母、数字或下划线 + print(parser.test('_'.codeUnitAt(0))); // 检查字符 '_' 是否是字母、数字或下划线 + print(parser.test(' '.codeUnitAt(0))); // 检查字符 ' ' 是否是字母、数字或下划线 + +//-------------构造方法---------------------- + group('Constructors', () { + test('WhitespaceCharPredicate()', () { + expect(parser.runtimeType, null); + expect(parser, null); + }); + }); + +//-------------属性---------------------- + // group('Properties', () { + + // }); + +//-------------对象方法---------------------- + group('Methods', () { + test('isEqualTo(CharacterPredicate other) → bool', () { + expect(parser.isEqualTo(parser).runtimeType, null); + expect(parser.isEqualTo(parser), null); + }); + + test('test(int value) → bool', () { + expect(parser.test(1).runtimeType, null); + expect(parser.test(1), null); + }); + + test('toString() → String', () { + expect(parser.toString().runtimeType, null); + expect(parser.toString(), null); + }); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/tutorial_test.dart b/ohos/lz_petitparser_test_os/lib/pages/tutorial_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..eb11090997e16fc6b78ba94db0162a80a168ed37 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/tutorial_test.dart @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import 'dart:math' as math; + +import 'package:flutter/cupertino.dart'; +import 'package:petitparser/debug.dart'; +import 'package:petitparser/petitparser.dart'; +import 'package:petitparser/reflection.dart'; + +import '../common/test_page.dart'; + +class ExpressionDefinition extends GrammarDefinition { + @override + Parser start() => ref0(term).end(); + Parser term() => ref0(add) | ref0(prod); + Parser add() => ref0(prod) & char('+').trim() & ref0(term); + Parser prod() => ref0(mul) | ref0(prim); + Parser mul() => ref0(prim) & char('*').trim() & ref0(prod); + Parser prim() => ref0(parens) | ref0(number); + Parser parens() => char('(').trim() & ref0(term) & char(')').trim(); + Parser number() => digit().plus().flatten().trim(); +} + +class EvaluatorDefinition extends ExpressionDefinition { + @override + Parser add() => super.add().castList().map((values) => values[0] + values[2]); + @override + Parser mul() => super.mul().castList().map((values) => values[0] * values[2]); + @override + Parser parens() => super.parens().castList().pick(1); + @override + Parser number() => super.number().map((value) => int.parse(value)); +} + +class TutorialTestPage extends TestPage { + TutorialTestPage(String title, {Key? key}) : super(title, key: key) { + test('simple grammar (operators)', () { + final id = letter() & (letter() | digit()).star(); + final id1 = id.parse('yeah'); + final id2 = id.parse('f12'); + expect(id1.value, [ + 'y', + ['e', 'a', 'h'] + ]); + expect(id2.value, [ + 'f', + ['1', '2'] + ]); + final id3 = id.parse('123'); + expect(id3.message, 'letter expected'); + expect(id3.position, 0); + expect(id.accept('foo'), null); //isTrue + expect(id.accept('123'), null); //isFalse + }); + test('simple grammar (chained calls)', () { + final id = letter().seq(letter().or(digit()).star()); + final id1 = id.parse('yeah'); + final id2 = id.parse('f12'); + expect(id1.value, [ + 'y', + ['e', 'a', 'h'] + ]); + expect(id2.value, [ + 'f', + ['1', '2'] + ]); + final id3 = id.parse('123'); + expect(id3.message, 'letter expected'); + expect(id3.position, 0); + expect(id.accept('foo'), null); //isTrue + expect(id.accept('123'), null); //isFalse + }); + test('simple grammar (lists)', () { + final id = [ + letter(), + [letter(), digit()].toChoiceParser().star() + ].toSequenceParser(); + final id1 = id.parse('yeah'); + final id2 = id.parse('f12'); + expect(id1.value, [ + 'y', + ['e', 'a', 'h'] + ]); + expect(id2.value, [ + 'f', + ['1', '2'] + ]); + final id3 = id.parse('123'); + expect(id3.message, 'letter expected'); + expect(id3.position, 0); + expect(id.accept('foo'), null); //isTrue + expect(id.accept('123'), null); //isFalse + }); + test('simple grammar (typed functions)', () { + final id = seq2(letter(), [letter(), digit()].toChoiceParser().star()); + final id1 = id.parse('yeah'); + final id2 = id.parse('f12'); + expect(id1.value, null); + expect(id2.value, null); + final id3 = id.parse('123'); + expect(id3.message, 'letter expected'); + expect(id3.position, 0); + expect(id.accept('foo'), null); //isTrue + expect(id.accept('123'), null); //isFalse + }); + test('different parsers (word)', () { + final id1 = letter() & word().star(); + final matches = id1.flatten().allMatches('foo 123 bar4'); + expect(matches, ['foo', 'bar4']); + }); + test('different parsers (pattern)', () { + final id2 = letter() & pattern('a-zA-Z0-9').star(); + final matches = id2.flatten().allMatches('foo 123 bar4'); + expect(matches, ['foo', 'bar4']); + }); + test('complicated grammar', () { + final term = undefined(); + final prod = undefined(); + final prim = undefined(); + final add = (prod & char('+').trim() & term).castList().map((values) => values[0] + values[2]); + term.set(add | prod); + final mul = (prim & char('*').trim() & prod).castList().map((values) => values[0] * values[2]); + prod.set(mul | prim); + final parens = (char('(').trim() & term & char(')').trim()).map((values) => values[1]); + final number = digit().plus().flatten().trim().map(int.parse); + prim.set(parens | number); + final parser = term.end(); + expect(parser.parse('1 + 2 + 3').value, 6); + expect(parser.parse('1 + 2 * 3').value, 7); + expect(parser.parse('(1 + 2) * 3').value, 9); + }); + test('expression definition', () { + final parser = ExpressionDefinition().build(); + expect(parser.parse('1 + 2 + 3').value, [ + '1', + '+', + ['2', '+', '3'] + ]); + expect(parser.parse('1 + 2 * 3').value, [ + '1', + '+', + ['2', '*', '3'] + ]); + expect(parser.parse('(1 + 2) * 3').value, [ + [ + '(', + ['1', '+', '2'], + ')' + ], + '*', + '3' + ]); + }); + test('evaluator definition', () { + final definition = ExpressionDefinition(); + final parser = definition.build(); + expect(parser.parse('1 + 2 + 3').value, [ + '1', + '+', + ['2', '+', '3'] + ]); + expect(parser.parse('1 + 2 * 3').value, [ + '1', + '+', + ['2', '*', '3'] + ]); + expect(parser.parse('(1 + 2) * 3').value, [ + [ + '(', + ['1', '+', '2'], + ')' + ], + '*', + '3' + ]); + }); + test('number definition', () { + final definition = EvaluatorDefinition(); + final parser = definition.build(); + expect(parser.parse('1 + 2 + 3').value, 6); + expect(parser.parse('1 + 2 * 3').value, 7); + expect(parser.parse('(1 + 2) * 3').value, 9); + }); + test('number definition', () { + final definition = EvaluatorDefinition(); + final parser = definition.build(start: definition.number); + expect(parser.parse('42').value, 42); + }); + test('expression builder', () { + final builder = ExpressionBuilder(); + builder.group() + ..primitive(digit().plus().seq(char('.').seq(digit().plus()).optional()).flatten().trim().map(num.parse)) + ..wrapper(char('(').trim(), char(')').trim(), (l, a, r) => a); + // Negation is a prefix operator + builder.group().prefix(char('-').trim(), (op, a) => -a); + // Power is right-associative + builder.group().right(char('^').trim(), (a, op, b) => math.pow(a, b)); + // Multiplication and addition are left-associative + builder.group() + ..left(char('*').trim(), (a, op, b) => a * b) + ..left(char('/').trim(), (a, op, b) => a / b); + builder.group() + ..left(char('+').trim(), (a, op, b) => a + b) + ..left(char('-').trim(), (a, op, b) => a - b); + final parser = builder.build().end(); + expect(parser.parse('-8').value, -8); + expect(parser.parse('1+2*3').value, 7); + expect(parser.parse('1*2+3').value, 5); + expect(parser.parse('8/4/2').value, 1); + expect(parser.parse('2^2^3').value, 256); + }); + test('number parsing', () { + final definition = EvaluatorDefinition(); + final parser = definition.build(start: definition.number); + expect(parser.parse('42').value, 42); + }); + test('detect common problems', () { + final definition = EvaluatorDefinition(); + final parser = definition.build(); + expect(linter(parser), null); //isEmpty + }); + test('debugging parser', () { + final output = []; + final parser = letter() & word().star(); + trace(parser, output: output.add).parse('f1'); + expect(output.map((each) => each.toString()), [ + "Instance of 'SequenceParser'", + " Instance of 'CharacterParser'[letter expected]", + " Success[1:2]: f", + " Instance of 'PossessiveRepeatingParser'[0..*]", + " Instance of 'CharacterParser'[letter or digit expected]", + " Success[1:3]: 1", + " Instance of 'CharacterParser'[letter or digit expected]", + " Failure[1:3]: letter or digit expected", + " Success[1:3]: [1]", + "Success[1:3]: [f, [1]]", + ]); + }); + } +} diff --git a/ohos/lz_petitparser_test_os/lib/pages/utils/matchers.dart b/ohos/lz_petitparser_test_os/lib/pages/utils/matchers.dart new file mode 100644 index 0000000000000000000000000000000000000000..bab046e008f4d3c189d716235fbb052eb0f0fae8 --- /dev/null +++ b/ohos/lz_petitparser_test_os/lib/pages/utils/matchers.dart @@ -0,0 +1,168 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/foundation.dart'; +import 'package:petitparser/petitparser.dart'; +import 'package:test/test.dart' hide predicate; +import 'package:test/test.dart' as test show predicate; + +/// Returns a [Matcher] that asserts on a [ParserException]. +// const isParserException = TypeMatcher(); +// bool isParserEqual(Parser actual, Parser parser) { +// return actual is Parser && actual.isEqualTo(parser); +// } + +/// Returns a [Matcher] that asserts two parsers are structurally equivalent. +Matcher isParserEqual(Parser parser) => + test.predicate((actual) => actual is Parser && actual.isEqualTo(parser), 'structurally equal'); + +/// Returns a [Matcher] that asserts the context under test is a [Success]. +/// Optionally also asserts [position] and [value]. +TypeMatcher> isSuccessContext({ + dynamic position = anything, + dynamic value = anything, +}) => + isA>() + .having((context) => context.value, 'value', value) + .having((context) => context.position, 'position', position); + +/// Returns a [Matcher] that asserts the parser under test yields a successful +/// parse [result] for the given [input]. If no [position] is provided, assert +/// that the parsing fails at the end of the input. +// Matcher isParseSuccess( +// String input, +// dynamic result, { +// dynamic position, +// }) => +// isA>() +// .having((parser) => parser.parse(input), 'parse', isSuccessContext(value: result, position: position ?? input.length)) +// .having((parser) => parser.fastParseOn(input, 0), 'fastParseOn', position ?? input.length) +// .having((parser) => parser.accept(input), 'accept', isTrue) +// .having((parser) => parser.allMatches(input).first, 'allMatches', result); + +T isParseSuccess( + Parser parser, + String input, { + dynamic position, +}) { + var parseResult = parser.parse(input); + if (parseResult.isSuccess) { + var value = parseResult.value; + var fastParseResult = parser.fastParseOn(input, 0); + var acceptResult = parser.accept(input); + var allMatchesResult = parser.allMatches(input).first; + + if (fastParseResult == (position ?? input.length) && acceptResult == true) { + if ((allMatchesResult.runtimeType == List) && (value.runtimeType == List)) { + // allMatchesResult.setEquals(value); + + if (listEquals(allMatchesResult as List?, value as List?)) { + return value; + } + } else if (allMatchesResult == value) { + return value; + } + } + print( + "fastParseResult:$fastParseResult\n input.length:${input.length}\n acceptResult:$acceptResult\n allMatchesResult:$allMatchesResult value:$value "); + print( + "fastParseResult:${fastParseResult == (position ?? input.length)}\n acceptResult:${acceptResult == true}\n allMatchesResult:${allMatchesResult == value}"); + print("fastParseResult:${allMatchesResult.runtimeType}--${allMatchesResult.runtimeType == List}"); + } + + throw Exception('Parse failed.'); +} + +/// Returns a [Matcher] that asserts the context under test is a [Failure]. +/// Optionally also asserts [position] and [message]. +// TypeMatcher> isFailureContext({ +// dynamic position = anything, +// dynamic message = anything, +// }) => +// isA>() +// .having((context) => context.message, 'message', message) +// .having((context) => context.position, 'position', position); +// bool isFailureContext(Failure context, {dynamic position = anything, dynamic message = anything}) { +// return context.message == message && context.position == position; +// } + +/// Returns a [Matcher] that asserts the parser under test yields a parse +/// failure for the given [input]. If no [position] is provided, assert that +/// parsing fails at the beginning of the input. An optional [message] can be +/// provided to assert on the error message. +// Matcher isParseFailure( +// String input, { +// dynamic position = 0, +// dynamic message = anything, +// }) => +// isA>() +// .having((parser) => parser.parse(input), 'parse', isFailureContext(position: position, message: message)) +// .having((parser) => parser.fastParseOn(input, 0), 'fastParseOn', -1) +// .having((parser) => parser.accept(input), 'accept', isFalse); + +// bool isParseFailure(Parser parser, String input, {dynamic position = 0, dynamic message = anything}) { +// return parser.parse(input) is Failure && +// isFailureContext("", position: position, message: message) && +// parser.fastParseOn(input, 0) == -1 && +// !parser.accept(input); +// } + +/// Returns a [Matcher] that asserts on a [Match], the result of a [Pattern]. +// Matcher isPatternMatch( +// String match, { +// dynamic start = anything, +// dynamic end = anything, +// dynamic groups = anything, +// }) => +// isA() +// .having((match) => match.group(0), 'match', match) +// .having((match) => match.start, 'start', start) +// .having((match) => match.end, 'end', end) +// .having((match) => List.generate(match.groupCount, (group) => match.group(1 + group)), 'groups', groups); +bool isFailureContext(Failure context, {dynamic position = anything, dynamic message = anything}) { + return context.message == message && context.position == position; +} + +bool isParseFailure(Parser parser, String input, {dynamic position = 0, dynamic message = anything}) { + return parser.parse(input) is Failure && + isFailureContext(parser.parse(input) as Failure, position: position, message: message) && + parser.fastParseOn(input, 0) == -1 && + !parser.accept(input); +} + +bool isPatternMatch( + Match matchObj, + String match, { + dynamic start = anything, + dynamic end = anything, + dynamic groups = anything, +}) { + if (matchObj.group(0) != match) { + return false; + } + if (start != anything && matchObj.start != start) { + return false; + } + if (end != anything && matchObj.end != end) { + return false; + } + if (groups != anything) { + var actualGroups = List.generate(matchObj.groupCount, (group) => matchObj.group(1 + group)); + if (!listEquals(actualGroups, groups)) { + return false; + } + } + return true; +} diff --git a/ohos/lz_petitparser_test_os/ohos/.gitignore b/ohos/lz_petitparser_test_os/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/AppScope/app.json5 b/ohos/lz_petitparser_test_os/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a0d250c2a468dcb10fd8be3a87337d74707f316e --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/AppScope/app.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "bundleName": "com.example.lz_petitparser_test_os", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/lz_petitparser_test_os/ohos/AppScope/resources/base/element/string.json b/ohos/lz_petitparser_test_os/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..da41c2f3faa29f894bf825c5587c95faee121f87 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "lz_petitparser_test_os" + } + ] +} diff --git a/ohos/lz_petitparser_test_os/ohos/AppScope/resources/base/media/app_icon.png b/ohos/lz_petitparser_test_os/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/lz_petitparser_test_os/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/lz_petitparser_test_os/ohos/build-profile.json5 b/ohos/lz_petitparser_test_os/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..aabb859a656f0bfcb93c29ec050b71e586841a51 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\zblicq\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.lz_petitparser_test_os.cer", + "storePassword": "0000001AFCB3EF5A336B05C95D11C72D1AE3B425A7A1C0D2EFF0741C0AA94173814AA9F1B6CF2788135F", + "keyAlias": "debugKey", + "keyPassword": "0000001ABDABCBB7E44DAD507CD14DBDB94F2CAB70FA4407C6983E2FF567BD803DF59AC05B7A7AFDA008", + "profile": "C:\\Users\\zblicq\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.lz_petitparser_test_os.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\zblicq\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.lz_petitparser_test_os.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/dependencies/hvigor-3.0.9-s.tgz b/ohos/lz_petitparser_test_os/ohos/dependencies/hvigor-3.0.9-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..65b0d24f94d2aecc1099f8f8220beec695bfb779 Binary files /dev/null and b/ohos/lz_petitparser_test_os/ohos/dependencies/hvigor-3.0.9-s.tgz differ diff --git a/ohos/lz_petitparser_test_os/ohos/dependencies/hvigor-ohos-arkui-x-plugin-2.1.7-s.tgz b/ohos/lz_petitparser_test_os/ohos/dependencies/hvigor-ohos-arkui-x-plugin-2.1.7-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..233a449cbfef6be702d861744254dd89ce633fb7 Binary files /dev/null and b/ohos/lz_petitparser_test_os/ohos/dependencies/hvigor-ohos-arkui-x-plugin-2.1.7-s.tgz differ diff --git a/ohos/lz_petitparser_test_os/ohos/dependencies/hvigor-ohos-plugin-3.0.9-s.tgz b/ohos/lz_petitparser_test_os/ohos/dependencies/hvigor-ohos-plugin-3.0.9-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..e2e499e18dfcd05e1e275579d11697640eb80323 Binary files /dev/null and b/ohos/lz_petitparser_test_os/ohos/dependencies/hvigor-ohos-plugin-3.0.9-s.tgz differ diff --git a/ohos/lz_petitparser_test_os/ohos/dependencies/rollup.tgz b/ohos/lz_petitparser_test_os/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..b224a37a5f69fd22f58c7a28151742eafe7e6317 Binary files /dev/null and b/ohos/lz_petitparser_test_os/ohos/dependencies/rollup.tgz differ diff --git a/ohos/lz_petitparser_test_os/ohos/entry/.gitignore b/ohos/lz_petitparser_test_os/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/build-profile.json5 b/ohos/lz_petitparser_test_os/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/hvigorfile.ts b/ohos/lz_petitparser_test_os/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/lz_petitparser_test_os/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/lz_petitparser_test_os/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/lz_petitparser_test_os/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/lz_petitparser_test_os/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/lz_petitparser_test_os/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/lz_petitparser_test_os/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/lz_petitparser_test_os/ohos/entry/oh-package.json5 b/ohos/lz_petitparser_test_os/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3acc1b55168da82fe1499efbb8084b1e2643dde6 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/oh-package.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har" + } +} diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/lz_petitparser_test_os/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..321a4eeaacd7b8079a876e25c4dafd498e4d9fb9 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + } +} diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/main/ets/pages/Index.ets b/ohos/lz_petitparser_test_os/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/main/module.json5 b/ohos/lz_petitparser_test_os/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/element/color.json b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/element/string.json b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/media/icon.png b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/module.json5 b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/lz_petitparser_test_os/ohos/hvigor/hvigor-config.json5 b/ohos/lz_petitparser_test_os/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b8eb5547b14a9ddd7ea0cf0fab0d93fa22b8e919 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-3.0.9-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-3.0.9-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/lz_petitparser_test_os/ohos/hvigor/hvigor-wrapper.js b/ohos/lz_petitparser_test_os/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..3f6712ce6fbe94416cb178cd37b654fc415a62aa --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/hvigorfile.ts b/ohos/lz_petitparser_test_os/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/hvigorw b/ohos/lz_petitparser_test_os/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/lz_petitparser_test_os/ohos/hvigorw.bat b/ohos/lz_petitparser_test_os/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..015ad7171d03a3c644d8ca0202c6d72313ba2a34 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/hvigorw.bat @@ -0,0 +1,77 @@ +:: Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +:: Licensed under the Apache License, Version 2.0 (the "License"); +:: you may not use this file except in compliance with the License. +:: You may obtain a copy of the License at +:: +:: http://www.apache.org/licenses/LICENSE-2.0 +:: +:: Unless required by applicable law or agreed to in writing, software +:: distributed under the License is distributed on an "AS IS" BASIS, +:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +:: See the License for the specific language governing permissions and +:: limitations under the License. + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/lz_petitparser_test_os/ohos/oh-package-lock.json5 b/ohos/lz_petitparser_test_os/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6a6e39b58064cedcec439004569626579dc58bf1 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/oh-package-lock.json5 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/lz_petitparser_test_os/ohos/oh-package.json5 b/ohos/lz_petitparser_test_os/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..58fc83812f9a50d6cb3d08a0e62dea6773e1c4f2 --- /dev/null +++ b/ohos/lz_petitparser_test_os/ohos/oh-package.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/lz_petitparser_test_os/pubspec.yaml b/ohos/lz_petitparser_test_os/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fed742e0e64bf5eae4f80d8b0050914f0d1c93cc --- /dev/null +++ b/ohos/lz_petitparser_test_os/pubspec.yaml @@ -0,0 +1,106 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: lz_petitparser_test_os +description: A new Flutter project. +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# In Windows, build-name is used as the major, minor, and patch parts +# of the product and file versions while build-number is used as the build suffix. +version: 1.0.0+1 + +environment: + sdk: '>=2.19.6 <3.0.0' + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + petitparser: ^5.1.0 + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^2.0.0 + lints: ^2.0.0 + test: ^1.21.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/ohos/lz_petitparser_test_os/test/widget_test.dart b/ohos/lz_petitparser_test_os/test/widget_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..79568789ff60ec15b3f29361e33852b3e5ee8625 --- /dev/null +++ b/ohos/lz_petitparser_test_os/test/widget_test.dart @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:lz_petitparser_test_os/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +}