From 4999c5096a8aeb37470f9bf04c29ae18b2e615df Mon Sep 17 00:00:00 2001 From: Shibo Lyu Date: Mon, 29 Apr 2024 14:32:06 +0800 Subject: [PATCH] fix: apply change for 2-w at alternate position --- logic/section.ts | 11 ++- tests/section.test.ts | 152 +++++++++++++++++++++++++++++------------- types/board.ts | 5 ++ 3 files changed, 121 insertions(+), 47 deletions(-) diff --git a/logic/section.ts b/logic/section.ts index 9ad05a2..cbc6206 100644 --- a/logic/section.ts +++ b/logic/section.ts @@ -7,6 +7,11 @@ export function createSection( { sx, sy }: SectionPosition, boardConfig: BoardConfig ): SectionData { + if (boardConfig.sectionWidth % 2 !== 0) + throw new Error( + "sectionWidth must be multiple of 2 (least common multiples of all character widths)" + ); + const offsetX = sx * boardConfig.sectionWidth; const offsetY = sy * boardConfig.sectionHeight; @@ -32,8 +37,10 @@ export function applyChange(change: BoardChange, section: SectionData) { if (change.ch) { const chWidth = getCharacterWidth(change.ch); - section.ch[yInSection][xInSection] = change.ch; - section.width[yInSection][xInSection] = chWidth; + const xCharacterOffset = xInSection % 2; + const offsetAdjustedXInSection = xInSection - xCharacterOffset; + section.ch[yInSection][offsetAdjustedXInSection] = change.ch; + section.width[yInSection][offsetAdjustedXInSection] = chWidth; } if (change.color) { section.color[yInSection][xInSection] = change.color; diff --git a/tests/section.test.ts b/tests/section.test.ts index 4f913eb..51a58b2 100644 --- a/tests/section.test.ts +++ b/tests/section.test.ts @@ -1,53 +1,115 @@ -import { assertEquals } from "https://deno.land/std@0.224.0/assert/mod.ts"; +import { + assert, + assertEquals, + assertThrows, +} from "https://deno.land/std@0.224.0/assert/mod.ts"; -import { createSection } from "../logic/section.ts"; +import { applyChange, createSection } from "../logic/section.ts"; +import type { SectionData } from "../types/section.ts"; -Deno.test("createSection", () => { - const section = createSection( - { sx: 0, sy: 0 }, - { - xSections: 2, - ySections: 2, - sectionWidth: 3, - sectionHeight: 3, - defaultCh: " ", - defaultColor: "F", - defaultBgColor: "0", - defaultWidth: 1, +Deno.test("section", async (t) => { + let section: SectionData | undefined; + + await t.step("createSection non-lcm", () => { + assertThrows(() => { + createSection( + { sx: 0, sy: 0 }, + { + xSections: 2, + ySections: 2, + sectionWidth: 3, + sectionHeight: 3, + defaultCh: " ", + defaultColor: "F", + defaultBgColor: "0", + defaultWidth: 1, + } + ); + }); + }); + + await t.step("createSection non-origin section", () => { + section = createSection( + { sx: 1, sy: 1 }, + { + xSections: 2, + ySections: 2, + sectionWidth: 4, + sectionHeight: 3, + defaultCh: " ", + defaultColor: "F", + defaultBgColor: "0", + defaultWidth: 1, + } + ); + + assertEquals(section.offsetX, 4); + assertEquals(section.offsetY, 3); + }); + + await t.step("createSection", () => { + section = createSection( + { sx: 0, sy: 0 }, + { + xSections: 2, + ySections: 2, + sectionWidth: 4, + sectionHeight: 3, + defaultCh: " ", + defaultColor: "F", + defaultBgColor: "0", + defaultWidth: 1, + } + ); + + assertEquals(section.offsetX, 0); + assertEquals(section.offsetY, 0); + + function assertSectionContent( + content: T[][], + rowCount: number, + columnCount: number, + value: T + ) { + assertEquals(content.length, rowCount); + for (const row of content) { + assertEquals(row.length, columnCount); + for (const item of row) { + assertEquals(item, value); + } + } } - ); - assertEquals(section.offsetX, 0); - assertEquals(section.offsetY, 0); - assertEquals(section.ch.length, 3); - for (const row of section.ch) { - assertEquals(row.length, 3); - for (const ch of row) { - assertEquals(ch, " "); - } - } + assertSectionContent(section.ch, 3, 4, " "); + assertSectionContent(section.color, 3, 4, "F"); + assertSectionContent(section.bgColor, 3, 4, "0"); + assertSectionContent(section.width, 3, 4, 1); + }); - assertEquals(section.color.length, 3); - for (const row of section.color) { - assertEquals(row.length, 3); - for (const color of row) { - assertEquals(color, "F"); - } - } + await t.step("applyChange 1-width", () => { + assert(section); - assertEquals(section.bgColor.length, 3); - for (const row of section.bgColor) { - assertEquals(row.length, 3); - for (const bgColor of row) { - assertEquals(bgColor, "0"); - } - } + applyChange({ x: 0, y: 0, ch: "t" }, section); + assertEquals(section.ch[0][0], "t"); + assertEquals(section.ch[0][1], " "); + assertEquals(section.width[0][0], 1); + }); - assertEquals(section.width.length, 3); - for (const row of section.width) { - assertEquals(row.length, 3); - for (const width of row) { - assertEquals(width, 1); - } - } + await t.step("applyChange 2-width at a correct position", () => { + assert(section); + + applyChange({ x: 0, y: 0, ch: "あ" }, section); + assertEquals(section.ch[0][0], "あ"); + assertEquals(section.ch[0][1], " "); + assertEquals(section.width[0][0], 2); + }); + + await t.step("applyChange 2-width at an alternate position", () => { + assert(section); + + applyChange({ x: 1, y: 0, ch: "あ" }, section); + assertEquals(section.ch[0][0], "あ"); + assertEquals(section.ch[0][1], " "); + assertEquals(section.width[0][0], 2); + }); }); diff --git a/types/board.ts b/types/board.ts index ea1aaa0..907c85e 100644 --- a/types/board.ts +++ b/types/board.ts @@ -36,6 +36,11 @@ export interface CharacterPosition { export interface BoardConfig { xSections: number; ySections: number; + /** + * Width of each section, in display characters. + * + * Note that this must be a multiple of the least common multiple of all possible character display width (returned by `getCharacterWidth`). + */ sectionWidth: number; sectionHeight: number;