main
  1describe Cell do
  2  let(:living_neighbor) { Cell.new(alive: true) }
  3  let(:dead_neighbor) { Cell.new(alive: false) }
  4  let(:world) { double }
  5
  6  context "when alive" do
  7    subject { Cell.new(alive: true) }
  8
  9    it "is alive at creation" do
 10      expect(subject.alive?).to be_truthy
 11    end
 12
 13    context "when it has a single living neighbor" do
 14      let(:neighbors) { [living_neighbor, dead_neighbor] }
 15
 16      it "dies of isolation" do
 17        world.stub(:neighbors_for).with(subject).and_return(neighbors)
 18        expect(subject.spawn(world)).to_not be_alive
 19      end
 20    end
 21
 22    context 'when it has two living neighbors' do
 23      let(:neighbors) { [living_neighbor] * 2 }
 24
 25      it "remains living" do
 26        world.stub(:neighbors_for).with(subject).and_return(neighbors)
 27        expect(subject.spawn(world)).to be_alive
 28      end
 29    end
 30
 31    context 'when it has three living neighbors' do
 32      let(:neighbors) { [living_neighbor] * 3 }
 33
 34      it "remains living" do
 35        world.stub(:neighbors_for).with(subject).and_return(neighbors)
 36        expect(subject.spawn(world)).to be_alive
 37      end
 38    end
 39
 40    context 'when it has more than three neighbors' do
 41      let(:neighbors) { [living_neighbor] * 4 }
 42
 43      it "dies" do
 44        world.stub(:neighbors_for).with(subject).and_return(neighbors)
 45        expect(subject.spawn(world)).to_not be_alive
 46      end
 47    end
 48  end
 49
 50  context "when dead" do
 51    subject { Cell.new(alive: false) }
 52    let(:living_neighbors) { [living_neighbor] * 2 }
 53    let(:neighbors) { living_neighbors + [dead_neighbor] }
 54
 55    context "when it has two living neighbors" do
 56      it "remains dead" do
 57        world.stub(:neighbors_for).with(subject).and_return(neighbors)
 58        expect(subject.spawn(world)).to_not be_alive
 59      end
 60    end
 61  end
 62
 63  describe "neighbor?" do
 64    subject { create_cell(3, 3) }
 65
 66    context "when other cell is one cell north" do
 67      it "returns true" do
 68        expect(subject.neighbor?(create_cell(3, 4))).to be_truthy
 69      end
 70    end
 71
 72    context "when the other cell is two cells north" do
 73      it "returns false" do
 74        expect(subject.neighbor?(create_cell(3, 5))).to be_falsey
 75      end
 76    end
 77
 78    context "when other cell is one cell east" do
 79      it "returns true" do
 80        expect(subject.neighbor?(create_cell(4, 3))).to be_truthy
 81      end
 82    end
 83
 84    context "when other cell is two cells to the east" do
 85      it "returns true" do
 86        expect(subject.neighbor?(create_cell(5, 3))).to be_falsey
 87      end
 88    end
 89
 90    context "when the other cell is one cell to the south" do
 91      it "return true" do
 92        expect(subject.neighbor?(create_cell(3, 2))).to be_truthy
 93      end
 94    end
 95
 96    context "when the other cell is two cells to the south" do
 97      it "returns false" do
 98        expect(subject.neighbor?(create_cell(3, 1))).to be_falsey
 99      end
100    end
101
102    context "when the other cell is one cell to the west" do
103      it "returns true" do
104        expect(subject.neighbor?(create_cell(2, 3))).to be_truthy
105      end
106    end
107
108    context "when the other cell is two cells to the west" do
109      it "returns true" do
110        expect(subject.neighbor?(create_cell(1, 3))).to be_falsey
111      end
112    end
113
114    def create_cell(x, y)
115      Cell.new(x: x, y: y)
116    end
117  end
118end
119