Files
go-jdenticon/CLAUDE.md
Kevin McIntyre f84b511895 init
2025-06-18 01:00:00 -04:00

294 lines
10 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Go Jdenticon - Development Guide for Claude Code
## Project Overview
Go Jdenticon is a Go library for generating highly recognizable identicons - geometric avatar images generated deterministically from any input string. This is a Go port of the JavaScript library [Jdenticon](https://github.com/dmester/jdenticon).
**Critical Achievement**: This implementation maintains **byte-for-byte identical SVG output** with the JavaScript reference implementation through careful algorithm replication.
## Key Features
- Renders identicons as PNG or SVG with no external dependencies
- Generates consistent, deterministic identicons from any input string
- Highly customizable color themes and styling options
- Command-line tool included for standalone usage
- **JavaScript reference compatibility** - produces identical output to the original JavaScript library
## Project Structure
```
go-jdenticon/
 jdenticon/ # Public API package
  config.go # Public configuration options
  generate.go # Main API functions
  hash.go # Hash computation and parsing
  reference_test.go # JavaScript compatibility tests
 internal/
  engine/ # Core generation logic
   generator.go # Main generation algorithm (CRITICAL FILE)
   shapes.go # Shape rendering with transforms
   color.go # Color theme generation
   config.go # Internal configuration
   layout.go # Grid layout system
   transform.go # Coordinate transformations
  renderer/ # Output rendering
  renderer.go # Base renderer interface
  svg.go # SVG output (maintains z-order!)
  png.go # PNG output using Go imaging
 cmd/jdenticon/ # Command-line tool
 jdenticon-js/ # JavaScript reference implementation
 example_usage.go # Demo and testing
```
## Build & Test Commands
```bash
# Run all tests
go test ./jdenticon ./internal/...
# Run specific test packages
go test ./jdenticon
go test ./internal/engine
go test ./internal/renderer
# Run JavaScript compatibility tests (CRITICAL)
go test ./jdenticon -run TestJavaScriptReferenceCompatibility
# Build command-line tool
go build -o jdenticon cmd/jdenticon/main.go
# Generate demo avatars
go run example_usage.go
# Quick test with visualization
go run quick_test.go
```
## Core Algorithm Architecture
### Generation Flow (internal/engine/generator.go)
The generation algorithm follows this exact sequence to match JavaScript:
1. **Hash Parsing**: Extract values from specific positions in SHA1 hash
- Positions 2,3: Side shape selection
- Positions 4,5: Corner shape selection
- Position 1: Center shape selection
- Position 0: Main hue value
2. **Shape Selection**: Use hard-coded position arrays (NOT layout engine)
```go
positions := [][]int{{1, 0}, {2, 0}, {2, 3}, {1, 3}, {0, 1}, {3, 1}, {3, 2}, {0, 2}}
```
3. **Color Generation**: Create theme colors from hue with specific lightness ranges
4. **Shape Rendering**: Process in exact order:
- Outer shapes (sides + corners) with rotations
- Center shapes with incremental rotation when no rotation hash
### Critical Implementation Details
#### Shape Selection Algorithm (generator.go:67-95)
```go
// CRITICAL: Use exact hash positions to match JavaScript
sideShapeIndex := parseHex(hash, 2, 1) % len(outerShapes)
cornerShapeIndex := parseHex(hash, 4, 1) % len(outerShapes)
centerShapeIndex := parseHex(hash, 1, 1) % len(centerShapes)
```
#### Transform Application (generator.go:125-135)
```go
// Center shapes: increment rotation per position when no rotation hash
if rotationHashIndex == -1 {
transformRotation = i % 4
} else {
transformRotation = parseHex(hash, rotationHashIndex, 1) % 4
}
```
#### Z-Order Rendering (renderer/svg.go)
**CRITICAL**: SVG renderer preserves insertion order, NOT alphabetical:
```go
// Maintain colorOrder to preserve z-order
for _, color := range r.colorOrder {
// Render in insertion order
}
```
## JavaScript Reference Compatibility
### ⚠️ CRITICAL REQUIREMENT ⚠️
**THE `jdenticon/reference_test.go` FILE MUST ALWAYS PASS**
This is the **MOST IMPORTANT** test in the entire codebase. It validates that our Go implementation produces byte-for-byte identical SVG output to the JavaScript reference implementation.
**NEVER commit code that breaks this test. NEVER merge PRs with failing reference tests.**
### Reference Files Location
- JavaScript reference SVGs: `jdenticon-js/test/`
- Go compatibility test: `jdenticon/reference_test.go`
### Test Cases
The compatibility test validates three critical cases:
1. `"test-hash"` at 64px
2. `"example1@gmail.com"` at 64px
3. `"example2@yahoo.com"` at 64px
**These tests MUST pass** - they verify byte-for-byte identical SVG output.
### Running the Critical Test
```bash
# Run ONLY the reference compatibility test
go test ./jdenticon -run TestJavaScriptReferenceCompatibility -v
# This test MUST show:
# === RUN TestJavaScriptReferenceCompatibility/test-hash_@
# --- PASS: TestJavaScriptReferenceCompatibility/test-hash_@ (0.00s)
# === RUN TestJavaScriptReferenceCompatibility/example1@gmail.com_@
# --- PASS: TestJavaScriptReferenceCompatibility/example1@gmail.com_@ (0.00s)
# === RUN TestJavaScriptReferenceCompatibility/example2@yahoo.com_@
# --- PASS: TestJavaScriptReferenceCompatibility/example2@yahoo.com_@ (0.00s)
```
### If the Reference Test Fails
1. **STOP DEVELOPMENT** - Do not proceed with other changes
2. Investigate what changed in the generation algorithm
3. Check hash parsing positions in `generator.go`
4. Verify shape selection and rendering order
5. Check SVG z-order in `renderer/svg.go`
6. Compare against JavaScript implementation line by line
7. **DO NOT** change the reference files to match Go output
8. **FIX** the Go implementation to match JavaScript exactly
### Key Compatibility Requirements
1. **Hash Parsing**: Must use identical positions as JavaScript
2. **Shape Order**: Must render in same sequence (outer shapes, then center)
3. **Position Arrays**: Must use hard-coded JavaScript positions, not computed layout
4. **Transform Logic**: Center shape rotation must increment when no rotation hash
5. **Circle Interface**: Uses top-left + size (not center + radius)
6. **Z-Order**: SVG elements must maintain insertion order
## Common Development Patterns
### Adding New Shape Types
1. Update shape arrays in `generator.go`
2. Implement rendering in `shapes.go`
3. Add transform support if needed
4. **Always run compatibility tests**
### Modifying Color Generation
1. Changes in `internal/engine/color.go`
2. Ensure lightness ranges match JavaScript exactly
3. Test with variety of hue values
### Renderer Changes
1. Update base interface in `renderer/renderer.go`
2. Implement in both SVG and PNG renderers
3. **Critical**: Maintain z-order in SVG renderer
## Testing Strategy
### Unit Tests
- Each component has comprehensive unit tests
- Focus on boundary conditions and edge cases
- All tests should pass consistently
### Integration Tests
- `reference_test.go` - **MOST CRITICAL** - JavaScript compatibility
- `integration_test.go` - Visual regression testing
- PNG checksum validation for consistency
### Manual Testing
- Run `example_usage.go` to generate various avatar types
- Verify visual output matches expectations
- Test edge cases (empty strings, long inputs, special characters)
## Configuration System
### Public API (jdenticon/config.go)
```go
type Config struct {
Hue float64 // Color hue (0.0-1.0)
Saturation float64 // Color saturation (0.0-1.0)
Lightness float64 // Color lightness (0.0-1.0)
BackgroundColor string // Hex color or empty for transparent
Padding float64 // Padding as percentage (0.0-0.5)
}
```
### Internal Configuration (internal/engine/config.go)
- More detailed color ranges and restrictions
- Validation logic for all parameters
- Builder pattern for complex configurations
## Error Handling Patterns
1. **Input Validation**: Validate size > 0, hash format, config ranges
2. **Graceful Degradation**: Default to safe values for invalid inputs
3. **Clear Error Messages**: Provide actionable error information
4. **No Panics**: Always return errors, never panic in library code
## Performance Considerations
1. **Caching**: Generator caches theme colors for repeated use
2. **Memory Management**: Reuse objects where possible
3. **PNG Generation**: Uses efficient Go imaging library
4. **SVG Generation**: String builder for optimal performance
## Debugging & Troubleshooting
### Visual Debug Tools
- `example_usage.go` - Generates multiple test cases
- `quick_test.go` - Quick visualization
- Generated avatars saved as PNG/SVG files
### Common Issues
1. **Compatibility Test Failures**: Usually indicates algorithm change
2. **Color Inconsistency**: Check hue/lightness calculations
3. **Shape Positioning**: Verify transform application
4. **Z-Order Problems**: Check SVG renderer color ordering
### Debug Hash Extraction
Use the hash parsing utilities to understand how values are extracted:
```go
parseHex(hash, position, octets) // Extract specific hash segments
```
## Future Development Guidelines
1. **Maintain Compatibility**: Always run reference tests after changes
2. **Follow Go Conventions**: Use standard Go patterns and idioms
3. **Test Coverage**: Add tests for any new functionality
4. **Documentation**: Update this guide for significant changes
5. **Performance**: Profile before optimizing, measure impact
## Dependencies
- **Standard Library Only**: No external dependencies for core functionality
- **Testing**: Uses standard Go testing framework
- **Command Line**: Uses standard `flag` package
## API Usage Examples
### Basic Generation
```go
icon := jdenticon.Generate("user@example.com", 200)
svg := icon.ToSVG()
png := icon.ToPNG()
```
### With Custom Configuration
```go
config := &jdenticon.Config{
Hue: 0.3,
Saturation: 0.7,
Lightness: 0.5,
Padding: 0.1,
}
icon := jdenticon.GenerateWithConfig("user@example.com", 200, config)
```
This implementation successfully achieves JavaScript reference compatibility while maintaining clean Go idioms and comprehensive test coverage.