Skip to content

Commit

Permalink
Merge pull request #50 from shivam091/5.3.0
Browse files Browse the repository at this point in the history
5.3.0
  • Loading branch information
shivam091 authored Oct 22, 2023
2 parents 6fcf04b + b18ed47 commit f711cf4
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 15 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## [5.3.0](https://github.com/shivam091/unit_measurements/compare/v5.2.0...v5.3.0) - 2023-10-24

### What's new

- Added ability set globally configurable options for **`unit_measurements`**.

### What's improved

- Code coverage improvements.

----------

## [5.2.0](https://github.com/shivam091/unit_measurements/compare/v5.1.1...v5.2.0) - 2023-10-22

### 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.2.0)
unit_measurements (5.3.0)
activesupport (~> 7.0)

GEM
Expand Down
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ The `unit_measurements` gem is designed to simplify the handling of units for sc

## Features

1. Provides easy conversion between units.
2. Lightweight and easily extensible to include other units and conversions.
3. Built in support for various [unit groups](https://github.com/shivam091/unit_measurements/blob/main/units.md).
1. Simplifies the conversion of measurements between compatible units.
2. Easily add new units and conversions to suit specific needs.
3. Built-in support for various [unit groups](https://github.com/shivam091/unit_measurements/blob/main/units.md).
4. Ability to parse strings representing complex, fractional, mixed fractional, scientific numbers, and ratios.
5. Well organized and descriptive documentation published [here](https://shivam091.github.io/unit_measurements).
6. Supports caching of conversion factors between different units of the unit group.
5. Well-organized and descriptive [documentation](https://shivam091.github.io/unit_measurements).
6. Ability to cache conversion factors for improved performance.
7. Fine-tune behavior using configurable options.

## Disclaimer

Expand Down Expand Up @@ -57,6 +58,23 @@ Or otherwise simply install it yourself as:

`$ gem install unit_measurements`

## Configuration

`unit_measurements` is designed to work out of the box, but you can customize its behavior by placing
the configuration block in an initializer file before requiring the library files:

```ruby
UnitMeasurements.configure do |config|
config.use_cache = false
end
```

The current available configurable options are:

| Option | Default value | Description |
| ------ | ------------- | ----------- |
| **use_cache** | false | Set to `true` to enable caching during conversions. |

## Usage

The **`UnitMeasurements::Measurement`** class is responsible for conversion of quantity to various compatible units
Expand Down
59 changes: 55 additions & 4 deletions lib/unit_measurements/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@

module UnitMeasurements
class << self
# Allows setting an instance of +Configuration+ containing values of desired
# configurable options.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.3.0
attr_writer :configuration

# Creates a new unit group based on the provided +block+ of instructions.
#
# The +build+ method allows you to define and create a custom unit group with
Expand Down Expand Up @@ -40,10 +47,6 @@ class << self
# cache "length.json"
# end
#
# @param block
# A block of instructions for defining units and their conversions within
# the unit group.
#
# @yield [builder]
# A block that defines the units to be added to the unit group.
# The block takes a {UnitGroupBuilder} instance as a parameter.
Expand Down Expand Up @@ -76,10 +79,58 @@ class << self
@unit_group = builder.build
end
end

# Returns an instance of +Configuration+ with the values of desired configurable
# options of +*unit_measurements*+. If instance is not present, it initializes
# a new instance of {Configuration}.
#
# @return [Configuration] An instance of +Configuration+.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.3.0
def configuration
@configuration ||= Configuration.new
end

# Reset the configuration to its default state.
#
# @example
# UnitMeasurements.reset
#
# @return [Configuration] A new +Configuration+ object.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.3.0
def reset
@configuration = Configuration.new
end

# Configures options of the +*UnitMeasurements*+ module using a block. It
# yields the current +Configuration+ instance for updating default values of
# options by new values specified within a block.
#
# @example
# UnitMeasurements.configure do |config|
# config.use_cache = false
# end
#
# @yield [configuration] The current +Configuration+ instance.
#
# @yieldparam [Configuration] configuration
# An instance of +Configuration+ with the new values of options.
#
# @yieldreturn [Configuration] The updated +Configuration+ instance.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.3.0
def configure
yield configuration
end
end
end

# The following requires load various components of the unit measurements library.
require "unit_measurements/configuration"
require "unit_measurements/cache"
require "unit_measurements/unit_group_builder"
require "unit_measurements/unit"
Expand Down
64 changes: 64 additions & 0 deletions lib/unit_measurements/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# -*- encoding: utf-8 -*-
# -*- frozen_stringing_literal: true -*-
# -*- warn_indent: true -*-

module UnitMeasurements
# The +UnitMeasurements::Configuration+ class maintains and manages the globally
# configurable options of +*unit_measurements*+.
#
# @note
# This class is responsible for configuring globally configurable options of
# +*unit_measurements*+.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.3.0
class Configuration
# Get the current value of the +use_cache+ option.
#
# @note
# This option controls whether caching is enabled for converting measurements.
# Defaults to +false+.
#
# @return [TrueClass|FalseClass]
# Returns +true+ if caching is enabled, otherwise +false+.
#
# @see Cache
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.3.0
attr_reader :use_cache

# Initializes a new +Configuration+ instance with default values of configurable
# options.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.3.0
def initialize
self.use_cache = false
end

# Sets a value for the +use_cache+ option.
#
# It controls whether caching is enabled for converting measurements. When
# caching is enabled, previously computed conversion factors are stored for
# future use, improving conversion performance.
#
# @param [TrueClass|FalseClass] use_cache
# +true+ if caching should be used while converting the measurement otherwise
# +false+.
#
# @return [TrueClass|FalseClass] The updated value of +use_cache+.
#
# @raise [BaseError] if +use_cache+ is not a boolean value.
#
# @see Cache
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.3.0
def use_cache=(use_cache)
unless [true, false].include?(use_cache)
raise BaseError, "Configuration#use_cache= only accepts true or false, but received #{use_cache}"
end

@use_cache = use_cache
end
end
end
2 changes: 2 additions & 0 deletions lib/unit_measurements/measurement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,8 @@ def unit_from_unit_or_name!(value)
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.2.0
def calculate_conversion_factor(target_unit, use_cache)
use_cache = (UnitMeasurements.configuration.use_cache || use_cache)

if use_cache && (cached_factor = self.class.cached.get(unit.name, target_unit.name))
cached_factor
else
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.2.0"
VERSION = "5.3.0"
end
37 changes: 37 additions & 0 deletions spec/unit_measurements/configuration_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# -*- encoding: utf-8 -*-
# -*- frozen_string_literal: true -*-
# -*- warn_indent: true -*-

# spec/unit_measurements/configuration_spec.rb

RSpec.describe UnitMeasurements::Configuration do
describe "#initialize" do
it "sets default values of configurable options" do
config = described_class.new

expect(config.use_cache).to be_falsey
end
end

describe "#use_cache=" do
it "sets use_cache to true" do
config = described_class.new
config.use_cache = true

expect(config.use_cache).to be_truthy
end

it "sets use_cache to false" do
config = described_class.new
config.use_cache = false

expect(config.use_cache).to be_falsey
end

it "raises BaseError for invalid input" do
config = described_class.new

expect { config.use_cache = "invalid" }.to raise_error(UnitMeasurements::BaseError, /only accepts true or false/)
end
end
end
4 changes: 2 additions & 2 deletions spec/unit_measurements/measurement_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@
expect(converted_length.unit).to eq(m)
end

it 'fetches conversion factor from cache when use_cache is true' do
it "fetches conversion factor from cache when use_cache is true" do
cache.clear_cache
cache.set("m", "cm", 0.00001)

converted_length = base_length.convert_to('cm', use_cache: true)
converted_length = base_length.convert_to("cm", use_cache: true)

expect(converted_length.quantity).to eq(1e-5)
end
Expand Down
63 changes: 61 additions & 2 deletions spec/unit_measurements_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,66 @@
# -*- warn_indent: true -*-

RSpec.describe UnitMeasurements do
it "has a valid version number" do
expect(UnitMeasurements::VERSION).to eq("5.2.0")
describe ".build" do
it "creates a new unit group based on provided block" do
unit_group = UnitMeasurements.build do
primitive "m"

system :metric do
si_unit "m", aliases: ["meter", "metre", "meters", "metres"]
end

system :imperial do
unit "in", value: "25.4 mm", aliases: ['"', "inch", "inches"]
end

cache "length.json"
end

expect(unit_group).to be_a(Class)
expect(unit_group.unit_group).to be_a(UnitMeasurements::UnitGroup)
end

it "returns a subclass of Measurement with defined units and conversions" do
unit_group = UnitMeasurements.build do
primitive "m"

system :metric do
si_unit "m", aliases: ["meter", "metre", "meters", "metres"]
end

system :imperial do
unit "in", value: "25.4 mm", aliases: ['"', "inch", "inches"]
end

cache "length.json"
end

expect(unit_group.ancestors).to include(UnitMeasurements::Measurement)
expect(unit_group.unit_group.units.length).to eq(26)
end
end

describe ".configuration" do
it "returns a Configuration instance" do
expect(described_class.configuration).to be_an_instance_of(UnitMeasurements::Configuration)
end
end

describe ".configure" do
it "yields the configuration block" do
expect { |block| described_class.configure(&block) }.to yield_with_args(described_class.configuration)
end
end

describe ".reset" do
it "resets the configuration to a new instance of Configuration" do
custom_config = double("Custom Configuration")
described_class.configuration = custom_config
described_class.reset

expect(described_class.configuration).not_to eq(custom_config)
expect(described_class.configuration).to be_an_instance_of(UnitMeasurements::Configuration)
end
end
end

0 comments on commit f711cf4

Please sign in to comment.