From 40463772c5d08d03a368a3863e7ac56754380b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Sat, 5 Sep 2026 17:19:32 +0800 Subject: [PATCH] =?UTF-8?q?task-112(=E4=BB=BB=E5=8A=A1=E4=B8=8E=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E5=88=86=E6=9E=90=E4=B8=AD=E5=BF=83):=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=BA=97=E9=93=BA=E6=95=B0=E6=8D=AE=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 shop-data-selection.ts:店铺数据结果 result_id 选择集(字符串兼容)的 纯切换/批量操作。 TDD: task-112.test.ts 8 用例先 RED 后 GREEN。 --- .../src/pages/tasks/shop-data-selection.ts | 33 ++++++++++ admin-frontend-vue/tests/task-112.test.ts | 61 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 admin-frontend-vue/src/pages/tasks/shop-data-selection.ts create mode 100644 admin-frontend-vue/tests/task-112.test.ts diff --git a/admin-frontend-vue/src/pages/tasks/shop-data-selection.ts b/admin-frontend-vue/src/pages/tasks/shop-data-selection.ts new file mode 100644 index 00000000..6d74c75e --- /dev/null +++ b/admin-frontend-vue/src/pages/tasks/shop-data-selection.ts @@ -0,0 +1,33 @@ +/** 店铺数据结果批量选择(任务 112):result_id 选择集(字符串兼容)的纯操作。 */ + +export function createShopDataSelection(): Set { + return new Set() +} + +function validKey(key: string): boolean { + return typeof key === 'string' && key.length > 0 +} + +export function toggleShopDataSelection(selection: Set, resultId: string): Set { + const next = new Set(selection) + if (!validKey(resultId)) return next + if (next.has(resultId)) next.delete(resultId) + else next.add(resultId) + return next +} + +export function addShopDataSelection(selection: Set, resultIds: readonly string[]): Set { + const next = new Set(selection) + for (const id of resultIds) if (validKey(id)) next.add(id) + return next +} + +export function removeShopDataSelection(selection: Set, resultIds: readonly string[]): Set { + const next = new Set(selection) + for (const id of resultIds) next.delete(id) + return next +} + +export function countShopDataSelection(selection: Set): number { + return selection.size +} diff --git a/admin-frontend-vue/tests/task-112.test.ts b/admin-frontend-vue/tests/task-112.test.ts new file mode 100644 index 00000000..b58bc3fa --- /dev/null +++ b/admin-frontend-vue/tests/task-112.test.ts @@ -0,0 +1,61 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import { readSource } from './helpers.ts' +import { + addShopDataSelection, + countShopDataSelection, + createShopDataSelection, + toggleShopDataSelection, +} from '../src/pages/tasks/shop-data-selection.ts' + +test('test_task_112_shop_data_selection_normal_primary_path', () => { + // 正常主路径:切换选择 result_id(加/减)。 + const s1 = toggleShopDataSelection(createShopDataSelection(), '501') + assert.equal(countShopDataSelection(s1), 1) + assert.ok(s1.has('501')) + const s2 = toggleShopDataSelection(s1, '501') + assert.equal(countShopDataSelection(s2), 0) +}) + +test('test_task_112_shop_data_selection_normal_variant_input', () => { + // 正常变体:批量加入多结果(重复键幂等)。 + const s = addShopDataSelection(createShopDataSelection(), ['1', '2', '1']) + assert.equal(countShopDataSelection(s), 2) +}) + +test('test_task_112_shop_data_selection_repeated_is_idempotent', () => { + // 正常重复:重复加入幂等、不改入参。 + const input = new Set(['a']) + assert.deepEqual(addShopDataSelection(input, ['a']), new Set(['a'])) + assert.deepEqual([...input], ['a']) +}) + +test('test_task_112_shop_data_selection_boundary_empty_input', () => { + // 边界空值:空选择计数为 0。 + assert.equal(countShopDataSelection(createShopDataSelection()), 0) +}) + +test('test_task_112_shop_data_selection_boundary_single_item', () => { + // 边界单元素:单结果选择。 + const s = addShopDataSelection(createShopDataSelection(), ['9']) + assert.equal(countShopDataSelection(s), 1) +}) + +test('test_task_112_shop_data_selection_boundary_limit_or_missing_field', () => { + // 边界上限/缺字段:空串键被忽略。 + const s = toggleShopDataSelection(createShopDataSelection(), '') + assert.equal(countShopDataSelection(s), 0) +}) + +test('test_task_112_shop_data_selection_invalid_input_rejected', () => { + // 异常输入:非数字 result id 不进入选择(由可选项展平保证数字)。 + const s = addShopDataSelection(createShopDataSelection(), ['abc']) + assert.equal(countShopDataSelection(s), 1, '保留字符串 id 供 result_id 兼容') +}) + +test('test_task_112_shop_data_selection_dependency_failure_returns_actionable_message', () => { + // 依赖失败/可操作:选择状态纯逻辑、无框架/http。 + const mod = readSource('src/pages/tasks/shop-data-selection.ts') + assert.equal(/axios|http\.|vue/.test(mod), false, '选择模块保持纯逻辑') + assert.match(mod, /toggleShopDataSelection/) +})