yx_app_upgrade_flutter/test/app_upgrade_simple_parse_te...

285 lines
10 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter_test/flutter_test.dart';
import 'package:yx_app_upgrade_flutter/app_upgrade_simple.dart';
void main() {
group('parseUpdateContent', () {
test('extracts header block and preserves nested markers', () {
const content = '''
/{
本次 **V2.2.0** 版本聚焦[使用体验]优化。
__支持嵌套__例如 **[特别注意]** 与 `version 2.0`
/}
1. 第一条说明
2. 第二条说明
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isTrue);
expect(
parsed.header,
'本次 **V2.2.0** 版本聚焦[使用体验]优化。\n__支持嵌套__例如 **[特别注意]** 与 `version 2.0`',
);
expect(parsed.bodyItems, hasLength(2));
expect(parsed.bodyItems.first.text, '1. 第一条说明');
expect(parsed.bodyItems.first.hasLeadingMarker, isTrue);
expect(parsed.bodyItems.last.text, '2. 第二条说明');
});
test('supports inline header block', () {
const content = '''
/{ 更新内容如下: /}
- 第一条说明
普通说明
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isTrue);
expect(parsed.header, '更新内容如下:');
expect(parsed.bodyItems, hasLength(2));
expect(parsed.bodyItems.first.hasLeadingMarker, isTrue);
expect(parsed.bodyItems.last.hasLeadingMarker, isFalse);
});
test('supports explicit but empty header block', () {
const content = '''
/{ /}
正文说明
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isTrue);
expect(parsed.header, isNull);
expect(parsed.bodyItems, hasLength(1));
expect(parsed.bodyItems.first.text, '正文说明');
});
test('keeps original content when header block is missing', () {
const content = '''
**重要内容**
第二行说明
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isFalse);
expect(parsed.header, isNull);
expect(parsed.bodyItems, hasLength(2));
expect(parsed.bodyItems.first.text, '**重要内容**');
expect(parsed.bodyItems.last.text, '第二行说明');
});
test('preserves blank lines inside header block', () {
const content = '''
/{
第一段说明
第二段说明
/}
正文说明
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isTrue);
expect(parsed.header, '第一段说明\n\n第二段说明');
expect(parsed.bodyItems, hasLength(1));
expect(parsed.bodyItems.first.text, '正文说明');
});
test('falls back to original content when header block is not closed', () {
const content = '''
/{
第一段说明
正文说明
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isFalse);
expect(parsed.header, isNull);
expect(parsed.bodyItems, hasLength(3));
expect(parsed.bodyItems[0].text, '/{');
expect(parsed.bodyItems[1].text, '第一段说明');
expect(parsed.bodyItems[2].text, '正文说明');
});
test('supports trailing body text on the same line as header end marker',
() {
const content = '''
/{ 头部说明 /} 1. 第一条说明
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isTrue);
expect(parsed.header, '头部说明');
expect(parsed.bodyItems, hasLength(1));
expect(parsed.bodyItems.first.text, '1. 第一条说明');
expect(parsed.bodyItems.first.hasLeadingMarker, isTrue);
});
test('normalizes windows line endings', () {
const content = '/{\r\n头部说明\r\n/}\r\n- 第一条\r\n普通说明\r\n';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isTrue);
expect(parsed.header, '头部说明');
expect(parsed.bodyItems, hasLength(2));
expect(parsed.bodyItems.first.text, '- 第一条');
expect(parsed.bodyItems.last.text, '普通说明');
});
test('detects multiple supported leading marker styles', () {
const content = '''
1. 数字序号
一、中文序号
- 无序列表
• 特殊符号列表
普通段落
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isFalse);
expect(parsed.bodyItems, hasLength(5));
expect(parsed.bodyItems[0].hasLeadingMarker, isTrue);
expect(parsed.bodyItems[1].hasLeadingMarker, isTrue);
expect(parsed.bodyItems[2].hasLeadingMarker, isTrue);
expect(parsed.bodyItems[3].hasLeadingMarker, isTrue);
expect(parsed.bodyItems[4].hasLeadingMarker, isFalse);
});
test('does not treat later header markers inside body as header block', () {
const content = '''
普通说明
/{ 这不是头部 /}
第二行正文
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isFalse);
expect(parsed.header, isNull);
expect(parsed.bodyItems, hasLength(3));
expect(parsed.bodyItems[1].text, '/{ 这不是头部 /}');
});
test('returns empty result for blank content', () {
final parsed = AppUpgradeSimple.parseUpdateContent(' \n \r\n ');
expect(parsed.hasExplicitHeaderBlock, isFalse);
expect(parsed.header, isNull);
expect(parsed.bodyItems, isEmpty);
});
test('keeps the final growth-center line as a separate body item', () {
const content = '''
/{本次 **V2.2.0** 版本围绕[使用体验]、[账号安全]、[家校联动]、[学习管理]等方面进行多项优化与功能新增,具体更新内容如下:/}
工作录入新增**草稿箱功能**,录入内容自动暂存,录入途中临时退出、意外关闭页面,都不会丢失填写数据,有效避免重复录入,提升使用效率;
优化**多账号登录机制**,若同一手机号绑定多个账号,登录时需手动选择本次要登录的对应账号,区分账号使用,保障使用精准性;
全新上线**家校互动板块**,新增家长会、社群运营、线上家访特色功能,搭建高效家校沟通渠道,助力家校协同共育;
**成长中心**全面调整优化:成长中心入口迁移至工作台页面,升级全局搜索能力,章节内容改为结构化排版展示;优化视频播放逻辑与播放限制规则,同时新增学习过程监管功能,强化学习管控。
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isTrue);
expect(
parsed.header,
'本次 **V2.2.0** 版本围绕[使用体验]、[账号安全]、[家校联动]、[学习管理]等方面进行多项优化与功能新增,具体更新内容如下:',
);
expect(parsed.bodyItems, hasLength(4));
expect(parsed.bodyItems[0].text, startsWith('工作录入新增**草稿箱功能**'));
expect(parsed.bodyItems[1].text, startsWith('优化**多账号登录机制**'));
expect(parsed.bodyItems[2].text, startsWith('全新上线**家校互动板块**'));
expect(
parsed.bodyItems[3].text,
'**成长中心**全面调整优化:成长中心入口迁移至工作台页面,升级全局搜索能力,章节内容改为结构化排版展示;优化视频播放逻辑与播放限制规则,同时新增学习过程监管功能,强化学习管控。',
);
});
test('does not treat bold marker at line start as list marker', () {
const content = '''
**成长中心**全面调整优化:成长中心入口迁移至工作台页面,升级全局搜索能力。
* 合法无序列表项
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.bodyItems, hasLength(2));
expect(parsed.bodyItems.first.text,
'**成长中心**全面调整优化:成长中心入口迁移至工作台页面,升级全局搜索能力。');
expect(parsed.bodyItems.first.hasLeadingMarker, isFalse);
expect(parsed.bodyItems.last.text, '* 合法无序列表项');
expect(parsed.bodyItems.last.hasLeadingMarker, isTrue);
});
test(
'supports all rich text markers when they appear on the first body line',
() {
const content = '''
**粗体首行**
__斜体次行__
`代码第三行`
[高亮第四行]
**[组合重点]**
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isFalse);
expect(parsed.bodyItems, hasLength(5));
expect(parsed.bodyItems[0].text, '**粗体首行**');
expect(parsed.bodyItems[1].text, '__斜体次行__');
expect(parsed.bodyItems[2].text, '`代码第三行`');
expect(parsed.bodyItems[3].text, '[高亮第四行]');
expect(parsed.bodyItems[4].text, '**[组合重点]**');
expect(
parsed.bodyItems.every((item) => item.hasLeadingMarker == false),
isTrue,
);
});
test('supports rich text markers on the first line inside header block',
() {
const content = '''
/{
**头部粗体**
__[头部高亮斜体]__
`头部代码`
/}
正文说明
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.hasExplicitHeaderBlock, isTrue);
expect(
parsed.header,
'**头部粗体**\n__[头部高亮斜体]__\n`头部代码`',
);
expect(parsed.bodyItems, hasLength(1));
expect(parsed.bodyItems.first.text, '正文说明');
});
test('does not treat version-like prefix as ordered marker', () {
const content = '''
1.0版本修复说明
2. 第一条真正的序号内容
''';
final parsed = AppUpgradeSimple.parseUpdateContent(content);
expect(parsed.bodyItems, hasLength(2));
expect(parsed.bodyItems.first.text, '1.0版本修复说明');
expect(parsed.bodyItems.first.hasLeadingMarker, isFalse);
expect(parsed.bodyItems.last.text, '2. 第一条真正的序号内容');
expect(parsed.bodyItems.last.hasLeadingMarker, isTrue);
});
});
}