diff --git a/CHANGELOG.md b/CHANGELOG.md index 2901a48..35c5b98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [1.6.0](https://github.com/shivam091/unit_measurements-rails/compare/v1.5.0...v1.6.0) - 2023-12-10 + +### What's new + +- Added tests for `measured_*` methods. + +----------- + ## [1.5.0](https://github.com/shivam091/unit_measurements-rails/compare/v1.4.0...v1.5.0) - 2023-11-27 ### What's new diff --git a/Gemfile.lock b/Gemfile.lock index 222781b..188f4b6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - unit_measurements-rails (1.5.0) + unit_measurements-rails (1.6.0) activemodel (>= 7) activerecord (>= 7) railties (>= 7) diff --git a/README.md b/README.md index 2e9113f..4e892b9 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ A Rails adaptor that encapsulate measurements and their units in Ruby on Rails. ## Introduction This gem is designed as a Rails integration for the [unit_measurements](https://github.com/shivam091/unit_measurements) gem. -It provides an `ActiveRecord` adapter for persisting and retrieving measurements along with their units, simplifying complex +It provides an `ActiveRecord` adapter for persisting and retrieving measurement quantity along with its unit, simplifying complex measurement handling within your Rails applications. ## Minimum Requirements @@ -42,8 +42,8 @@ Or otherwise simply install it yourself as: ### ActiveRecord -This gem provides an ActiveRecord integration allowing you to declare measurement attributes with their -corresponding units in your database schema: +This gem provides an ActiveRecord integration allowing you to declare measurement +attributes along with their corresponding units in your database schema: ```ruby class CreateCubes < ActiveRecord::Migration[7.0] @@ -76,6 +76,9 @@ cube.length_unit #=> "ft" cube.length #=> 5.0 ft ``` +Attribute accessor names are expected to have the `_quantity` and `_unit` suffix, +and be `DECIMAL` and `VARCHAR` types, respectively, and defaults values are accepted. + You can specify multiple measurement attributes simultaneously: ```ruby @@ -84,28 +87,36 @@ class Cube < ActiveRecord::Base end ``` -Attribute names are expected to have the `_quantity` and `_unit` suffix, and be -`DECIMAL` and `VARCHAR` types, respectively, and defaults values are accepted. - -You can customize the model's quantity and unit accessors by specifying them in the -`quantity_attribute_name` and `unit_attribute_name` options, respectively. +You can customize the quantity and unit accessors of the measurement attribute by +specifying them in the `quantity_attribute_name` and `unit_attribute_name` options, +respectively. ```ruby class CubeWithCustomAccessor < ActiveRecord::Base - measured_length :length, unit_attribute_name: :length_uom - measured_length :width, quantity_attribute_name: :width_value + measured UnitMeasurements::Length, :length, :width, :height, unit_attribute_name: :size_uom + measured UnitMeasurements::Weight, :weight, quantity_attribute_name: :width_quantity end ``` For a more streamlined approach, predefined methods are available for commonly used -types like `length`, `weight`, `area`, `volume`, etc.: +types: + +| # | Unit group | Method name | +| :- | :---------- | :----------- | +| 1 | Length or distance | measured_length | +| 2 | Weight or mass | measured_weight | +| 3 | Time or duration | measured_time | +| 4 | Temperature | measured_temperature | +| 5 | Area | measured_area | +| 6 | Volume | measured_volume | +| 7 | Density | measured_density | ```ruby -class Package < ActiveRecord::Base +class CubeWithPredefinedMethods < ActiveRecord::Base measured_length :size - measured_area :carpet_area - measured_volume :total_volume - measured_weight :item_weight, :package_weight + measured_volume :volume + measured_weight :weight + measured_density :density end ``` @@ -121,4 +132,4 @@ Contributions to this project are welcomed! To contribute: ## License -Copyright 2023 [Harshal V. LADHE]((https://shivam091.github.io)), Released under the [MIT License](http://opensource.org/licenses/MIT). +Copyright 2023 [Harshal V. LADHE](https://shivam091.github.io), Released under the [MIT License](http://opensource.org/licenses/MIT). diff --git a/lib/unit_measurements/rails/version.rb b/lib/unit_measurements/rails/version.rb index 92c4357..9e31dc7 100644 --- a/lib/unit_measurements/rails/version.rb +++ b/lib/unit_measurements/rails/version.rb @@ -5,6 +5,6 @@ module UnitMeasurements module Rails # Current stable version. - VERSION = "1.5.0" + VERSION = "1.6.0" end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 79e3e82..8641a36 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -38,3 +38,6 @@ # Establish connection to the database and dump database. ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:" require_relative "support/schema.rb" + +# Load shared examples +require_relative "support/shared_examples" diff --git a/spec/support/models/container.rb b/spec/support/models/container.rb deleted file mode 100644 index c67656c..0000000 --- a/spec/support/models/container.rb +++ /dev/null @@ -1,9 +0,0 @@ -# -*- encoding: utf-8 -*- -# -*- frozen_string_literal: true -*- -# -*- warn_indent: true -*- - -class Container < ActiveRecord::Base - measured UnitMeasurements::Volume, :total_volume - - measured_volume :internal_volume, :external_volume -end diff --git a/spec/support/models/land.rb b/spec/support/models/land.rb deleted file mode 100644 index bed40fd..0000000 --- a/spec/support/models/land.rb +++ /dev/null @@ -1,9 +0,0 @@ -# -*- encoding: utf-8 -*- -# -*- frozen_string_literal: true -*- -# -*- warn_indent: true -*- - -class Land < ActiveRecord::Base - measured UnitMeasurements::Area, :total_area - - measured_area :carpet_area, :buildup_area -end diff --git a/spec/support/models/package.rb b/spec/support/models/package.rb deleted file mode 100644 index e89445c..0000000 --- a/spec/support/models/package.rb +++ /dev/null @@ -1,9 +0,0 @@ -# -*- encoding: utf-8 -*- -# -*- frozen_string_literal: true -*- -# -*- warn_indent: true -*- - -class Package < ActiveRecord::Base - measured UnitMeasurements::Weight, :total_weight - - measured_weight :item_weight, :package_weight -end diff --git a/spec/support/models/project_timeline.rb b/spec/support/models/project_timeline.rb deleted file mode 100644 index cce9db9..0000000 --- a/spec/support/models/project_timeline.rb +++ /dev/null @@ -1,9 +0,0 @@ -# -*- encoding: utf-8 -*- -# -*- frozen_string_literal: true -*- -# -*- warn_indent: true -*- - -class ProjectTimeline < ActiveRecord::Base - measured UnitMeasurements::Time, :duration - - measured_time :setup_time, :processing_time -end diff --git a/spec/support/models/substance.rb b/spec/support/models/substance.rb deleted file mode 100644 index cdbf666..0000000 --- a/spec/support/models/substance.rb +++ /dev/null @@ -1,9 +0,0 @@ -# -*- encoding: utf-8 -*- -# -*- frozen_string_literal: true -*- -# -*- warn_indent: true -*- - -class Substance < ActiveRecord::Base - measured UnitMeasurements::Density, :total_density - - measured_density :internal_density, :external_density -end diff --git a/spec/support/models/weather_report.rb b/spec/support/models/weather_report.rb deleted file mode 100644 index e4f689f..0000000 --- a/spec/support/models/weather_report.rb +++ /dev/null @@ -1,9 +0,0 @@ -# -*- encoding: utf-8 -*- -# -*- frozen_string_literal: true -*- -# -*- warn_indent: true -*- - -class WeatherReport < ActiveRecord::Base - measured UnitMeasurements::Temperature, :average_temperature - - measured_temperature :day_temperature, :night_temperature -end diff --git a/spec/support/schema.rb b/spec/support/schema.rb index fa6bf7a..322c6b8 100644 --- a/spec/support/schema.rb +++ b/spec/support/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 1) do +ActiveRecord::Schema.define(version: 2) do create_table "cubes", force: :cascade do |t| t.decimal "length_quantity", precision: 10, scale: 2 t.string "length_unit", limit: 12 @@ -28,58 +28,4 @@ t.decimal "height_value", precision: 10, scale: 2 t.string "height_uom", limit: 12 end - - create_table "containers", force: :cascade do |t| - t.decimal "total_volume_quantity", precision: 10, scale: 2 - t.string "total_volume_unit", limit: 12 - t.decimal "internal_volume_quantity", precision: 10, scale: 2 - t.string "internal_volume_unit", limit: 12 - t.decimal "external_volume_quantity", precision: 10, scale: 2 - t.string "external_volume_unit", limit: 12 - end - - create_table "lands", force: :cascade do |t| - t.decimal "total_area_quantity", precision: 10, scale: 2 - t.string "total_area_unit", limit: 12 - t.decimal "carpet_area_quantity", precision: 10, scale: 2 - t.string "carpet_area_unit", limit: 12 - t.decimal "buildup_area_quantity", precision: 10, scale: 2 - t.string "buildup_area_unit", limit: 12 - end - - create_table "packages", force: :cascade do |t| - t.decimal "total_weight_quantity", precision: 10, scale: 2 - t.string "total_weight_unit", limit: 12 - t.decimal "item_weight_quantity", precision: 10, scale: 2 - t.string "item_weight_unit", limit: 12 - t.decimal "package_weight_quantity", precision: 10, scale: 2 - t.string "package_weight_unit", limit: 12 - end - - create_table "substances", force: :cascade do |t| - t.decimal "total_density_quantity", precision: 10, scale: 2 - t.string "total_density_unit", limit: 12 - t.decimal "internal_density_quantity", precision: 10, scale: 2 - t.string "internal_density_unit", limit: 12 - t.decimal "external_density_quantity", precision: 10, scale: 2 - t.string "external_density_unit", limit: 12 - end - - create_table "weather_reports", force: :cascade do |t| - t.decimal "average_temperature_quantity", precision: 10, scale: 2 - t.string "average_temperature_unit", limit: 12 - t.decimal "day_temperature_quantity", precision: 10, scale: 2 - t.string "day_temperature_unit", limit: 12 - t.decimal "night_temperature_quantity", precision: 10, scale: 2 - t.string "night_temperature_unit", limit: 12 - end - - create_table "project_timelines", force: :cascade do |t| - t.decimal "duration_quantity", precision: 10, scale: 2 - t.string "duration_unit", limit: 12 - t.decimal "setup_time_quantity", precision: 10, scale: 2 - t.string "setup_time_unit", limit: 12 - t.decimal "processing_time_quantity", precision: 10, scale: 2 - t.string "processing_time_unit", limit: 12 - end end diff --git a/spec/support/shared_examples.rb b/spec/support/shared_examples.rb new file mode 100644 index 0000000..90ae0b6 --- /dev/null +++ b/spec/support/shared_examples.rb @@ -0,0 +1,65 @@ +# -*- encoding: utf-8 -*- +# -*- frozen_string_literal: true -*- +# -*- warn_indent: true -*- + +# spec/unit_measurements/shared_examples.rb + +RSpec.shared_examples "measured method" do |unit_group, method_name| + let!(:mock_model) { Class.new(ActiveRecord::Base) } + + it "responds to .#{method_name}" do + expect(mock_model).to respond_to(method_name) + end + + describe ".#{method_name}" do + it "defines single measurement attribute" do + mock_model.public_send(method_name, :attribute) + + expect_attribute_definition("attribute", unit_group, "attribute_quantity", "attribute_unit") + end + + it "defines multiple measurement attributes" do + mock_model.public_send(method_name, :attribute1, :attribute2) + + expect_attribute_definition("attribute1", unit_group, "attribute1_quantity", "attribute1_unit") + expect_attribute_definition("attribute2", unit_group, "attribute2_quantity", "attribute2_unit") + end + + it "accepts string or symbol for measurement attribute name" do + mock_model.public_send(method_name, "string_attr", :symbol_attr) + + expect_attribute_definition("string_attr", unit_group, "string_attr_quantity", "string_attr_unit") + expect_attribute_definition("symbol_attr", unit_group, "symbol_attr_quantity", "symbol_attr_unit") + end + + it "accepts quantity_attribute_name and unit_attribute_name options" do + mock_model.public_send(method_name, :attribute1, quantity_attribute_name: :custom_quantity, unit_attribute_name: :custom_unit) + + expect_attribute_definition("attribute1", unit_group, "custom_quantity", "custom_unit") + end + + it "accepts string or symbol for quantity_attribute_name and unit_attribute_name options" do + mock_model.public_send(method_name, :attribute1, quantity_attribute_name: "custom_quantity", unit_attribute_name: :custom_unit) + + expect_attribute_definition("attribute1", unit_group, "custom_quantity", "custom_unit") + end + + it "allows using both quantity_attribute_name and unit_attribute_name options simultaneously" do + mock_model.public_send(method_name, :attribute1, quantity_attribute_name: :custom_quantity, unit_attribute_name: :custom_unit) + + expect_attribute_definition("attribute1", unit_group, "custom_quantity", "custom_unit") + end + end + + private + + def expect_attribute_definition(attribute, unit_group, quantity_attribute_name, unit_attribute_name) + expect(mock_model.measured_attributes).to have_key(attribute) + + attribute_info = mock_model.measured_attributes[attribute] + + expect(attribute_info[:unit_group]).to eq(unit_group) + expect(attribute_info[:quantity_attribute_name]).to eq(quantity_attribute_name) + expect(attribute_info[:unit_attribute_name]).to eq(unit_attribute_name) + end +end diff --git a/spec/unit_measurements/rails/unit_groups/area_spec.rb b/spec/unit_measurements/rails/unit_groups/area_spec.rb new file mode 100644 index 0000000..dcefb8a --- /dev/null +++ b/spec/unit_measurements/rails/unit_groups/area_spec.rb @@ -0,0 +1,9 @@ +# -*- encoding: utf-8 -*- +# -*- frozen_string_literal: true -*- +# -*- warn_indent: true -*- + +# spec/unit_measurements/rails/unit_groups/area_spec.rb + +RSpec.describe UnitMeasurements::Rails::ActiveRecord::Area do + include_examples "measured method", UnitMeasurements::Area, :measured_area +end diff --git a/spec/unit_measurements/rails/unit_groups/density_spec.rb b/spec/unit_measurements/rails/unit_groups/density_spec.rb new file mode 100644 index 0000000..414dd18 --- /dev/null +++ b/spec/unit_measurements/rails/unit_groups/density_spec.rb @@ -0,0 +1,9 @@ +# -*- encoding: utf-8 -*- +# -*- frozen_string_literal: true -*- +# -*- warn_indent: true -*- + +# spec/unit_measurements/rails/unit_groups/density_spec.rb + +RSpec.describe UnitMeasurements::Rails::ActiveRecord::Density do + include_examples "measured method", UnitMeasurements::Density, :measured_density +end diff --git a/spec/unit_measurements/rails/unit_groups/length_spec.rb b/spec/unit_measurements/rails/unit_groups/length_spec.rb new file mode 100644 index 0000000..353a707 --- /dev/null +++ b/spec/unit_measurements/rails/unit_groups/length_spec.rb @@ -0,0 +1,9 @@ +# -*- encoding: utf-8 -*- +# -*- frozen_string_literal: true -*- +# -*- warn_indent: true -*- + +# spec/unit_measurements/rails/unit_groups/length_spec.rb + +RSpec.describe UnitMeasurements::Rails::ActiveRecord::Length do + include_examples "measured method", UnitMeasurements::Length, :measured_length +end diff --git a/spec/unit_measurements/rails/unit_groups/temperature_spec.rb b/spec/unit_measurements/rails/unit_groups/temperature_spec.rb new file mode 100644 index 0000000..8048ae8 --- /dev/null +++ b/spec/unit_measurements/rails/unit_groups/temperature_spec.rb @@ -0,0 +1,9 @@ +# -*- encoding: utf-8 -*- +# -*- frozen_string_literal: true -*- +# -*- warn_indent: true -*- + +# spec/unit_measurements/rails/unit_groups/temperature_spec.rb + +RSpec.describe UnitMeasurements::Rails::ActiveRecord::Temperature do + include_examples "measured method", UnitMeasurements::Temperature, :measured_temperature +end diff --git a/spec/unit_measurements/rails/unit_groups/time_spec.rb b/spec/unit_measurements/rails/unit_groups/time_spec.rb new file mode 100644 index 0000000..9a2f097 --- /dev/null +++ b/spec/unit_measurements/rails/unit_groups/time_spec.rb @@ -0,0 +1,9 @@ +# -*- encoding: utf-8 -*- +# -*- frozen_string_literal: true -*- +# -*- warn_indent: true -*- + +# spec/unit_measurements/rails/unit_groups/time_spec.rb + +RSpec.describe UnitMeasurements::Rails::ActiveRecord::Time do + include_examples "measured method", UnitMeasurements::Time, :measured_time +end diff --git a/spec/unit_measurements/rails/unit_groups/volume_spec.rb b/spec/unit_measurements/rails/unit_groups/volume_spec.rb new file mode 100644 index 0000000..e66c71d --- /dev/null +++ b/spec/unit_measurements/rails/unit_groups/volume_spec.rb @@ -0,0 +1,9 @@ +# -*- encoding: utf-8 -*- +# -*- frozen_string_literal: true -*- +# -*- warn_indent: true -*- + +# spec/unit_measurements/rails/unit_groups/volume_spec.rb + +RSpec.describe UnitMeasurements::Rails::ActiveRecord::Volume do + include_examples "measured method", UnitMeasurements::Volume, :measured_volume +end diff --git a/spec/unit_measurements/rails/unit_groups/weight_spec.rb b/spec/unit_measurements/rails/unit_groups/weight_spec.rb new file mode 100644 index 0000000..f039565 --- /dev/null +++ b/spec/unit_measurements/rails/unit_groups/weight_spec.rb @@ -0,0 +1,9 @@ +# -*- encoding: utf-8 -*- +# -*- frozen_string_literal: true -*- +# -*- warn_indent: true -*- + +# spec/unit_measurements/rails/unit_groups/weight_spec.rb + +RSpec.describe UnitMeasurements::Rails::ActiveRecord::Weight do + include_examples "measured method", UnitMeasurements::Weight, :measured_weight +end