Skip to content
Merged
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
10 changes: 7 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

ccsay is a joke CLI tool that displays text in ASCII art similar to cowsay. It renders text using block-style Unicode characters in orange color (ANSI escape code). By default, it displays "CLAUDE CODE" but accepts custom text as command-line arguments.
ccsay is a joke CLI tool that displays text in ASCII art similar to cowsay. It renders text using block-style Unicode characters in orange color (ANSI escape code). By default, it displays "CLAUDE CODE" but accepts custom text as command-line arguments. It supports color customization and help options.

## Development Setup

Expand All @@ -24,6 +24,7 @@ bun install
# Run in development
bun run dev
bun run src/index.ts "YOUR TEXT"
bun run src/index.ts --help # Show help

# Run tests
bun test
Expand All @@ -46,7 +47,8 @@ ccsay/
│ ├── index.ts # CLI entry point
│ └── fonts.ts # ASCII art font definitions
├── test/
│ └── fonts.test.ts # Unit tests
│ ├── fonts.test.ts # Font tests
│ └── index.test.ts # CLI tests
├── biome.json # Formatter/linter config
├── vitest.config.ts # Test runner config
└── package.json # Project configuration
Expand All @@ -64,11 +66,13 @@ ccsay/

The project consists of two main modules:
1. `fonts.ts`: Contains the BLOCK_FONT dictionary mapping characters to 6-line ASCII art arrays
2. `index.ts`: CLI interface that processes arguments and outputs colored ASCII art
2. `index.ts`: CLI interface that processes arguments, handles help flags, and outputs colored ASCII art

## Testing

Tests are written using Vitest and cover:
- Font character availability (A-Z, 0-9, punctuation)
- Text-to-ASCII conversion logic
- CLI argument parsing (color flags, help flags)
- Help functionality and output formatting
- Edge cases (empty strings, unknown characters)
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@ ccsay "Hello World"

# Multiple words
ccsay "This is awesome"

# Show help
ccsay --help
ccsay -h
```

### Color Options

```bash
# Default orange color
ccsay "Hello World"

# Red text
ccsay -c red "ERROR"
ccsay --color red "ERROR"

# Available colors: black, red, green, yellow, blue, magenta, cyan, white, orange, purple, pink, gray, grey
ccsay -c blue "BUILDING..."
```

### Multi-line Text
Expand Down
35 changes: 35 additions & 0 deletions src/index.ts
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,43 @@ function parseColor(colorInput: string): string {
return COLOR_MAP[color] || COLOR_MAP.orange || "\x1b[38;5;208m"; // Default to orange if color not found
}

function showHelp(): void {
const helpText = `ccsay - Display text in colorful ASCII art

Usage:
ccsay [options] [text]
echo "text" | ccsay [options]

Options:
--help, -h Show this help message
--color, -c Set text color (default: orange)
Available colors: black, red, green, yellow, blue, magenta,
cyan, white, orange, purple, pink, gray, grey

Examples:
ccsay "Hello World" Display "Hello World" in ASCII art
ccsay -c red "ERROR" Display "ERROR" in red
ccsay "Line 1\\nLine 2" Multi-line text with newlines
echo "Piped text" | ccsay Read from stdin
ccsay --color blue "BUILDING..." Display in blue color

Version:
0.0.2

For more information, visit: https://github.com/watany-dev/ccsay`;

console.log(helpText);
}

export function main() {
const args = process.argv.slice(2);

// Check for help flags first
if (args.includes("--help") || args.includes("-h")) {
showHelp();
return;
}

let color = COLOR_MAP.orange; // Default color
const textArgs: string[] = [];

Expand Down
64 changes: 64 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,68 @@ describe("index", () => {
expect(output).toContain("████████╗███████╗███████╗████████╗"); // TEST in ASCII art
});
});

describe("help functionality", () => {
it("should display help when --help flag is used", () => {
process.argv = ["node", "index.ts", "--help"];
main();
const output = consoleLogSpy.mock.calls[0]?.[0];
expect(output).toContain("Usage:");
expect(output).toContain("ccsay");
expect(output).toContain("Options:");
expect(output).toContain("--help, -h");
expect(output).toContain("--color, -c");
// Should not contain ASCII art
expect(output).not.toContain("██");
});

it("should display help when -h flag is used", () => {
process.argv = ["node", "index.ts", "-h"];
main();
const output = consoleLogSpy.mock.calls[0]?.[0];
expect(output).toContain("Usage:");
expect(output).toContain("ccsay");
expect(output).toContain("Options:");
expect(output).toContain("--help, -h");
expect(output).toContain("--color, -c");
// Should not contain ASCII art
expect(output).not.toContain("██");
});

it("should display help when --help is mixed with other arguments", () => {
process.argv = ["node", "index.ts", "SOME_TEXT", "--help", "-c", "red"];
main();
const output = consoleLogSpy.mock.calls[0]?.[0];
expect(output).toContain("Usage:");
expect(output).toContain("ccsay");
// Should not contain ASCII art even with other args
expect(output).not.toContain("██");
});

it("should display help when -h is mixed with other arguments", () => {
process.argv = ["node", "index.ts", "-c", "blue", "-h", "TEXT"];
main();
const output = consoleLogSpy.mock.calls[0]?.[0];
expect(output).toContain("Usage:");
expect(output).toContain("ccsay");
// Should not contain ASCII art even with other args
expect(output).not.toContain("██");
});

it("should contain examples in help output", () => {
process.argv = ["node", "index.ts", "--help"];
main();
const output = consoleLogSpy.mock.calls[0]?.[0];
expect(output).toContain("Examples:");
expect(output).toContain('ccsay "Hello World"');
});

it("should contain version information in help output", () => {
process.argv = ["node", "index.ts", "--help"];
main();
const output = consoleLogSpy.mock.calls[0]?.[0];
expect(output).toContain("Version:");
expect(output).toContain("0.0.2");
});
});
});