# frozen_string_literal: true # rubocop:disable RSpec/MultipleSubjects # rubocop:disable RSpec/EmptyLineAfterSubject RSpec.describe GameOfLife::Cell do subject(:living_cell) { described_class.new(x: nil, y: nil, alive: true) } subject(:dead_cell) { described_class.new(x: nil, y: nil, alive: false) } describe "#to_s" do context "when alive" do it "returns LIVE_CELL representation" do stub_const("LIVE_CELL", "X") expect(living_cell.to_s).to eq "X" end end context "when dead" do it "returns DEAD_CELL representation" do stub_const("DEAD_CELL", ".") expect(dead_cell.to_s).to eq "." end end end # rubocop:disable RSpec/SubjectStub # rubocop:disable RSpec/StubbedMock describe "#evolve!" do it "calls #living_neighbors with param: neighbors" do neighbors = [1, 2, 3, 4, 5] expect(living_cell).to receive(:living_neighbors).with(neighbors) living_cell.evolve!(neighbors) end context "when dead" do it "stays dead" do allow(dead_cell).to receive(:living_neighbors).with([]).and_return 0 expect(dead_cell).to receive(:living_neighbors) next_generation = dead_cell.evolve!([]) expect(next_generation.object_id).to eq dead_cell.object_id expect(next_generation).to be_dead end it "becomes alive when having 3 living neighbors" do expect(dead_cell).to receive(:living_neighbors).with([]).and_return 3 next_generation = dead_cell.evolve!([]) expect(next_generation.object_id).not_to eq dead_cell.object_id expect(next_generation).to be_alive end end context "when alive" do it "survives when having 2 neighbors" do expect(living_cell).to receive(:living_neighbors).with([]).and_return 2 next_generation = living_cell.evolve!([]) expect(next_generation.object_id).to eq living_cell.object_id expect(next_generation).to be_alive end it "survives when having 3 neighbors" do expect(living_cell).to receive(:living_neighbors).with([]).and_return 3 next_generation = living_cell.evolve!([]) expect(next_generation.object_id).to eq living_cell.object_id expect(next_generation).to be_alive end it "dies when having less than 2 neighbors" do expect(living_cell).to receive(:living_neighbors).with([]).and_return 1 next_generation = living_cell.evolve!([]) expect(next_generation.object_id).not_to eq living_cell.object_id expect(next_generation).to be_dead end it "dies when having more than 3 neighbors" do expect(living_cell).to receive(:living_neighbors).with([]).and_return 4 next_generation = living_cell.evolve!([]) expect(next_generation).not_to eq living_cell expect(next_generation).to be_dead end end end # rubocop:enable RSpec/SubjectStub # rubocop:enable RSpec/StubbedMock describe "#alive?" do it { expect(living_cell).to be_alive } it { expect(dead_cell).not_to be_alive } end describe "#dead?" do it { expect(living_cell).not_to be_dead } it { expect(dead_cell).to be_dead } end describe "#living_neighbors" do subject(:cell) { [living_cell, dead_cell].sample } let(:living_neighbors) { (0...rand(100)).map { described_class.new(x: nil, y: nil, alive: true) } } let(:dead_neighbors) { (0...rand(100)).map { described_class.new(x: nil, y: nil, alive: false) } } let(:neighbors) { (living_neighbors + dead_neighbors).shuffle } it "returns the count of living neighbors cells" do expect(cell.send(:living_neighbors, neighbors)).to eq living_neighbors.size end end describe "#repopulate!" do # evaluate subject to avoid multiple calls on first evaluation in the test subject!(:cell) { [dead_cell, living_cell].sample } it "returns living cell" do expect(described_class).to receive(:new).with(hash_including(alive: true)) cell.send(:repopulate!) end end describe "#survive!" do subject(:cell) { [dead_cell, living_cell].sample } it "returns self" do expect(cell.send(:survive!).object_id).to eq cell.object_id end end describe "#die!" do context "when dead" do subject(:cell) { dead_cell } it "returns self" do expect(cell.send(:die!).object_id).to eq cell.object_id end end context "when alive" do # evaluate subject to avoid multiple calls on first evaluation in the test subject!(:cell) { living_cell } it "returns new dead cell" do expect(described_class).to receive(:new).with(hash_including(alive: false)) cell.send(:die!) end end end end # rubocop:enable RSpec/MultipleSubjects # rubocop:enable RSpec/EmptyLineAfterSubject