# Nathan Hinton Jan 8 2026 # Test file for the buildings in the game require 'game/building' RSpec.describe Building do let(:player) {instance_double( 'Player', ship_build_power: 0, research_tech_build_power: 0, military_tech_build_power: 0, player_resources: { 'metal' => 20_000, 'crystals' => 20_000, 'fuel' => 20_000, 'credits' => 20_000}, all_buildings: [], all_tech: [] )} let(:planet) {instance_double( 'Planet', owner: player )} let(:anti_gravity_thrusters_1) {instance_double('Tech', name: 'Anti Gravity Thrusters 1' )} let(:anti_gravity_thrusters_2) {instance_double('Tech', name: 'Anti Gravity Thrusters 2' )} before(:all) do end describe '#initialize & #validate_building' do it 'Can construct any of level one mining buildings' do expect{Building.new(player, planet, 'Metal Mines 1')}.to_not raise_error end it 'Can construct basic factory buildings' do expect{Building.new(player, planet, 'Shipyard Level 1')}.to_not raise_error end it 'Can construct second level factory buildings' do allow(player).to receive(:all_buildings).and_return([Building.new(player, planet, 'Shipyard Level 1')]) expect{Building.new(player, planet, 'Shipyard Level 2')}.to_not raise_error end it 'Can construct third level (dependency check) buildings' do allow(player).to receive(:all_tech).and_return([anti_gravity_thrusters_1, anti_gravity_thrusters_2]) # Required tech for buildings allow(player).to receive(:all_buildings).and_return([Building.new(player, planet, 'Shipyard Level 1')]) # Building the second level requires the first first :) allow(player).to receive(:all_buildings).and_return([Building.new(player, planet, 'Shipyard Level 2'), Building.new(player, planet, 'Space Construction Station Level 1')]) expect{Building.new(player, planet, 'Space Construction Station Level 2')}.to_not raise_error end it 'Raises an error when trying to build a building that does not have the required buildings' do expect{Building.new(player, planet, 'Shipyard Level 2')}.to raise_error(BuildingError, 'Requires `Shipyard Level 1` first') end it 'Raises an error when trying to build a building that does not have the required tech' do allow(player).to receive(:all_buildings).and_return([Building.new(player, planet, 'Shipyard Level 1')]) # Building the second level requires the first first :) expect{Building.new(player, planet, 'Space Construction Station Level 1')}.to raise_error(BuildingError, 'Requires the tech of `Anti Gravity Thrusters 1` first') end it 'Raises an error when the player does not own the planet' do allow(planet).to receive(:owner).and_return(nil) expect{Building.new(player, planet, 'Shipyard Level 1')}.to raise_error(BuildingError, 'Player does not own planet!') end it 'Raises an error if the player does not have the required credits' do allow(player).to receive(:player_resources).and_return( { 'metal' => 20_000, 'crystals' => 20_000, 'fuel' => 20_000, 'credits' => 0} ) expect{Building.new(player, planet, 'Shipyard Level 1')}.to raise_error(BuildingError, 'Player does not have enough credits!') end it 'Raises an error if the player does not have enough metal' do allow(player).to receive(:player_resources).and_return( { 'metal' => 0, 'crystals' => 20_000, 'fuel' => 20_000, 'credits' => 20_000} ) expect{Building.new(player, planet, 'Shipyard Level 1')}.to raise_error(BuildingError, 'Player does not have enough metal!') end it 'Raises an error if the player does not have enough fuel' do allow(player).to receive(:player_resources).and_return( { 'metal' => 20_000, 'crystals' => 20_000, 'fuel' => 0, 'credits' => 20_000} ) expect{Building.new(player, planet, 'Shipyard Level 1')}.to raise_error(BuildingError, 'Player does not have enough fuel!') end it 'Raises an error if the player does not have enough crystals' do allow(player).to receive(:player_resources).and_return( { 'metal' => 20_000, 'crystals' => 0, 'fuel' => 20_000, 'credits' => 20_000} ) expect{Building.new(player, planet, 'Shipyard Level 1')}.to raise_error(BuildingError, 'Player does not have enough crystals!') end it 'Raises an error if the building does not exist' do expect{Building.new(player, planet, 'billy bob joe')}.to raise_error(BuildingError, 'Invalid building name `billy bob joe`') end end describe '#update/#produce_resources' do before(:each) do allow(player).to receive(:ship_build_power=) allow(player).to receive(:research_tech_build_power=) allow(player).to receive(:military_tech_build_power=) end describe 'Harvesting building produces resources' do it 'Metal Mines' do building = Building.new(player, planet, 'Metal Mines 1') # Ensure the building is built: building.instance_variable_set(:@building_exist_time, 10000) building.update(1.0) expect(player.player_resources).to eq( { 'metal' => 19_500, 'crystals' => 19_140, 'fuel' => 19_000, 'credits' => 18_960 }) end it 'Crystal Collector' do building = Building.new(player, planet, 'Crystal Collector 1') # Ensure the building is built: building.instance_variable_set(:@building_exist_time, 10000) building.update(1.0) expect(player.player_resources).to eq( { 'crystals' => 19_500, 'fuel' => 19_140, 'credits' => 19_000, 'metal' => 18_960 }) end it 'Fuel Refinery' do building = Building.new(player, planet, 'Fuel Refinery 1') # Ensure the building is built: building.instance_variable_set(:@building_exist_time, 10000) building.update(1.0) expect(player.player_resources).to eq( { 'fuel' => 19_500, 'credits' => 19_140, 'metal' => 19_000, 'crystals' => 18_960 }) end it 'Credit Center' do building = Building.new(player, planet, 'Credit Center 1') # Ensure the building is built: building.instance_variable_set(:@building_exist_time, 10000) building.update(1.0) expect(player.player_resources).to eq( { 'credits' => 19_500, 'metal' => 19_140, 'crystals' => 19_000, 'fuel' => 18_960 }) end end it 'Does not produce when there are not enough resources for upkeep' do start_resources = { 'metal' => 1_010, 'crystals' => 1_020, 'fuel' => 1_030, 'credits' => 1_040} allow(player).to receive(:player_resources).and_return(start_resources) building = Building.new(player, planet, 'Credit Center 1') building.instance_variable_set(:@building_exist_time, 10000) expect{building.update(1.0)}.to raise_error(BuildingWarning, 'Player does not have enough metal to produce from Credit Center 1!') expect(player.player_resources).to eq(start_resources) end it 'does not produce when it is not yet finished constructing' do building = Building.new(player, planet, 'Metal Mines 1') building.update(1.0) expect(player.player_resources).to eq( { 'metal' => 19_000, 'crystals' => 19_000, 'fuel' => 19_000, 'credits' => 19_000 }) end it 'Having shipyard buildings allows the production of ships' do building = Building.new(player, planet, 'Shipyard Level 1') building.instance_variable_set(:@building_exist_time, 10000) building.update(1.0) expect(player).to have_received(:ship_build_power=).with(100) end it 'Having research tech buildings allows the production of tech' do building = Building.new(player, planet, 'Research Factory Level 1') building.instance_variable_set(:@building_exist_time, 10000) building.update(1.0) expect(player).to have_received(:research_tech_build_power=).with(100) end it 'Having military tech buildings allows the production of military tech' do allow(player).to receive(:all_buildings).and_return([Building.new(player, planet, 'Research Factory Level 1')]) building = Building.new(player, planet, 'Military Factory Level 1') building.instance_variable_set(:@building_exist_time, 10000) building.update(1.0) expect(player).to have_received(:military_tech_build_power=).with(100) end it 'Is in production for the right amount of time' do building = Building.new(player, planet, 'Metal Mines 1') building.update(1000.0) expect(player.player_resources).to eq( { 'metal' => 19_000, 'crystals' => 19_000, 'fuel' => 19_000, 'credits' => 19_000 }) building.update(1.0) expect(player.player_resources).to eq( { 'metal' => 19_500, 'crystals' => 19_140, 'fuel' => 19_000, 'credits' => 18_960 }) end end end