Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
2 changes: 1 addition & 1 deletion main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export interface GenerateOptions {
input?: string;
}

async function generate({
export async function generate({
angleOption = 0,
degrees,
output,
Expand Down
223 changes: 223 additions & 0 deletions main_test.ts
Original file line number Diff line number Diff line change
@@ -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° - 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]);
}
});