T-M2-05 ConfigManager:本地 rawfile/app_config.json(§4.2 实测值)、远程 URL 拼装('-'→'/'+.txt+?a=ts 禁缓存)、
长度<30 走 showmessage 阻断、二级 url 二次请求(语义待真机校验)、产出版本决策
T-M2-06 VersionResolver:纯函数,agentlist/gamelist 两棵树 + agent→channel→market→game 后层覆盖 +
两树取更高 version(§4.4)。单测 8 用例全通过,覆盖率 81.8%(≥80%)
T-M2-07 ResourceManager:沙箱路径规范、内置包拷贝解压、version.xml 解析(@ohos.xml)、远程 zip 下载/删旧/解压、版本比较
T-M2-09 AppDataInjector:加载前写 <gameDir>/app_data.js(§6 全局变量同名同义,JSON.stringify 安全字面量)
T-M2-11 StartupOrchestrator:INIT→…→ENTER_HALL 状态机,远程失败降级本地、showmessage 阻断、weburl 空/非空入口规则
配套:module.json5 声明 ohos.permission.INTERNET + reason_internet 字符串
devecocli build 通过;scripts/test.sh 单测全通过(修复 PermissionRequestResult 顶层导入)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
116 lines
4.6 KiB
Plaintext
116 lines
4.6 KiB
Plaintext
import { describe, it, expect } from '@ohos/hypium';
|
||
import { VersionResolver, RemoteConfig, MatchKeys, VersionDecision } from 'domain_resource';
|
||
|
||
/**
|
||
* 分层版本决策单测(T-M2-06,契约 §4.4)。纯函数,构造典型多层样例验证后层覆盖、
|
||
* 两棵树取更高 version、showmessage 阻断。
|
||
*/
|
||
export default function versionResolverTest() {
|
||
const keys: MatchKeys = { agentid: 'A1', channelid: 'C1', marketid: 'M1', gameid: 'G1' };
|
||
|
||
describe('VersionResolver', () => {
|
||
it('empty_config_zero_decision', 0, () => {
|
||
const d: VersionDecision = VersionResolver.resolve({}, keys);
|
||
expect(d.gameVersion).assertEqual(0);
|
||
expect(d.appVersion).assertEqual(0);
|
||
expect(d.showmessage).assertEqual('');
|
||
expect(d.gameDownload).assertEqual('');
|
||
});
|
||
|
||
it('agent_tree_deeper_overrides', 0, () => {
|
||
// 代理树:agent 设 game_version=10,market 覆盖为 20(深层覆盖浅层)
|
||
const remote: RemoteConfig = {
|
||
agentlist: [{
|
||
agentid: 'A1', game_version: '10', game_download: 'a_url', game_size: '100',
|
||
channellist: [{
|
||
channelid: 'C1',
|
||
marketlist: [{ marketid: 'M1', game_version: '20', game_download: 'm_url' }],
|
||
}],
|
||
}],
|
||
};
|
||
const d: VersionDecision = VersionResolver.resolve(remote, keys);
|
||
expect(d.gameVersion).assertEqual(20);
|
||
expect(d.gameDownload).assertEqual('m_url');
|
||
});
|
||
|
||
it('market_game_level_overrides', 0, () => {
|
||
// market.gamelist 中 gameid 命中,覆盖到最深
|
||
const remote: RemoteConfig = {
|
||
agentlist: [{
|
||
agentid: 'A1',
|
||
channellist: [{
|
||
channelid: 'C1',
|
||
marketlist: [{
|
||
marketid: 'M1', game_version: '20',
|
||
gamelist: [{ gameid: 'G1', game_version: '30', game_download: 'g_url' }],
|
||
}],
|
||
}],
|
||
}],
|
||
};
|
||
const d: VersionDecision = VersionResolver.resolve(remote, keys);
|
||
expect(d.gameVersion).assertEqual(30);
|
||
expect(d.gameDownload).assertEqual('g_url');
|
||
});
|
||
|
||
it('two_trees_take_higher_version', 0, () => {
|
||
// 代理树 game_version=20,游戏树 game_version=25 → 取 25 及其下载地址
|
||
const remote: RemoteConfig = {
|
||
agentlist: [{ agentid: 'A1', game_version: '20', game_download: 'agent_url' }],
|
||
gamelist: [{
|
||
gameid: 'G1',
|
||
agentlist: [{ agentid: 'A1', game_version: '25', game_download: 'game_url' }],
|
||
}],
|
||
};
|
||
const d: VersionDecision = VersionResolver.resolve(remote, keys);
|
||
expect(d.gameVersion).assertEqual(25);
|
||
expect(d.gameDownload).assertEqual('game_url');
|
||
});
|
||
|
||
it('app_and_game_independent_winners', 0, () => {
|
||
// app 升级取代理树(app_version=49),game 升级取游戏树(game_version=30)
|
||
const remote: RemoteConfig = {
|
||
agentlist: [{ agentid: 'A1', app_version: '49', app_download: 'apk_url', game_version: '10' }],
|
||
gamelist: [{
|
||
gameid: 'G1',
|
||
agentlist: [{ agentid: 'A1', app_version: '40', game_version: '30', game_download: 'g_url' }],
|
||
}],
|
||
};
|
||
const d: VersionDecision = VersionResolver.resolve(remote, keys);
|
||
expect(d.appVersion).assertEqual(49);
|
||
expect(d.appDownload).assertEqual('apk_url');
|
||
expect(d.gameVersion).assertEqual(30);
|
||
expect(d.gameDownload).assertEqual('g_url');
|
||
});
|
||
|
||
it('no_match_returns_empty', 0, () => {
|
||
const remote: RemoteConfig = {
|
||
agentlist: [{ agentid: 'OTHER', game_version: '99', game_download: 'x' }],
|
||
};
|
||
const d: VersionDecision = VersionResolver.resolve(remote, keys);
|
||
expect(d.gameVersion).assertEqual(0);
|
||
expect(d.gameDownload).assertEqual('');
|
||
});
|
||
|
||
it('showmessage_from_layer_or_top', 0, () => {
|
||
const top: RemoteConfig = { showmessage: '停服维护公告' };
|
||
expect(VersionResolver.resolve(top, keys).showmessage).assertEqual('停服维护公告');
|
||
const layer: RemoteConfig = {
|
||
agentlist: [{ agentid: 'A1', showmessage: '代理层公告' }],
|
||
};
|
||
expect(VersionResolver.resolve(layer, keys).showmessage).assertEqual('代理层公告');
|
||
});
|
||
|
||
it('empty_string_does_not_override', 0, () => {
|
||
// 深层空串不应覆盖浅层非空值
|
||
const remote: RemoteConfig = {
|
||
agentlist: [{
|
||
agentid: 'A1', game_download: 'keep', game_version: '10',
|
||
channellist: [{ channelid: 'C1', game_download: '' }],
|
||
}],
|
||
};
|
||
const d: VersionDecision = VersionResolver.resolve(remote, keys);
|
||
expect(d.gameDownload).assertEqual('keep');
|
||
});
|
||
});
|
||
}
|