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

10 KiB
Raw Blame History

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.

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

# 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)

    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)

// 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)

// 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:

// 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

# 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)

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:

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

icon := jdenticon.Generate("user@example.com", 200)
svg := icon.ToSVG()
png := icon.ToPNG()

With Custom Configuration

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.