lantern

sprout-garden-phase-4-test

Test: Sprout Garden Phase 4

Following [[pattern-looking-glass-development]] - the tests ARE the documentation.

Subject

Phase 4 plot types: shape-fork, color-fork, binary-fork, grafter (routing and merging)

config

path: null
plots_dir: /Users/graemefawcett/working/ben.fawcett.family/activities/sprout-garden/src/plots/types

Spec

Test: Shape Fork Routes By Shape

describe('Shape Fork', () => {
  it('routes circles up', () => {
    const fork = shapeFork;
    const sprout = { shape: 'circle', color: 'red' };
    
    expect(fork.getOutputDirection(sprout)).toBe('up');
  });
  
  it('routes squares right', () => {
    const sprout = { shape: 'square', color: 'blue' };
    expect(shapeFork.getOutputDirection(sprout)).toBe('right');
  });
  
  it('routes triangles down', () => {
    const sprout = { shape: 'triangle', color: 'green' };
    expect(shapeFork.getOutputDirection(sprout)).toBe('down');
  });
  
  it('routes stars left', () => {
    const sprout = { shape: 'star', color: 'yellow' };
    expect(shapeFork.getOutputDirection(sprout)).toBe('left');
  });
  
  it('passes sprout through unchanged', () => {
    const sprout = { shape: 'circle', color: 'red' };
    expect(shapeFork.grow(sprout)).toEqual(sprout);
  });
});

Test: Color Fork Routes By Color

describe('Color Fork', () => {
  it('routes red up', () => {
    const sprout = { shape: 'circle', color: 'red' };
    expect(colorFork.getOutputDirection(sprout)).toBe('up');
  });
  
  it('routes green right', () => {
    const sprout = { shape: 'square', color: 'green' };
    expect(colorFork.getOutputDirection(sprout)).toBe('right');
  });
  
  it('routes blue down', () => {
    const sprout = { shape: 'triangle', color: 'blue' };
    expect(colorFork.getOutputDirection(sprout)).toBe('down');
  });
  
  it('routes yellow left', () => {
    const sprout = { shape: 'star', color: 'yellow' };
    expect(colorFork.getOutputDirection(sprout)).toBe('left');
  });
});

Test: Binary Fork Routes By Condition

describe('Binary Fork', () => {
  it('routes matching sprouts one way', () => {
    const fork = createBinaryFork({ property: 'shape', value: 'star' });
    const sprout = { shape: 'star', color: 'red' };
    
    expect(fork.getOutputDirection(sprout)).toBe('right'); // true path
  });
  
  it('routes non-matching sprouts other way', () => {
    const fork = createBinaryFork({ property: 'shape', value: 'star' });
    const sprout = { shape: 'circle', color: 'red' };
    
    expect(fork.getOutputDirection(sprout)).toBe('down'); // false path
  });
  
  it('can check color property', () => {
    const fork = createBinaryFork({ property: 'color', value: 'blue' });
    
    expect(fork.getOutputDirection({ shape: 'circle', color: 'blue' })).toBe('right');
    expect(fork.getOutputDirection({ shape: 'circle', color: 'red' })).toBe('down');
  });
});

Test: Grafter Merges Paths

describe('Grafter', () => {
  it('accepts from all 4 directions', () => {
    expect(grafter.seeds).toContain('left');
    expect(grafter.seeds).toContain('right');
    expect(grafter.seeds).toContain('up');
    expect(grafter.seeds).toContain('down');
  });
  
  it('outputs to single direction', () => {
    expect(grafter.fruits.length).toBe(1);
  });
  
  it('passes sprout through unchanged', () => {
    const sprout = { shape: 'star', color: 'yellow' };
    expect(grafter.grow(sprout)).toEqual(sprout);
  });
});

Test: Fork-Graft Pattern

describe('Fork-Graft Pattern', () => {
  it('sprouts rejoin after fork', () => {
    // Garden: spring → fork → [path A, path B] → grafter → harvest
    const sim = new Simulation(forkGraftGarden);
    const result = sim.run();
    
    // All sprouts should arrive regardless of which path they took
    expect(result.sprouts.every(s => s.status === 'arrived')).toBe(true);
  });
  
  it('different shapes take different paths', () => {
    const sim = new Simulation(shapeSortingGarden);
    sim.run();
    
    // Check lineage shows different routes
    const circles = sim.sprouts.filter(s => s.shape === 'circle');
    const squares = sim.sprouts.filter(s => s.shape === 'square');
    
    // Circles went through path A, squares through path B
    expect(circles[0].lineage.map(l => l.plot)).not.toEqual(
      squares[0].lineage.map(l => l.plot)
    );
  });
});

Results

{
  "summary": "0/4 tests passing",
  "phase": "Phase 4: Forking",
  "status": "not yet implemented",
  "tests": [
    {
      "test": "shape-fork.js exists",
      "status": "fail",
      "details": "not yet implemented"
    },
    {
      "test": "color-fork.js exists",
      "status": "fail",
      "details": "not yet implemented"
    },
    {
      "test": "binary-fork.js exists",
      "status": "fail",
      "details": "not yet implemented"
    },
    {
      "test": "grafter.js exists",
      "status": "fail",
      "details": "not yet implemented"
    }
  ]
}

Provenance

Fences

test-shape-fork

  • Status: Spec only (Phase 4 not implemented)
  • By: Claude (2025-11-29)
  • Note: Shape-based routing

test-color-fork

  • Status: Spec only
  • By: Claude (2025-11-29)
  • Note: Color-based routing

test-binary-fork

  • Status: Spec only
  • By: Claude (2025-11-29)
  • Note: Configurable condition routing

test-grafter

  • Status: Spec only
  • By: Claude (2025-11-29)
  • Note: Path merging

test-fork-graft-pattern

  • Status: Spec only
  • By: Claude (2025-11-29)
  • Note: Integration test for fork-graft

sprout-garden-phase-4-results

  • Status: Verified (checks for implementation)
  • By: Claude (2025-11-29)
  • Note: Reports Phase 4 implementation status

Slots

North

slots:
- sprout-garden-phase-4

South

slots: []

East

slots: []

West

slots:
- pattern-looking-glass-development