Skip to content

Commit

Permalink
Merge pull request #66 from shivam091/5.13.0
Browse files Browse the repository at this point in the history
5.13.0
  • Loading branch information
shivam091 authored Nov 26, 2023
2 parents 6b52fb1 + 051e1d6 commit d52fd2f
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 49 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## [5.13.0](https://github.com/shivam091/unit_measurements/compare/v5.12.0...v5.13.0) - 2023-11-27

### What's new

- Added `Measurement#to_primitive` to convert the measurement to the primitive unit.
- Added `#cbrt` method to calculate cube root of the measurement quantity.
- Added `#sqrt` method to calculate square root of the measurement quantity.
- Aliased `#to_primitive` method as `#in_primitive` and `#as_primitive`.

----------

## [5.12.0](https://github.com/shivam091/unit_measurements/compare/v5.11.1...v5.12.0) - 2023-11-25

### What's new
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
unit_measurements (5.12.0)
unit_measurements (5.13.0)
activesupport (~> 7.0)

GEM
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,12 @@ UnitMeasurements::Length.new(1, "km").convert_to!("m")
You can convert the measurement directly to the `primitive` unit of the unit group as:

```ruby
UnitMeasurements::Length.new(1, "cm").convert_to("primitive")
UnitMeasurements::Length.new(1, "cm").to_primitive
#=> 0.01 m
```

Note: `#to_primitive` method is aliased as `#in_primitive` and `#as_primitive`.

**Parse string without having to split out the quantity and source unit:**

This method provides `use_cache` parameter which defaults to `false` to indicate whether the caching of conversion factors should happen.
Expand Down Expand Up @@ -444,7 +446,7 @@ unit group using the `primitive` method. You can specify cache file name in unit

```ruby
UnitMeasurements::MyUnitGroup = UnitMeasurements.build do
# Set primitive unit for the unit group (optional).
# Set primitive unit for the unit group.
primitive "s"

# Group units by the unit system (optional).
Expand Down
29 changes: 29 additions & 0 deletions lib/unit_measurements/math.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,34 @@ def floor(ndigits = 0)
def ceil(ndigits = 0)
self.class.new(quantity.ceil(ndigits), unit)
end

# Returns square root of the measurement quantity.
#
# @example
# UnitMeasurements::Length.new(9, "m").sqrt
# => 3.0 m
#
# @return [Measurement] A new +Measurement+ instance with square root of quantity.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.13.0
def sqrt
self.class.new((quantity ** Rational(1, 2)), unit)
end

# Returns cube root of the measurement quantity.
#
# @example
# UnitMeasurements::Length.new(27, "m").cbrt
# => 3.0 m
#
# @return [Measurement]
# A new +Measurement+ instance with cube root of quantity.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.13.0
def cbrt
self.class.new((quantity ** Rational(1, 3)), unit)
end
end
end
67 changes: 42 additions & 25 deletions lib/unit_measurements/measurement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,36 +131,22 @@ def initialize(quantity, unit)
# UnitMeasurements::Length.new(1, "m").convert_to("cm")
# => 100.0 cm
#
# UnitMeasurements::Length.new(1, "cm").convert_to("primitive")
# => 0.01 m
#
# UnitMeasurements::Length.new(1, "m").convert_to("cm", use_cache: true)
# => 100.0 cm
# UnitMeasurements::Length.new(1, "m").convert_to("mm", use_cache: true)
# => 1000.0 cm
#
# @param [String|Symbol] target_unit
# The target unit for conversion. Specifing +primitive+ will convert the
# measurement to a primitive unit of the unit group.
# The target unit for conversion.
# @param [TrueClass|FalseClass] use_cache
# Indicates whether to use cached conversion factors.
#
# @return [Measurement]
# A new +Measurement+ instance with the converted +quantity+ and
# +target unit+.
#
# @raise [MissingPrimitiveUnitError]
# if primitive unit is not set for the unit group.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 1.0.0
def convert_to(target_unit, use_cache: false)
target_unit = if target_unit.to_s.eql?("primitive")
primitive_unit = self.class.primitive

raise MissingPrimitiveUnitError if primitive_unit.nil?
primitive_unit
else
unit_from_unit_or_name!(target_unit)
end
target_unit = unit_from_unit_or_name!(target_unit)
return self if target_unit == unit

conversion_factor = calculate_conversion_factor(target_unit, use_cache)
Expand All @@ -177,15 +163,11 @@ def convert_to(target_unit, use_cache: false)
# UnitMeasurements::Length.new(1, "m").convert_to!("cm")
# => 100.0 cm
#
# UnitMeasurements::Length.new(1, "cm").convert_to!("primitive")
# => 0.01 m
#
# UnitMeasurements::Length.new(1, "m").convert_to!("cm", use_cache: true)
# => 100.0 cm
# UnitMeasurements::Length.new(1, "m").convert_to!("mm", use_cache: true)
# => 1000.0 mm
#
# @param [String|Symbol] target_unit
# The target unit for conversion. Specifing +primitive+ will convert the
# measurement to a primitive unit of the unit group.
# The target unit for conversion.
# @param [TrueClass|FalseClass] use_cache
# Indicates whether to use cached conversion factors.
#
Expand All @@ -205,6 +187,41 @@ def convert_to!(target_unit, use_cache: false)
alias_method :in!, :convert_to!
alias_method :as!, :convert_to!

# Converts the measurement to its primitive unit and returns a new instance
# of the +Measurement+.
#
# The method first retrieves the primitive unit of the unit group associated
# with the measurement. If the primitive unit is not set, it raises a
# +MissingPrimitiveUnitError+.
#
# @example
# UnitMeasurements::Length.new(1, "m").to_primitive
# => 1 m
#
# UnitMeasurements::Length.new(1, "cm").to_primitive
# => 0.01 m
#
# @param [TrueClass|FalseClass] use_cache
# Indicates whether to use cached conversion factors.
# @return [Measurement]
# A new +Measurement+ instance representing the measurement in its
# primitive unit.
#
# @raise [MissingPrimitiveUnitError]
# If the primitive unit is not set for the unit group associated with the
# measurement.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.13.0
def to_primitive(use_cache: false)
primitive_unit = self.class.primitive
raise MissingPrimitiveUnitError if primitive_unit.nil?

convert_to(primitive_unit, use_cache: use_cache)
end
alias_method :in_primitive, :to_primitive
alias_method :as_primitive, :to_primitive

# Returns an object representation of the +Measurement+.
#
# @param [TrueClass|FalseClass] dump If +true+, returns the dump representation.
Expand Down
2 changes: 1 addition & 1 deletion lib/unit_measurements/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

module UnitMeasurements
# Current stable version.
VERSION = "5.12.0"
VERSION = "5.13.0"
end
24 changes: 20 additions & 4 deletions spec/unit_measurements/math_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

RSpec.describe UnitMeasurements::Math do
describe "#round" do
let(:measurement) { UnitMeasurements::Length.new(17.625, :m) }
let(:measurement) { UnitMeasurements::Length.new(17.625, "m") }

context "when parameter ndigits is not specified" do
it "rounds quantity to nearest integer" do
Expand All @@ -24,26 +24,42 @@
end

describe "#abs" do
let(:measurement) { UnitMeasurements::Length.new(-17.625, :m) }
let(:measurement) { UnitMeasurements::Length.new(-17.625, "m") }

it "returns absolute value of the quantity." do
expect(measurement.abs.quantity).to eq(17.625)
end
end

describe "#floor" do
let(:measurement) { UnitMeasurements::Length.new(17.625, :cm) }
let(:measurement) { UnitMeasurements::Length.new(17.625, "cm") }

it "rounds quantity to next lower integer" do
expect(measurement.floor.quantity).to eq(17)
end
end

describe "#ceil" do
let(:measurement) { UnitMeasurements::Length.new(17.625, :m) }
let(:measurement) { UnitMeasurements::Length.new(17.625, "m") }

it "rounds quantity to next higher integer" do
expect(measurement.ceil.quantity).to eq(18)
end
end

describe "#sqrt" do
let(:measurement) { UnitMeasurements::Length.new(4, "m") }

it "returns square root of measurement quantity" do
expect(measurement.sqrt.quantity).to eq(2.0)
end
end

describe "#cbrt" do
let(:measurement) { UnitMeasurements::Length.new(27, "m") }

it "returns cube root of measurement quantity" do
expect(measurement.cbrt.quantity).to eq(3.0)
end
end
end
34 changes: 18 additions & 16 deletions spec/unit_measurements/measurement_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,26 @@

expect(converted_length.quantity).to eq(1e-5)
end
end

describe "#convert_to!" do
let(:measurement) { UnitMeasurements::Length.new(300, "cm") }

it "modifies the measurement object" do
expect(measurement.quantity).to eq(300)
expect(measurement.unit).to eq(cm)

measurement.convert_to!("m")

expect(measurement.quantity).to eq(3)
expect(measurement.unit).to eq(m)
end
end

describe "#to_primitive" do
context "when the primitive unit is set to unit group" do
it "converts to a primitive unit" do
converted_length = other_length.convert_to("primitive")
converted_length = other_length.to_primitive

expect(converted_length.quantity).to eq(1)
expect(converted_length.unit).to eq(m)
Expand All @@ -97,26 +113,12 @@
allow(UnitMeasurements::Length).to receive(:primitive).and_return(nil)

expect {
UnitMeasurements::Length.new(1, "m").convert_to("primitive")
UnitMeasurements::Length.new(1, "cm").to_primitive
}.to raise_error(UnitMeasurements::MissingPrimitiveUnitError, "The primitive unit is not set for the unit group.")
end
end
end

describe "#convert_to!" do
let(:measurement) { UnitMeasurements::Length.new(300, "cm") }

it "modifies the measurement object" do
expect(measurement.quantity).to eq(300)
expect(measurement.unit).to eq(cm)

measurement.convert_to!("m")

expect(measurement.quantity).to eq(3)
expect(measurement.unit).to eq(m)
end
end

describe "#inspect" do
it "returns a formatted string representation" do
expect(base_length.inspect).to eq("1 m")
Expand Down

0 comments on commit d52fd2f

Please sign in to comment.