From 03af51b35d7b7460b45a66d7f3acd7a93b73dc95 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:07:06 +0000 Subject: [PATCH 1/4] Initial plan From dede5f8ac4a91b6bd8724363ac883d0b81ff8845 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:21:34 +0000 Subject: [PATCH 2/4] Add comprehensive tests for generate function Co-authored-by: marlonmarcello <1956448+marlonmarcello@users.noreply.github.com> --- deno.json | 3 +- main.ts | 2 +- main_test.ts | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 main_test.ts diff --git a/deno.json b/deno.json index b61140f..1b61968 100644 --- a/deno.json +++ b/deno.json @@ -6,7 +6,8 @@ "sharp": "npm:sharp@^0.34.5" }, "tasks": { - "compile": "deno compile --allow-all main.ts" + "compile": "deno compile --allow-all main.ts", + "test": "deno test --allow-all" }, "version": "0.0.1" } diff --git a/main.ts b/main.ts index 7815a2a..705bed1 100644 --- a/main.ts +++ b/main.ts @@ -132,7 +132,7 @@ export interface GenerateOptions { input?: string; } -async function generate({ +export async function generate({ angleOption = 0, degrees, output, diff --git a/main_test.ts b/main_test.ts new file mode 100644 index 0000000..68f3bf3 --- /dev/null +++ b/main_test.ts @@ -0,0 +1,223 @@ +import { assertEquals, assertRejects } from "jsr:@std/assert"; +import { existsSync } from "@std/fs/exists"; +import { generate, GenerateOptions } from "./main.ts"; + +// Create a temporary test image for testing +async function createTestImage(path: string) { + // Create a simple 100x100 PNG for testing + const sharp = (await import("sharp")).default; + await sharp({ + create: { + width: 100, + height: 100, + channels: 4, + background: { r: 255, g: 0, b: 0, alpha: 1 }, + }, + }) + .png() + .toFile(path); +} + +// Clean up test files +async function cleanupTestFiles(paths: string[]) { + for (const path of paths) { + try { + if (existsSync(path)) { + await Deno.remove(path); + } + } catch { + // Ignore cleanup errors + } + } +} + +Deno.test("generate - successful generation with default angleOption", async () => { + const testInput = "/tmp/test-input-default.png"; + const expectedOutput = "/tmp/test-input-default-tile-0.png"; + + try { + // Create test input image + await createTestImage(testInput); + + // Generate tile with default options + await generate({ + input: testInput, + angleOption: 0, + maxValidSize: 2000, + } as GenerateOptions); + + // Verify output file was created + assertEquals(existsSync(expectedOutput), true); + } finally { + await cleanupTestFiles([testInput, expectedOutput]); + } +}); + +Deno.test("generate - successful generation with degrees parameter", async () => { + const testInput = "/tmp/test-input-degrees.png"; + const expectedOutput = "/tmp/test-input-degrees-tile-45.png"; + + try { + // Create test input image + await createTestImage(testInput); + + // Generate tile with degrees parameter + await generate({ + input: testInput, + degrees: 45, + maxValidSize: 2000, + } as GenerateOptions); + + // Verify output file was created + assertEquals(existsSync(expectedOutput), true); + } finally { + await cleanupTestFiles([testInput, expectedOutput]); + } +}); + +Deno.test("generate - error when input file is missing", async () => { + await assertRejects( + async () => { + await generate({ + maxValidSize: 2000, + } as GenerateOptions); + }, + Error, + "Input file is required for generation.", + ); +}); + +Deno.test("generate - error when input file doesn't exist", async () => { + await assertRejects( + async () => { + await generate({ + input: "/tmp/nonexistent-file.png", + maxValidSize: 2000, + } as GenerateOptions); + }, + Error, + "Input file not found:", + ); +}); + +Deno.test("generate - error when angleOption is out of range (negative)", async () => { + const testInput = "/tmp/test-input-negative-angle.png"; + + try { + await createTestImage(testInput); + + await assertRejects( + async () => { + await generate({ + input: testInput, + angleOption: -1, + maxValidSize: 2000, + } as GenerateOptions); + }, + Error, + "Invalid angle index", + ); + } finally { + await cleanupTestFiles([testInput]); + } +}); + +Deno.test("generate - error when angleOption is out of range (too large)", async () => { + const testInput = "/tmp/test-input-large-angle.png"; + + try { + await createTestImage(testInput); + + await assertRejects( + async () => { + await generate({ + input: testInput, + angleOption: 999, + maxValidSize: 2000, + } as GenerateOptions); + }, + Error, + "Invalid angle index", + ); + } finally { + await cleanupTestFiles([testInput]); + } +}); + +Deno.test("generate - error when dimensions exceed maxValidSize", async () => { + const testInput = "/tmp/test-input-exceed-size.png"; + + try { + // Create a larger test image + const sharp = (await import("sharp")).default; + await sharp({ + create: { + width: 500, + height: 500, + channels: 4, + background: { r: 255, g: 0, b: 0, alpha: 1 }, + }, + }) + .png() + .toFile(testInput); + + await assertRejects( + async () => { + await generate({ + input: testInput, + angleOption: 7, // 63.435° (arctan 2) - will produce larger dimensions + maxValidSize: 100, // Very small max size to trigger error + } as GenerateOptions); + }, + Error, + "exceed maximum valid size", + ); + } finally { + await cleanupTestFiles([testInput]); + } +}); + +Deno.test("generate - successful generation with custom output path", async () => { + const testInput = "/tmp/test-input-custom-output.png"; + const customOutput = "/tmp/custom-output-name.png"; + + try { + // Create test input image + await createTestImage(testInput); + + // Generate tile with custom output path + await generate({ + input: testInput, + angleOption: 3, // 45 degrees + output: customOutput, + maxValidSize: 2000, + } as GenerateOptions); + + // Verify custom output file was created + assertEquals(existsSync(customOutput), true); + } finally { + await cleanupTestFiles([testInput, customOutput]); + } +}); + +Deno.test("generate - generation with specific angle options", async () => { + const testInput = "/tmp/test-input-angle-option.png"; + const expectedOutput = "/tmp/test-input-angle-option-tile-26.565.png"; + + try { + // Create test input image + await createTestImage(testInput); + + // Generate tile with angle option 5 (26.565°) + await generate({ + input: testInput, + angleOption: 5, + maxValidSize: 2000, + } as GenerateOptions); + + // Verify output file was created + assertEquals(existsSync(expectedOutput), true); + } finally { + await cleanupTestFiles([testInput, expectedOutput]); + } +}); From 0bac7e9f885e5a086ef891a58f833101765a996f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:22:00 +0000 Subject: [PATCH 3/4] Add testing documentation to README Co-authored-by: marlonmarcello <1956448+marlonmarcello@users.noreply.github.com> --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 3471b24..130f818 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,20 @@ The output file will be saved in the same directory as the input with the angle deno run -A main.ts ``` +### Running Tests + +To run the test suite: + +```sh +deno task test +``` + +Or run tests directly: + +```sh +deno test --allow-all +``` + --- ## CLI Usage From 62686514e46574d3d80a39154a44a3eb031eac12 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:22:41 +0000 Subject: [PATCH 4/4] Clarify angle comment in test Co-authored-by: marlonmarcello <1956448+marlonmarcello@users.noreply.github.com> --- main_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main_test.ts b/main_test.ts index 68f3bf3..23b1795 100644 --- a/main_test.ts +++ b/main_test.ts @@ -165,7 +165,7 @@ Deno.test("generate - error when dimensions exceed maxValidSize", async () => { async () => { await generate({ input: testInput, - angleOption: 7, // 63.435° (arctan 2) - will produce larger dimensions + angleOption: 7, // 63.435° - will produce larger dimensions maxValidSize: 100, // Very small max size to trigger error } as GenerateOptions); },