require "spec_helper" describe RTanque::Heading do NINETY = Math::PI / 2.0 describe '#delta' do before do @instance = described_class.new(0) end it 'receives floats' do other = 0.0 expect(@instance.delta(other)).to eql 0.0 end it 'receives headings' do other = described_class.new(0.0) expect(@instance.delta(other)).to eql 0.0 end it 'gives 0 when provided same a == b' do expect(@instance.delta(@instance)).to eq 0 end it 'outputs positive when a < b' do expect(@instance.delta(@instance + 1)).to be > 0 end it 'outputs negative when b < a' do expect(@instance.delta(@instance - 1)).to be < 0 end it 'correct output when difference < 180 deg' do expect(@instance.delta(NINETY)).to eq NINETY end it 'correct output when difference > 180 deg' do expect(@instance.delta(NINETY * 3)).to eq -NINETY end it 'correctly handles degress > 360' do expect(@instance.delta(NINETY * 5)).to eq NINETY end it 'correctly handles differences > 180 in which a < b' do expect(@instance.delta(NINETY * 3)).to eq -NINETY end it 'correctly handles differences > 180 in which a > b' do expect(@instance.delta(-(NINETY * 3))).to eq NINETY end it 'correctly handles when a and b are on both sides of 180' do @instance = described_class.new(RTanque::Heading::S - RTanque::Heading::ONE_DEGREE) delta = (@instance.delta(RTanque::Heading::S + RTanque::Heading::ONE_DEGREE)).round(5) expected = (RTanque::Heading::ONE_DEGREE * 2).round(5) expect(delta).to eq(expected) end end describe '.new_from_degrees' do it 'receives positive degrees' do expect(described_class.new_from_degrees(90).to_f).to eql NINETY end it 'receives degrees large than 360' do expect(described_class.new_from_degrees(90 + 360).to_f).to eql NINETY end it 'receives negative degrees' do expect(described_class.new_from_degrees(-90).to_f).to eql NINETY * 3 end it 'receives negative degrees less than -360' do expect(described_class.new_from_degrees(-90 - 360).to_f).to eql NINETY * 3 end end describe '.delta_between_points' do let(:from_point) { RTanque::Point.new(10, 10, @arena) } let(:from_heading) { described_class.new(0) } it 'is correct when 0 delta' do to_point = RTanque::Point.new(10, 20, @arena) expect(described_class.delta_between_points(from_point, from_heading, to_point)).to eq 0 end it 'is correct when delta is negative' do to_point = RTanque::Point.new(9, 11) expect(described_class.delta_between_points(from_point, from_heading, to_point)).to eq -(NINETY / 2) end it 'is correct when delta is positive' do to_point = RTanque::Point.new(11, 11) expect(described_class.delta_between_points(from_point, from_heading, to_point)).to eq(NINETY / 2) end it 'is correct when delta is max' do to_point = RTanque::Point.new(10, 9) expect(described_class.delta_between_points(from_point, from_heading, to_point)).to eq(NINETY * 2) end end describe '#initialize' do it 'receives inits and sets radians to float' do expect(described_class.new(0).radians).to eql 0.0 end it 'receives negative floats' do expect(described_class.new(-NINETY).radians).to eql NINETY * 3 end it 'creates frozen object' do expect(described_class.new(0).frozen?).to be_truthy end end describe '#clone' do it 'returns a Heading' do expect(described_class.new.clone).to be_instance_of described_class end it 'returns a new object' do original = described_class.new copy = original.clone expect(original.object_id).not_to eq copy.object_id end it 'returns a new object which does not affect old' do original = described_class.new(0.0) copy = original.clone expect(copy).not_to equal original end end describe '#==' do it 'works like Numeric, ignoring type' do a = described_class.new(1.0) expect(a == 1).to be_truthy end it 'correctly compares two equal headings' do a = described_class.new(1.0) b = described_class.new(1.0) expect(a == b).to be_truthy end it 'correctly compares two different headings' do a = described_class.new(0) b = described_class.new(1.0) expect(a == b).to be_falsey end it 'compares to a numeric on LHS' do a = described_class.new(Math::PI) expect(Math::PI == a).to be_truthy end end describe '#eql?' do it 'compares types like Numeric, comparing type' do a = described_class.new(1.0) expect(a.eql?(1)).to be_falsey end it 'correctly compares two equal headings' do a = described_class.new(1.0) b = described_class.new(1.0) expect(a.eql?(b)).to be_truthy end it 'correctly compares two different headings' do a = described_class.new(0) b = described_class.new(1.0) expect(a.eql?(b)).to be_falsey end end describe '#<=>' do it 'receives headings' do a = described_class.new b = described_class.new(NINETY) expect(a <=> b).to eq -1 end it 'receives floats' do a = described_class.new expect(a <=> NINETY).to eq -1 end end describe '#+' do it 'returns new instance' do a = described_class.new(0.0) result = a + NINETY expect(result).not_to eql a expect(result).not_to equal a expect(result).to be_kind_of described_class end it 'leaves receiver unchanged' do a = described_class.new(1.0) a + NINETY expect(a).to eql described_class.new(1.0) end it 'correctly adds' do a = described_class.new(0.0) + NINETY expect(a).to eq NINETY end it 'correctly adds negative numbers' do a = described_class.new(0.0) + -NINETY expect(a).to eq(NINETY * 3) end it 'correctly adds other headings' do a = described_class.new(NINETY * 2) b = described_class.new(NINETY) expect(a + b).to eq(NINETY * 3) end it 'respects radian module ring' do a = described_class.new(NINETY * 3) b = described_class.new(NINETY * 3) expect(a + b).to eq NINETY * 2 end end describe '#*' do it 'returns new instance' do a = described_class.new(NINETY) result = a * NINETY expect(result).not_to eql a expect(result).not_to equal a expect(result).to be_kind_of described_class end it 'correctly multiplies' do a = described_class.new(NINETY) expect(a * 2.0).to eq NINETY * 2.0 end end describe '#/' do it 'returns new instance' do a = described_class.new(NINETY) result = a / NINETY expect(result).not_to eql a expect(result).not_to equal a expect(result).to be_kind_of described_class end it 'correctly divides' do a = described_class.new(NINETY * 2.0) expect(a / 2.0).to eq NINETY end end describe '#-@' do it 'creates a new instance' do a = described_class.new(1.0) b = -a expect(b).not_to equal a end it 'correctly negates itself' do expect(-described_class.new(NINETY)).to eq(NINETY * 3) end end describe '#to_degrees' do it 'returns float' do a = described_class.new expect(a.to_degrees).to eq 0.0 b = described_class.new(NINETY) expect(b.to_degrees).to eq 90.0 end end end