Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable equivalence and hash equality to Observer #57

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions lib/astronoby/observer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Observer
MOLAR_MASS_OF_AIR = 0.0289644
UNIVERSAL_GAS_CONSTANT = 8.31432

attr_reader :latitude, :longitude, :elevation, :temperature
attr_reader :latitude, :longitude, :elevation, :temperature, :pressure

# @param latitude [Angle] geographic latitude of the observer
# @param longitude [Angle] geographic longitude of the observer
Expand All @@ -31,19 +31,38 @@ def initialize(
@longitude = longitude
@elevation = elevation
@temperature = temperature
@pressure = pressure
@pressure = pressure || compute_pressure
end

# Compute an estimation of the atmospheric pressure based on the elevation
# and temperature
#
# @return [Float] the atmospheric pressure in millibars.
def pressure
@pressure ||= PRESSURE_AT_SEA_LEVEL * pressure_ratio
def ==(other)
return false unless other.is_a?(self.class)

@latitude == other.latitude &&
@longitude == other.longitude &&
@elevation == other.elevation &&
@temperature == other.temperature &&
@pressure == other.pressure
end
alias_method :eql?, :==

def hash
[
self.class,
@latitude,
@longitude,
@elevation,
@temperature,
@pressure
].hash
end

private

# @return [Float] the atmospheric pressure in millibars.
def compute_pressure
@pressure ||= PRESSURE_AT_SEA_LEVEL * pressure_ratio
end

# Source:
# Barometric formula
# https://en.wikipedia.org/wiki/Barometric_formula
Expand Down
84 changes: 84 additions & 0 deletions spec/astronoby/observer_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,90 @@
# frozen_string_literal: true

require "set" # rubocop:disable Lint/RedundantRequireStatement

RSpec.describe Astronoby::Observer do
describe "equivalence (#==)" do
it "returns true when the observers are equivalent" do
observer1 = described_class.new(
latitude: Astronoby::Angle.from_degrees(45),
longitude: Astronoby::Angle.from_degrees(90),
elevation: 100,
temperature: 280,
pressure: 10
)
observer2 = described_class.new(
latitude: Astronoby::Angle.from_degrees(45),
longitude: Astronoby::Angle.from_degrees(90),
elevation: 100,
temperature: 280,
pressure: 10
)

expect(observer1).to eq observer2
end

it "returns true when the observers are not equivalent" do
observer1 = described_class.new(
latitude: Astronoby::Angle.from_degrees(45),
longitude: Astronoby::Angle.from_degrees(90),
elevation: 100,
temperature: 280,
pressure: 10
)
observer2 = described_class.new(
latitude: Astronoby::Angle.from_degrees(45),
longitude: Astronoby::Angle.from_degrees(90),
elevation: 100,
temperature: 280,
pressure: 15
)

expect(observer1).not_to eq observer2
end
end

describe "hash equality" do
it "makes an angle foundable as a Hash key" do
observer1 = described_class.new(
latitude: Astronoby::Angle.from_degrees(45),
longitude: Astronoby::Angle.from_degrees(90),
elevation: 100,
temperature: 280,
pressure: 10
)
observer2 = described_class.new(
latitude: Astronoby::Angle.from_degrees(45),
longitude: Astronoby::Angle.from_degrees(90),
elevation: 100,
temperature: 280,
pressure: 10
)
map = {observer1 => :observer}

expect(map[observer2]).to eq :observer
end

it "makes an angle foundable in a Set" do
observer1 = described_class.new(
latitude: Astronoby::Angle.from_degrees(45),
longitude: Astronoby::Angle.from_degrees(90),
elevation: 100,
temperature: 280,
pressure: 10
)
observer2 = described_class.new(
latitude: Astronoby::Angle.from_degrees(45),
longitude: Astronoby::Angle.from_degrees(90),
elevation: 100,
temperature: 280,
pressure: 10
)
set = Set.new([observer1])

expect(set.include?(observer2)).to be true
end
end

describe "#pressure" do
it "returns the computed pression in millibars" do
latitude = Astronoby::Angle.from_degrees(0)
Expand Down