summaryrefslogtreecommitdiffstats
path: root/CLI/ruby
diff options
context:
space:
mode:
authora14m <[email protected]>2020-12-14 15:13:37 +0100
committera14m <[email protected]>2020-12-14 15:13:37 +0100
commite706a28b85b47d9c6944cff691b88101c1605138 (patch)
treed09eb8c53096fe72efbec802c25ae7e9d570fd70 /CLI/ruby
parent3a84b11208e8378424790be4302a82f61a556186 (diff)
Fix rspec violations and complete coverage testing
Diffstat (limited to 'CLI/ruby')
-rw-r--r--CLI/ruby/.rubocop.yml11
-rw-r--r--CLI/ruby/spec/game_of_life/cell_spec.rb31
-rw-r--r--CLI/ruby/spec/game_of_life/plane_spec.rb20
-rw-r--r--CLI/ruby/spec/game_of_life_spec.rb63
4 files changed, 86 insertions, 39 deletions
diff --git a/CLI/ruby/.rubocop.yml b/CLI/ruby/.rubocop.yml
index 075df4f..a84ca99 100644
--- a/CLI/ruby/.rubocop.yml
+++ b/CLI/ruby/.rubocop.yml
@@ -1,3 +1,6 @@
+require:
+ - rubocop-rspec
+
AllCops:
TargetRubyVersion: 2.5
NewCops: enable
@@ -47,3 +50,11 @@ Style/TrailingCommaInArrayLiteral:
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: comma
+RSpec/ExampleLength:
+ Max: 12
+
+RSpec/MessageSpies:
+ EnforcedStyle: receive
+
+RSpec/MultipleExpectations:
+ Max: 4
diff --git a/CLI/ruby/spec/game_of_life/cell_spec.rb b/CLI/ruby/spec/game_of_life/cell_spec.rb
index 00f55b3..088bdae 100644
--- a/CLI/ruby/spec/game_of_life/cell_spec.rb
+++ b/CLI/ruby/spec/game_of_life/cell_spec.rb
@@ -1,5 +1,7 @@
# 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) }
@@ -20,6 +22,8 @@ RSpec.describe GameOfLife::Cell do
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]
@@ -29,17 +33,18 @@ RSpec.describe GameOfLife::Cell do
context "when dead" do
it "stays dead" do
- expect(dead_cell).to receive(:living_neighbors).with([]).and_return 0
+ 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.dead?).to be_truthy
+ 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.alive?).to be_truthy
+ expect(next_generation).to be_alive
end
end
@@ -48,40 +53,42 @@ RSpec.describe GameOfLife::Cell 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.alive?).to be_truthy
+ 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.alive?).to be_truthy
+ 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.dead?).to be_truthy
+ 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.dead?).to be_truthy
+ expect(next_generation).to be_dead
end
end
end
+ # rubocop:enable RSpec/SubjectStub
+ # rubocop:enable RSpec/StubbedMock
describe "#alive?" do
- it { expect(living_cell.alive?).to be_truthy }
- it { expect(dead_cell.alive?).to be_falsy }
+ it { expect(living_cell).to be_alive }
+ it { expect(dead_cell).not_to be_alive }
end
describe "#dead?" do
- it { expect(living_cell.dead?).to be_falsy }
- it { expect(dead_cell.dead?).to be_truthy }
+ it { expect(living_cell).not_to be_dead }
+ it { expect(dead_cell).to be_dead }
end
describe "#living_neighbors" do
@@ -134,3 +141,5 @@ RSpec.describe GameOfLife::Cell do
end
end
end
+# rubocop:enable RSpec/MultipleSubjects
+# rubocop:enable RSpec/EmptyLineAfterSubject
diff --git a/CLI/ruby/spec/game_of_life/plane_spec.rb b/CLI/ruby/spec/game_of_life/plane_spec.rb
index c4efbb4..88ce0dc 100644
--- a/CLI/ruby/spec/game_of_life/plane_spec.rb
+++ b/CLI/ruby/spec/game_of_life/plane_spec.rb
@@ -3,36 +3,36 @@
RSpec.describe GameOfLife::Plane do
describe "#[]" do
context "when empty" do
- subject { described_class.new }
+ subject(:cyclic_array) { described_class.new }
it "returns nil with [-1]" do
- expect(subject[-1]).to be_nil
+ expect(cyclic_array[-1]).to be_nil
end
it "returns nil with [0]" do
- expect(subject[0]).to be_nil
+ expect(cyclic_array[0]).to be_nil
end
it "returns nil with [1]" do
- expect(subject[1]).to be_nil
+ expect(cyclic_array[1]).to be_nil
end
end
context "when not empty" do
- subject { described_class.new([0, 1, 2, 3]) }
+ subject(:cyclic_array) { described_class.new([0, 1, 2, 3]) }
it "returns value at index" do
- expect(subject[0]).to eq 0
+ expect(cyclic_array[0]).to eq 0
end
it "returns value at -index (negative indices count backward from the end of the array)" do
- expect(subject[-5]).to eq 3
- expect(subject[-1]).to eq 3
+ expect(cyclic_array[-5]).to eq 3
+ expect(cyclic_array[-1]).to eq 3
end
it "returns value at any index (indices bigger than size cycle again from the beginning)" do
- expect(subject[5]).to eq 1
- expect(subject[9]).to eq 1
+ expect(cyclic_array[5]).to eq 1
+ expect(cyclic_array[9]).to eq 1
end
end
end
diff --git a/CLI/ruby/spec/game_of_life_spec.rb b/CLI/ruby/spec/game_of_life_spec.rb
index 00b58b8..285b766 100644
--- a/CLI/ruby/spec/game_of_life_spec.rb
+++ b/CLI/ruby/spec/game_of_life_spec.rb
@@ -2,65 +2,79 @@
RSpec.describe GameOfLife do
describe ".parsed_options" do
- context "options['delay']" do
- it "raises GameOfLife::Error when negative delay" do
+ before do
+ console = instance_double("<File:/dev/tty>")
+ allow(IO).to receive(:console).and_return(console)
+ allow(console).to receive(:winsize).and_return([10, 20])
+ end
+
+ context "with options['delay']" do
+ it "raises GameOfLife::Error when negative" do
options = { "delay" => -13 }
expect { described_class.parsed_options(options) }.to raise_error(GameOfLife::Error, /Invalid --delay value/)
end
- it "uses options['delay'] when provided" do
+ it "uses options['delay'] when posotive" do
options = { "delay" => 15 }
expect(described_class.parsed_options(options)).to include("delay" => 15)
end
end
- context "options['width']" do
- it "raises GameOfLife::Error when width < 1" do
+ context "with options['width']" do
+ it "raises GameOfLife::Error when < 1" do
options = { "width" => 0 }
expect { described_class.parsed_options(options) }.to raise_error(GameOfLife::Error, /Invalid --width value/)
end
- it "raises GameOfLife::Error when width > IO.console.winsize[1]" do
+ it "raises GameOfLife::Error when > IO.console.winsize[1]" do
options = { "width" => 23 }
- allow(IO).to receive_message_chain(:console, :winsize).and_return([10, 20])
expect { described_class.parsed_options(options) }.to raise_error(GameOfLife::Error, /Invalid --width value/)
end
- it "uses options['width'] when provided" do
+ it "uses options['width']" do
options = { "width" => 15 }
- allow(IO).to receive_message_chain(:console, :winsize).and_return([10, 20])
expect(described_class.parsed_options(options)).to include("width" => 15)
end
it "uses IO.console.winsize[1] as default" do
- allow(IO).to receive_message_chain(:console, :winsize).and_return([10, 20])
expect(described_class.parsed_options({})).to include("width" => 20)
end
end
- context "options['height']" do
- it "raises GameOfLife::Error when height < 1" do
+ context "with options['height']" do
+ it "raises GameOfLife::Error < 1" do
options = { "height" => 0 }
expect { described_class.parsed_options(options) }.to raise_error(GameOfLife::Error, /Invalid --height value/)
end
- it "raises GameOfLife::Error when height > winsize[0] - 2" do
+ it "raises GameOfLife::Error when > winsize[0] - 2" do
options = { "height" => 9 }
- allow(IO).to receive_message_chain(:console, :winsize).and_return([10, 20])
expect { described_class.parsed_options(options) }.to raise_error(GameOfLife::Error, /Invalid --height value/)
end
- it "uses options['height'] when provided" do
+ it "uses options['height']" do
options = { "height" => 5 }
- allow(IO).to receive_message_chain(:console, :winsize).and_return([10, 20])
expect(described_class.parsed_options(options)).to include("height" => 5)
end
it "uses IO.console.winsize[0] - 2 as default" do
- allow(IO).to receive_message_chain(:console, :winsize).and_return([10, 20])
expect(described_class.parsed_options({})).to include("height" => 8)
end
end
+
+ context "with options['seed']" do
+ it "uses options['seed']" do
+ options = { "seed" => 1337 }
+ expect(described_class.parsed_options(options)).to include("seed" => 1337)
+ end
+
+ # rubocop:disable RSpec/AnyInstance
+ it "defaults to Kernel.random" do
+ allow_any_instance_of(Kernel).to receive(:rand).and_return "random"
+ expect(described_class.parsed_options({})).to include("seed" => "random")
+ end
+ # rubocop:enable RSpec/AnyInstance
+ end
end
describe ".generate" do
@@ -134,5 +148,18 @@ RSpec.describe GameOfLife do
end
end
- describe.pending ".render"
+ describe ".render" do
+ let(:universe) { GameOfLife::Universe.new(width: 3, height: 3) }
+
+ it "renders the game of life presentation" do
+ stub_const("BANNER", "")
+ stub_const("DELAY", 100.0)
+ expect_any_instance_of(Kernel).to receive(:puts).with("\33c\e[3J")
+ expect_any_instance_of(Kernel).to receive(:puts).twice
+ expect(universe).to receive(:to_s)
+ expect_any_instance_of(Kernel).to receive(:sleep)
+
+ described_class.render(universe)
+ end
+ end
end