Finished testing and docs for now. Time for new features!

This commit is contained in:
2025-10-02 23:58:24 -06:00
parent 279658f3e5
commit b8f54b44a3
16 changed files with 316 additions and 66 deletions
+157
View File
@@ -1,2 +1,159 @@
# frozen_string_literal: true
# Nathan Hinton 2 Oct 2025
# This is for testing the API that the clients can use.
# Most of the api is here as it relates to interacting with the universe
require './universe'
require './player'
require './position'
require './ship'
RSpec.describe 'API' do
# Universe setup
let(:name) { 'Test Universe' }
let(:universe_size) { 3 }
let(:seed) { 12345 }
subject(:universe) do
Universe.new(
name,
universe_size: universe_size,
seed: seed,
create_chances: { planet: 1 } # force a planet at every valid spot
)
end
before(:each) do
universe.create_universe
end
# Player setup
let(:player_1) { Player.new('test player 01') }
let(:player_2) { Player.new('test player 02') }
# Positions setup
let(:center_position) { Position.new(5, 3) }
describe 'UNIVERSE API' do
describe '#get_position' do
it 'returns a position in the universe' do
expect(universe.get_position(player_1, Position.new(0, 0))).to be nil
expect(universe.get_position(player_1, Position.new(3, 5))).to be_a(Planet)
expect(universe.get_position(player_1, center_position)).to be_a(Star)
end
end # describe Universe#get_position
end # describe 'UNIVERSE API'
describe 'SHIPS API' do
describe '@create_ship' do
it 'returns false when the player is invalid' do
expect(universe.create_ship(player_1, Position.new(3, 5))).to eq false
end
end # describe '@create_ship'
describe '@move_ship' do
it 'returns false when the player is invalid' do
expect(universe.move_ship(player_1, Ship.new(2, 4, player_1), Position.new(3, 5))).to eq false
end
end # describe '@move_ship'
describe '@remove_ship' do
it 'returns false when the player is invalid' do
expect(universe.remove_ship(player_1, Position.new(3, 5))).to eq false
end
end # describe '@remove_ship'
end # describe 'SHIPS API'
describe 'PLANETS API' do
describe '@remove_planet' do
end # describe '@remove_planet'
end # describe 'PLANETS API'
describe 'PLAYER API' do
describe '#add_player' do
it 'adds with free planets' do
expect(universe.add_player(player_1)).to be(true)
expect(universe.instance_variable_get(:@player_list)).to eq [player_1]
end
it 'fails to add when all planets are occopuied' do
# Make all the planets owned by player_2
universe.planets.each do |planet|
planet.change_owner(player_2)
end
expect(universe.add_player(player_1)).to be(false)
expect(universe.instance_variable_get(:@player_list)).to eq []
end
it 'raises an error if a planet can not be taken' do
# This is an exceptional case. This is actually proper behavior when
# not trying to deal out planets.
end
end # describe 'add_player'
describe '#remove_player' do
it 'can remove an existing player' do
universe.add_player(player_1)
expect(universe.remove_player(player_1)).to eq true
expect(universe.remove_player(player_2)).to eq true
expect(universe.instance_variable_get(:@player_list)).to eq []
end
it 'can remove a non existing player' do
expect(universe.remove_player(player_2)).to eq true
end
end # describe 'remove_player'
describe '#validate_player' do
it 'returns true when a player is valid' do
universe.add_player(player_1)
expect(universe.validate_player(player_1)).to eq true
end
it 'returns false when the player is not in the player list' do
expect(universe.validate_player(player_2)).to eq false
end
end # describe 'validate_player'
describe '#get_player_ships' do
it 'lists all ships owned by a player' do
universe.add_player(player_1)
universe.add_player(player_2)
expect(universe.get_player_ships(player_1)).to eq []
ship_1 = Ship.new(2, 4, player_1)
ship_2 = Ship.new(2, 4, player_2)
ship_3 = Ship.new(3, 5, player_1)
universe.instance_variable_set(:@ship_list, [ship_1, ship_2, ship_3])
expect(universe.get_player_ships(player_1)).to eq [ship_1, ship_3]
expect(universe.get_player_ships(player_2)).to eq [ship_2]
end
it 'returns an empty list when a player that is not registered gets ships' do
ship_2 = Ship.new(2, 4, player_2)
universe.instance_variable_set(:@ship_list, [ship_2])
expect(universe.get_player_ships(player_2)).to eq []
end
end # describe 'get_player_ships'
describe '#get_player_planets' do
it 'returns the planets owned by a player' do
universe.add_player(player_1)
expect(universe.get_player_planets(player_2)).to eq []
expect(universe.get_player_planets(player_1).length).to eq 1
end
it 'returns an empty list for a unregistered player' do
expect(universe.get_player_planets(player_2)).to eq []
end
end # describe 'get_player_planets'
end # describe 'PLAYER API'
end
+5 -5
View File
@@ -13,15 +13,15 @@ RSpec.describe Planet do
describe '#initialize' do
it 'stores the random off' do
expect(planet.instance_variable_get(:@random)).to eq(random)
expect(planet.instance_variable_get(:@random)).to eq random
end
it 'creates a production rate' do
expect(planet.instance_variable_get(:@prod_rate)).to eq(Random.new(seed).rand)
expect(planet.instance_variable_get(:@prod_rate)).to eq Random.new(seed).rand
end
it 'sets a resource' do
expect(planet.instance_variable_get(:@resource)).to eq(PLANET_PRODUCTION_RESOURCES[(Random.new(seed).rand * PLANET_PRODUCTION_RESOURCES.length).floor])
expect(planet.instance_variable_get(:@resource)).to eq PLANET_PRODUCTION_RESOURCES[(Random.new(seed).rand * PLANET_PRODUCTION_RESOURCES.length).floor]
end
it 'has a nil owner' do
@@ -31,13 +31,13 @@ RSpec.describe Planet do
describe '#change_owner' do
it 'allows an ownership change when the current owner is nil' do
expect(planet.change_owner(player_1)).to eq(true)
expect(planet.change_owner(player_1)).to eq true
expect(planet.instance_variable_get(:@owner)).to eq player_1
end
it 'does not change when already owned' do
planet.change_owner(player_2)
expect(planet.change_owner(player_1)).to eq(false)
expect(planet.change_owner(player_1)).to eq false
expect(planet.instance_variable_get(:@owner)).to eq player_2
end
end
+7 -7
View File
@@ -10,8 +10,8 @@ RSpec.describe Position do
context 'with two arguments' do
it 'stores the coordinates when the sum is even' do
pos = Position.new(*even_pair)
expect(pos.x_pos).to eq(even_pair[0])
expect(pos.y_pos).to eq(even_pair[1])
expect(pos.x_pos).to eq even_pair[0]
expect(pos.y_pos).to eq even_pair[1]
end
it 'raises ArgumentError when the sum is odd' do
@@ -43,30 +43,30 @@ RSpec.describe Position do
describe '#two_d_cartesian' do
it 'returns the original (x, y) pair' do
pos = Position.new(*even_pair)
expect(pos.two_d_cartesian).to eq(even_pair)
expect(pos.two_d_cartesian).to eq even_pair
end
end
describe '#two_d_hexagonal' do
it 'returns an array of nil values for a, b, c' do
pos = Position.new(*even_pair)
expect(pos.two_d_hexagonal).to eq([nil, nil, nil])
expect(pos.two_d_hexagonal).to eq [nil, nil, nil]
end
end
describe '#to_s' do
it 'puts out the coordinates' do
expect(Position.new(*even_pair).to_s).to eq('(4, 6)')
expect(Position.new(*even_pair).to_s).to eq '(4, 6)'
end
end
describe '#==' do
it 'returns false when the positions differ' do
expect(Position.new(*even_pair) == Position.new(6, 8)).to eq(false)
expect(Position.new(*even_pair) == Position.new(6, 8)).to eq false
end
it 'returns true when the positions are the same' do
expect(Position.new(*even_pair) == Position.new(4, 6)).to eq(true)
expect(Position.new(*even_pair) == Position.new(4, 6)).to eq true
end
end
end
+7 -5
View File
@@ -1,17 +1,19 @@
# frozen_string_literal: true
require_relative '../ship' # <-- adjust to the actual path of ship.rb
require './ship'
require './player'
RSpec.describe Ship do
let(:ship) { Ship.new(0, 0) }
let(:ship) { Ship.new(0, 0, Player.new('test player 01')) }
describe '#initialize' do
it 'stores the given position' do
expect(ship.instance_variable_get(:@position)).to eq([0, 0])
expect(ship.instance_variable_get(:@position)).to eq [0, 0]
end
it 'sets the speed to 0.1' do
expect(ship.instance_variable_get(:@speed)).to eq(0.1)
expect(ship.instance_variable_get(:@speed)).to eq 0.1
end
it 'does not set @moving until a direction is chosen' do
@@ -70,7 +72,7 @@ RSpec.describe Ship do
}
mapping.each do |dir, expected|
expect { ship.move_direction(dir) }.not_to raise_error
expect(ship.instance_variable_get(:@moving)).to eq(expected)
expect(ship.instance_variable_get(:@moving)).to eq expected
end
end
+1 -3
View File
@@ -52,7 +52,6 @@ RSpec.configure do |config|
# The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content.
=begin
# This allows you to limit a spec run to individual examples or groups
# you care about by tagging them with `:focus` metadata. When nothing
# is tagged with `:focus`, all examples get run. RSpec also provides
@@ -87,7 +86,7 @@ RSpec.configure do |config|
# Print the 10 slowest examples and example groups at the
# end of the spec run, to help surface which specs are running
# particularly slow.
config.profile_examples = 10
# config.profile_examples = 10
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
@@ -100,5 +99,4 @@ RSpec.configure do |config|
# test failures related to randomization by passing the same `--seed` value
# as the one that triggered the failure.
Kernel.srand config.seed
=end
end
+7
View File
@@ -18,6 +18,13 @@ RSpec.describe UniverseArray do
uni_arr[0][0] = 'hi'
expect(uni_arr[Position.new(0, 0)]).to eq 'hi'
end
it 'returns nil when access outside universe' do
uni_arr = UniverseArray.new()
uni_arr[3] = []
expect(uni_arr[Position.new(3, 51)]).to eq nil
expect(uni_arr[Position.new(0, 0)]).to eq nil
end
end
describe '#[]=' do
+20 -16
View File
@@ -24,15 +24,15 @@ RSpec.describe Universe do
describe '#initialize' do
it 'stores all expected instance variables' do
expect(universe.name).to eq(name)
expect(universe.instance_variable_get(:@universe_size)).to eq(universe_size)
expect(universe.instance_variable_get(:@seed)).to eq(seed)
expect(universe.name).to eq name
expect(universe.instance_variable_get(:@universe_size)).to eq universe_size
expect(universe.instance_variable_get(:@seed)).to eq seed
end
it 'creates a deterministic Random object when a seed is given' do
rng = universe.instance_variable_get(:@random)
expect(rng).to be_a(Random)
expect(rng.rand(100)).to eq(Random.new(seed).rand(100))
expect(rng.rand(100)).to eq Random.new(seed).rand(100)
end
it 'initializes the random if no seed is passed in' do
@@ -50,12 +50,12 @@ RSpec.describe Universe do
it 'is symmetric' do
a = Position.new(0, 0)
b = Position.new(4, 2)
expect(universe.distance(a, b)).to eq(universe.distance(b, a))
expect(universe.distance(a, b)).to eq universe.distance(b, a)
end
it 'returns 0 when both points are identical' do
p = Position.new(1, 1)
expect(universe.distance(p, p)).to eq(0)
expect(universe.distance(p, p)).to eq 0
end
it 'correctly computes known hex distances' do
@@ -64,13 +64,13 @@ RSpec.describe Universe do
p2 = Position.new(4, 2)
p3 = Position.new(2, 2)
# (0,0) to (2,0) → 1
expect(universe.distance(p0, p1)).to eq(1)
expect(universe.distance(p0, p1)).to eq 1
# (0,0) to (4,2) → 3
expect(universe.distance(p0, p2)).to eq(3)
expect(universe.distance(p0, p2)).to eq 3
# (0,0) to (2,2) → 2
expect(universe.distance(p0, p3)).to eq(2)
expect(universe.distance(p0, p3)).to eq 2
end
end
end # describe '#distance'
describe '#map generation' do
it 'creates the expected dimensions' do
@@ -80,7 +80,7 @@ RSpec.describe Universe do
# (our stub) and every other entry is nil.
expect(map).to be_a(UniverseArray)
# Check how may nodes were created:
expect(map.flatten.compact.length).to eq(19) # 1 + 1*6 + 2*6
expect(map.flatten.compact.length).to eq 19 # 1 + 1*6 + 2*6
end
it 'contains a planet at every valid point when create_chances is 1' do
@@ -89,12 +89,16 @@ RSpec.describe Universe do
map.each do |row|
row.each do |idx|
# The indexes are allowed to be nil
if !idx.nil?
expect(idx).to be_a(Planet)
if idx.nil?
next # Is allowed to be nil
end
if idx.is_a? Star
next # Is allowed to be star
end
expect(idx).to be_a(Planet)
end
end
end
end # describe '#map generation'
it 'is deterministic when the same seed is used' do
first_universe = Universe.new(
@@ -113,7 +117,7 @@ RSpec.describe Universe do
)
second_map = second_universe.instance_variable_get(:@universe_map)
expect(first_map).to eq(second_map)
expect(first_map).to eq second_map
end
end
@@ -140,7 +144,7 @@ RSpec.describe Universe do
describe '#planets' do
it 'lists all of the generated planets' do
universe.create_universe
expect(universe.planets.length).to eq(19)
expect(universe.planets.length).to eq 18
end
end
end