---
title: 测试文档
order: 4
category: pro
---

# PisellFloorMapLayout 测试文档

## 1. 测试范围

| 类别           | 说明                       |
|--------------|--------------------------|
| 单元测试         | 工具函数、尺寸计算、key 生成等        |
| 组件测试         | 主组件与子组件渲染、Props 与 Ref 行为 |
| 交互测试         | 点击、hover、缩放、平移、控制按钮      |
| 视觉/Storybook | 多场景 Story 覆盖，回归 UI 与布局   |

## 2. 测试环境与工具

- **框架**：按项目约定（如 Jest + React Testing Library）。
- **运行**：`pnpm test` 或 `npm test`，可限定包路径。
- **Storybook**：`pnpm storybook` 或对应命令，用于手工/快照与视觉回归。

## 3. 单元级测试要点

### 3.1 尺寸与坐标（`utils/layoutMeasurements.ts`）

- **getContentSize**
  - 空 items：返回默认宽高（cell 与 pixel 模式分别验证）。
  - cell 模式：根据 items 的 x/y/width/height 与 cellSize、itemGap 计算 contentWidth/contentHeight。
  - pixel 模式：根据 items 的 x/y/width/height 取 maxRight、maxBottom；缺省 width/height 时用 cellSize。
- **getPixelBoundingBox**：有 items 时返回 minLeft/minTop/maxRight/maxBottom；空数组返回 null。
- **gapToPx**：支持 number、`"8px"` 等形式，未传或非法时返回默认 `DEFAULT_ITEM_GAP`。

### 3.2 ItemLayer 定位与尺寸

- cell 模式、itemGap = 0：left = x * cellSize，width = w * cellSize。
- cell 模式、itemGap > 0：left = x * (cellSize + gap) + gap，width = w * cellSize + (w - 1) * gap。
- pixel 模式：left = item.x，width = item.width ?? cellSize（height 同理）。

### 3.3 Key 生成

- 无 rowKey：使用 item.id。
- rowKey 为字符串：使用 item[rowKey] 或 item.id。
- rowKey 为函数：使用函数返回值。

## 4. 组件级测试要点

### 4.1 PisellFloorMapLayout

- 渲染：传入 items、renderItem，能渲染出与 items 数量一致的节点。
- 类名与样式：传入 className、style，应挂到根节点。
- itemUnit：切换 cell / pixel，内容区尺寸与 item 位置符合预期。
- mapLayer.gap：影响 content 尺寸与 item 间距（cell 模式）。
- Ref：mount 后 ref.current 存在，且具备 zoomIn、zoomOut、reset、fitBounds 方法；调用后不抛错。

### 4.2 ViewControls

- 默认：仅渲染缩放（+ / −）两个按钮。
- controls.showReset === true：渲染复位按钮。
- controls.showFitBounds === true 且 api.fitBounds 存在：渲染区域定位按钮。
- controls.showFullscreen === true 且 api.toggleFullscreen 存在：渲染全屏按钮（**平面图编辑态**下主组件会将
  `showFullscreen`/`showFitBounds` 从左下角配置中关闭，改由顶栏渲染，单元测 ViewControls 本身行为不变）。
- controls.showZoom === false：不渲染缩放按钮。
- 点击：调用 api 对应方法（可 mock api）。

### 4.3 MapLayer

- 根据 mapLayer 配置渲染背景（无/纯色/图/SVG）、网格线、padding、gap。

### 4.4 ItemLayer

- 根据 items、cellSize、itemGap、itemUnit 计算每个 item 的 left/top/width/height。
- 调用 renderItem(item, index) 渲染内容。
- rowKey 决定 key；enableHover、onItemClick、onItemHover、onItemLeave 影响交互。

### 4.5 平面图编辑（可选）

- **mergeCanvasItems**（`floorMapConfigMerge.ts`）：给定 `canvasId` 与 `config`，按 `sceneElements` 过滤当前画布，输出
  `FloorMapMergedItem[]`，`id`/`instanceId` 与 `_sceneElement.instanceId` 一致。
- **FloorMapEditTopBar**：`mode=compact` 为画布 Tab + 全屏入口；`mode=full` 全屏态下含 Tab、保存、退出全屏等。
- **侧栏拖拽**：`FLOOR_MAP_PALETTE_DRAG_MIME` + `parsePaletteDragPayload`；`sceneXYFromContentDropOffset` 与落点 offset
  一致。
- **FloorMapEditPanel**：配置 `dataSourceRecordForm` 时渲染自定义节点，不挂载 `FloorMapDataForm`；未配置且存在
  `onSaveRecord` 时挂载 `FloorMapDataForm`。
- **useFloorMapEditState**：`editPanelParams` 含 `dataSourceRecordForm` 透传；暴露 `placeSceneElementFromPaletteDrop`；无
  `ReferenceError`。

## 5. 交互与 E2E 要点

- **缩放**：点击 + / − 或通过 ref.zoomIn()/zoomOut()，视图缩放变化且不报错。
- **平移**：pan.enabled 为 true 时，可拖拽画布。
- **复位**：ref.reset() 或点击复位按钮，缩放与位置恢复初始。
- **区域定位**：ref.fitBounds() 或点击区域定位按钮，内容区适应容器。
- **Item 事件**：点击 item 触发 onItemClick；hover 触发 onItemHover/onItemLeave；enableHover 为 false 时不触发 hover 且无
  hover 样式。

## 6. Storybook 覆盖场景

以下 Story 用于手工验证与回归，建议保持可用：

| Story                                                                         | 验证点                                                         |
|-------------------------------------------------------------------------------|-------------------------------------------------------------|
| Default                                                                       | 基础渲染、格子布局、默认 controls（仅缩放）                                  |
| WithGrid / WithPan / WithShapes / WithVariableSizes / PixelUnits / WithEvents | 与名称一致的布局与交互                                                 |
| WithRefControls                                                               | Ref：`zoomIn` / `zoomOut` / `reset` / `fitBounds`            |
| ControlsHidden                                                                | `controls` 显隐                                               |
| FloorMapViewEdit                                                              | 平面图编辑：Tab、工具栏、侧栏、拖拽、内置或自定义记录表单                              |
| FloorMapViewRead                                                              | 平面图只读                                                       |
| FloorMapViewEditCustomRecordForm                                              | **`dataSourceRecordForm`** 自定义表单 + `onDataSourceRecordSave` |
| FigmaDesign                                                                   | Figma 还原（Tab、图例、像素布局）                                       |
| **PisellRecordBoard → Default**                                               | 表格/平面图切换；**侧栏自定义记录表单**开关与 `onDataSourceRecordSave` 写回表格     |

## 7. 回归检查清单

- [ ] 无 items 时内容区有默认宽高，不报错。
- [ ] itemUnit 为 cell 时，mapLayer.gap 影响间距与 content 尺寸。
- [ ] itemUnit 为 pixel 时，item 的 x/y/width/height 为像素，无 gap 参与。
- [ ] 缩放按钮在左下角；默认仅显示 + / −。
- [ ] controls.showReset/showFitBounds 为 true 时显示对应按钮。
- [ ] Ref 的 zoomIn、zoomOut、reset、fitBounds 可用。
- [ ] 点击 item 触发 onItemClick；hover 触发 onItemHover/onItemLeave。
  - [ ]（平面图）保存布局触发 `onSave`；侧栏保存记录触发 `onDataSourceRecordSave`。
  - [ ]（可选）`dataSourceRecordForm` 与列配置二选一展示逻辑正确。

## 8. Bug 汇总

### 待修复的 Bug

| Bug ID | 描述 | 优先级 | 状态 | 发现时间 |
|--------|----|-----|----|------|
| -      | -  | -   | -  | -    |

### 已修复的 Bug

| Bug ID | 描述 | 修复方案 | 修复时间 |
|--------|----|------|------|
| -      | -  | -    | -    |
