lantern

sprout-garden-phase-3-test

Test: Sprout Garden Phase 3

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

Subject

Phase 3 plot types: gates, lap-counter, exit-gate, merge, teleport (conditionals and loops)

config

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

Spec

Test: Gate Blocks Non-Matching Sprouts

describe('Gate Plot', () => {
  it('starGate passes star-shaped sprouts', () => {
    const gate = createGate({ shape: 'star' });
    const sprout = { shape: 'star', color: 'red' };
    
    expect(gate.canPass(sprout)).toBe(true);
  });
  
  it('starGate blocks non-star sprouts', () => {
    const gate = createGate({ shape: 'star' });
    const sprout = { shape: 'circle', color: 'red' };
    
    expect(gate.canPass(sprout)).toBe(false);
  });
  
  it('colorGate checks color property', () => {
    const gate = createGate({ color: 'blue' });
    
    expect(gate.canPass({ shape: 'circle', color: 'blue' })).toBe(true);
    expect(gate.canPass({ shape: 'circle', color: 'red' })).toBe(false);
  });
  
  it('gate grow() returns null when blocked', () => {
    const gate = createGate({ shape: 'star' });
    const sprout = { shape: 'circle', color: 'red' };
    
    expect(gate.grow(sprout)).toBeNull();
  });
});

Test: Lap Counter Increments

describe('Lap Counter Plot', () => {
  it('increments laps property', () => {
    const counter = lapCounter;
    const sprout = { shape: 'star', color: 'yellow', laps: 0 };
    
    const result = counter.grow(sprout);
    expect(result.laps).toBe(1);
  });
  
  it('creates laps property if missing', () => {
    const counter = lapCounter;
    const sprout = { shape: 'star', color: 'yellow' };
    
    const result = counter.grow(sprout);
    expect(result.laps).toBe(1);
  });
  
  it('preserves other sprout properties', () => {
    const counter = lapCounter;
    const sprout = { shape: 'star', color: 'yellow', laps: 3 };
    
    const result = counter.grow(sprout);
    expect(result.shape).toBe('star');
    expect(result.color).toBe('yellow');
    expect(result.laps).toBe(4);
  });
  
  it('has pass-through fruits', () => {
    expect(lapCounter.fruits).toContain('pass-through');
  });
});

Test: Exit Gate Conditional

describe('Exit Gate Plot', () => {
  it('blocks when laps < threshold', () => {
    const gate = createExitGate({ laps: 5 });
    const sprout = { shape: 'star', color: 'yellow', laps: 3 };
    
    expect(gate.shouldExit(sprout)).toBe(false);
  });
  
  it('allows exit when laps >= threshold', () => {
    const gate = createExitGate({ laps: 5 });
    const sprout = { shape: 'star', color: 'yellow', laps: 5 };
    
    expect(gate.shouldExit(sprout)).toBe(true);
  });
  
  it('has conditional fruits (exit vs loop)', () => {
    const gate = createExitGate({ laps: 5 });
    
    // When condition met: exit direction
    // When not met: loop back direction
    expect(gate.fruits).toContain('conditional');
  });
});

Test: Merge Accepts Multiple Inputs

describe('Merge Plot', () => {
  it('accepts from all 4 directions', () => {
    expect(merge.seeds).toContain('left');
    expect(merge.seeds).toContain('right');
    expect(merge.seeds).toContain('up');
    expect(merge.seeds).toContain('down');
  });
  
  it('outputs to single direction', () => {
    // Merge combines paths, outputs one way
    expect(merge.fruits.length).toBe(1);
  });
  
  it('passes sprout through unchanged', () => {
    const sprout = { shape: 'star', color: 'yellow', laps: 2 };
    expect(merge.grow(sprout)).toEqual(sprout);
  });
});

Test: Teleport Jumps Position

describe('Teleport Plot', () => {
  it('has target address as fruit', () => {
    const teleport = createTeleport('A5');
    
    // Teleport's fruit is a position, not a direction
    expect(teleport.fruits).toContain('A5');
  });
  
  it('passes sprout through unchanged', () => {
    const teleport = createTeleport('A5');
    const sprout = { shape: 'star', color: 'yellow' };
    
    expect(teleport.grow(sprout)).toEqual(sprout);
  });
});

Test: For-Loop Pattern

describe('For-Loop Pattern', () => {
  it('sprout completes N laps before exit', () => {
    const sim = new Simulation(raceTrackGarden);
    const result = sim.run();
    
    const finishedSprout = result.sprouts.find(s => s.status === 'arrived');
    expect(finishedSprout.laps).toBe(5);
  });
  
  it('detects infinite loops', () => {
    const sim = new Simulation(infiniteLoopGarden);
    const result = sim.run(100); // Max ticks
    
    const loopingSprout = result.sprouts.find(s => s.status === 'looping');
    expect(loopingSprout).toBeDefined();
  });
});

Results

{
  "summary": "0/5 tests passing",
  "phase": "Phase 3: Gates & Loops",
  "status": "not yet implemented",
  "tests": [
    {
      "test": "gate.js exists",
      "status": "fail",
      "details": "not yet implemented"
    },
    {
      "test": "lap-counter.js exists",
      "status": "fail",
      "details": "not yet implemented"
    },
    {
      "test": "exit-gate.js exists",
      "status": "fail",
      "details": "not yet implemented"
    },
    {
      "test": "merge.js exists",
      "status": "fail",
      "details": "not yet implemented"
    },
    {
      "test": "teleport.js exists",
      "status": "fail",
      "details": "not yet implemented"
    }
  ]
}

Provenance

Fences

test-gate-blocks

  • Status: Spec only (Phase 3 not implemented)
  • By: Claude (2025-11-29)
  • Note: Gate conditional logic

test-lap-counter

  • Status: Spec only
  • By: Claude (2025-11-29)
  • Note: Counter increment behavior

test-exit-gate

  • Status: Spec only
  • By: Claude (2025-11-29)
  • Note: Loop exit condition

test-merge

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

test-teleport

  • Status: Spec only
  • By: Claude (2025-11-29)
  • Note: Non-adjacent position jumping

test-for-loop-pattern

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

sprout-garden-phase-3-results

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

Slots

North

slots:
- sprout-garden-phase-3

South

slots: []

East

slots: []

West

slots:
- pattern-looking-glass-development
↑ northsprout-garden-phase-3