Fingertips-conversions 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2008 Manfred Stienstra, Fingertips <manfred@fngtps.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,32 @@
1
+ = Conversions
2
+
3
+ The conversions plugin does a number of things. The core functionality is the unit conversion:
4
+
5
+ 1.miles.to(:kilometres) #=> 1.609344
6
+ 1.pounds.to(:kilograms) #=> 0.453592
7
+
8
+ It also adds a class method to ActiveRecord::Base that allows you to define conversion methods for attributes:
9
+
10
+ class Car < ActiveRecord::Base
11
+ conversion_accessor :weight, :internal => :kilograms, :external => :pounds
12
+ end
13
+
14
+ car = Car.new(:weight => 1500)
15
+ car.weight_in_pounds #=> 3306.93393
16
+
17
+
18
+ == Installation
19
+
20
+ === As a gem
21
+
22
+ Configure the gem in environment.rb:
23
+
24
+ config.gem 'Fingertips-conversions', :lib => 'conversions', :source => 'http://gems.github.com'
25
+
26
+ Install them using Rails' rake task:
27
+
28
+ $ rake gems:install
29
+
30
+ === In your vendor directory:
31
+
32
+ script/install plugin git://github.com/Fingertips/conversions.git
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+
4
+ desc 'Default: run unit tests.'
5
+ task :default => :test
6
+
7
+ desc 'Test the conversions plugin.'
8
+ Rake::TestTask.new(:test) do |t|
9
+ t.libs << 'lib'
10
+ t.pattern = 'test/**/*_test.rb'
11
+ t.verbose = true
12
+ end
13
+
14
+ namespace :rdoc do
15
+ desc 'Generate documentation for conversions plugin.'
16
+ Rake::RDocTask.new(:generate) do |rdoc|
17
+ rdoc.rdoc_dir = 'documentation'
18
+ rdoc.title = 'Conversions'
19
+ rdoc.options << '--line-numbers' << '--inline-source' << '--charset' << 'utf-8'
20
+ rdoc.rdoc_files.include('README', 'lib/**/*.rb')
21
+ end
22
+ end
23
+
24
+ namespace :gem do
25
+ desc "Build the gem"
26
+ task :build do
27
+ sh 'gem build conversions.gemspec'
28
+ end
29
+
30
+ desc "Install the gem"
31
+ task :install => :build do
32
+ sh 'sudo gem install conversions-*.gem'
33
+ end
34
+ end
data/TODO ADDED
File without changes
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "conversions"
3
+ spec.version = "1.2.1"
4
+
5
+ spec.author = "Manfred Stienstra"
6
+ spec.email = "manfred@fngtps.com"
7
+
8
+ spec.description = <<-EOF
9
+ A Ruby on Rails plugin that adds conversion capabilities to numeric objects"
10
+ EOF
11
+ spec.summary = <<-EOF
12
+ A Ruby on Rails plugin that adds conversion capabilities to numeric objects"
13
+ EOF
14
+ spec.homepage = "http://github.com/Fingertips/conversions/tree/master"
15
+
16
+ spec.files = ["conversions.gemspec", "init.rb", "lib", "LICENSE", "rails", "Rakefile", "README", "test", "TODO", "lib/conversions/active_record_accessors.rb", "lib/conversions/ext.rb", "lib/conversions/unit.rb", "lib/conversions.rb", "rails/init.rb", "test/accessor_test.rb", "test/ext_test.rb", "test/test_helper.rb", "test/unit_test.rb"]
17
+ spec.test_files = ["test/unit_test.rb", "test/accessor_test.rb", "test/ext_test.rb", "test/test_helper.rb"]
18
+
19
+ spec.has_rdoc = true
20
+ spec.extra_rdoc_files = ['README', 'LICENSE']
21
+ spec.rdoc_options << "--charset=utf-8"
22
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'conversions'
@@ -0,0 +1,49 @@
1
+ module Conversions #:nodoc:
2
+ # Implements new accessor classmethods to define conversion accessors on active record classes.
3
+ module ActiveRecordAccessors
4
+ # Adds conversion methods to the model for a certain attribute.
5
+ #
6
+ # Options:
7
+ #
8
+ # * <tt>:internal</tt>: The unit of the internal value
9
+ # * <tt>:external</tt>: The unit of desired external value
10
+ # * <tt>:scale</tt>: If a scale is given, the external value is automatically rounded on the specified scale.
11
+ #
12
+ #
13
+ # Examples:
14
+ #
15
+ # require 'conversions'
16
+ #
17
+ # class Flight
18
+ # extend Conversions::ActiveRecordAccessors
19
+ #
20
+ # attr_accessor :distance
21
+ # conversion_accessor :distance, :internal => :kilometers, :external => :miles, :scale => 2
22
+ #
23
+ # def initialize(distance)
24
+ # self.distance = distance
25
+ # end
26
+ # end
27
+ #
28
+ # flight = Flight.new(1200)
29
+ # flight.distance_in_miles #=> 745.65, rounded down to two decimals as specified in :scale
30
+ #
31
+ # When used as a plugin for Rails, the ActiveRecord::Base is automatically extended.
32
+ #
33
+ # class Car < ActiveRecord::Base
34
+ # conversion_accessor :length, :internal => :kilometers, :external => :miles
35
+ # end
36
+ def conversion_accessor(attribute, options={})
37
+ if options[:internal].nil? or options[:external].nil?
38
+ raise ArgumentError, "Please specify both :external and :internal metrics."
39
+ end
40
+ define_method "#{attribute}_in_#{options[:external]}" do
41
+ v = send(attribute)
42
+ v ? v.send(options[:internal]).to(options[:external], options[:scale]) : nil
43
+ end
44
+ define_method "#{attribute}_in_#{options[:external]}=" do |v|
45
+ send("#{attribute}=", v.to_f.send(options[:external]).to(options[:internal]))
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,10 @@
1
+ module Conversions #:nodoc:
2
+ # Defines all the conversion methods (miles, kilometers, etc…)
3
+ module Ext
4
+ Unit.conversion.each do |method, _|
5
+ define_method method do
6
+ Unit.new self, method
7
+ end unless respond_to? method
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,46 @@
1
+ module Conversions #:nodoc
2
+ # Proxy class to contain the unit as well as reference the base value
3
+ class Unit
4
+ # Create a new Unit instance.
5
+ #
6
+ # * _value_: The value to convert from (ie. 4.92)
7
+ # * _from_: The unit to convert from (ie. :miles)
8
+ def initialize(value, from)
9
+ @value = value
10
+ @from = from
11
+ end
12
+
13
+ # Convert to a certain other unit.
14
+ #
15
+ # * _to_: The unit to convert to (ie. :kilometers)
16
+ # * _scale_: The number of digits behind the decimal point to you want to keep (Optional)
17
+ def to(to, scale=nil)
18
+ value = @value * self.class.exchange_rate(@from, to)
19
+ scale.nil? ? value : (value * (10 ** scale)).round / (10 ** scale).to_f
20
+ end
21
+
22
+ def self.exchange_rate(from_unit, to_unit) #:nodoc:
23
+ return 1 if from_unit == to_unit
24
+ from = conversion[from_unit]
25
+ raise ArgumentError, "Can't convert from `#{from}', unknown unit" if from.nil?
26
+ to = from[to_unit]
27
+ raise ArgumentError, "Can't convert from `#{from_unit}' to `#{to_unit}', unknown unit" if to.nil?
28
+ to
29
+ end
30
+
31
+ def self.conversion #:nodoc:
32
+ if !defined? @@conversion
33
+ @@conversion = {}
34
+ CONVERSION.each do |from, conversion|
35
+ conversion.each do |to, value|
36
+ @@conversion[from] ||= {}
37
+ @@conversion[from][to] = value
38
+ @@conversion[to] ||= {}
39
+ @@conversion[to][from] = 1.0 / value
40
+ end
41
+ end
42
+ end
43
+ @@conversion
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,31 @@
1
+ module Conversions
2
+ CONVERSION = {
3
+ :miles => {
4
+ :kilometres => 1.609344
5
+ },
6
+ :kilograms => {
7
+ :grams => 1000.0,
8
+ :pounds => 2.20462262,
9
+ :short_tons => 0.00110231131,
10
+ :tons => 0.00110231131
11
+ },
12
+ :tons => {
13
+ :pounds => 2000.0
14
+ },
15
+ :gallons => {
16
+ :litres => 3.7854118
17
+ },
18
+ :cubic_feet => {
19
+ :cubic_meters => 0.0283168466
20
+ }
21
+ }
22
+ end
23
+
24
+ require 'conversions/unit'
25
+ require 'conversions/ext'
26
+ require 'conversions/active_record_accessors'
27
+
28
+ Numeric.send :include, Conversions::Ext
29
+ if defined?(ActiveRecord)
30
+ ActiveRecord::Base.send :extend, Conversions::ActiveRecordAccessors
31
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'init')
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Flight
4
+ extend Conversions::ActiveRecordAccessors
5
+ attr_accessor :distance, :fuel_consumption
6
+ conversion_accessor :distance, :internal => :kilometres, :external => :miles
7
+ conversion_accessor :fuel_consumption, :internal => :litres, :external => :gallons, :scale => 2
8
+ end
9
+
10
+ class AccessorTest < Test::Unit::TestCase
11
+
12
+ def setup
13
+ @flight = Flight.new
14
+ end
15
+
16
+ def test_include
17
+ assert @flight.respond_to?(:distance)
18
+ assert @flight.respond_to?(:distance_in_miles)
19
+ end
20
+
21
+ def test_conversion
22
+ @flight.distance = 1200
23
+ assert_in_delta 745.645430684801, @flight.distance_in_miles, DELTA
24
+ end
25
+
26
+ def test_conversion_with_scale
27
+ @flight.fuel_consumption = 3400
28
+ assert_equal 898.18, @flight.fuel_consumption_in_gallons, DELTA
29
+ end
30
+ end
data/test/ext_test.rb ADDED
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class ExtTest < Test::Unit::TestCase
4
+
5
+ def test_conversions
6
+ assert_in_delta 1.609344, 1.miles.to(:kilometres), DELTA
7
+ assert_in_delta 1.609344, 1.0.miles.to(:kilometres), DELTA
8
+ assert_in_delta 0.45359237, 1.pounds.to(:kilograms), DELTA
9
+ assert_in_delta 0.00110231131092439, 1.kilograms.to(:tons), DELTA
10
+ assert_in_delta 2.20462262184878, 1.kilograms.to(:pounds), DELTA
11
+ assert_in_delta 1, ( 1.kilograms.to(:pounds) * 1.pounds.to(:kilograms) ), DELTA
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require 'test/unit'
2
+
3
+ if not defined?(ActiveRecord)
4
+ require 'rubygems'
5
+ require 'active_record'
6
+ end
7
+
8
+ $:.unshift File.dirname(__FILE__) + '/../lib'
9
+ require 'conversions'
10
+
11
+ DELTA = 0.0000001
data/test/unit_test.rb ADDED
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class UnitTest < Test::Unit::TestCase
4
+ def test_exchange_rate
5
+ assert_in_delta 1.609344, Conversions::Unit.exchange_rate(:miles, :kilometres), DELTA
6
+ assert_in_delta 0.621371192237334, Conversions::Unit.exchange_rate(:kilometres, :miles), DELTA
7
+ assert_raises(ArgumentError) { Conversions::Unit.exchange_rate(:unknown, :miles) }
8
+ assert_raises(ArgumentError) { Conversions::Unit.exchange_rate(:miles, :unknown) }
9
+ assert_raises(ArgumentError) { Conversions::Unit.exchange_rate(nil, :miles) }
10
+ assert_raises(ArgumentError) { Conversions::Unit.exchange_rate(:miles, nil) }
11
+ end
12
+
13
+ def test_exchange_rate_for_identity_transform
14
+ Conversions::Unit.conversion.keys.each do |unit|
15
+ assert_equal 1, Conversions::Unit.exchange_rate(unit, unit)
16
+ end
17
+ end
18
+
19
+ def test_to
20
+ amount = Conversions::Unit.new(10.0, :miles)
21
+ assert_in_delta 16.09344, amount.to(:kilometres), DELTA
22
+
23
+ amount = Conversions::Unit.new(10.0, :miles)
24
+ assert_equal 16.09, amount.to(:kilometres, 2), DELTA
25
+
26
+ amount = Conversions::Unit.new(10.0, :kilograms)
27
+ assert_in_delta 22.0462262184878, amount.to(:pounds), DELTA
28
+
29
+ amount = Conversions::Unit.new(10.0, :kilograms)
30
+ assert_equal 22.05, amount.to(:pounds, 2), DELTA
31
+ end
32
+
33
+ def test_identity_transforms
34
+ Conversions::Unit.conversion.keys.each do |unit|
35
+ assert_equal 1.0, Conversions::Unit.new(1.0, unit).to(unit, 2)
36
+ end
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Fingertips-conversions
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Manfred Stienstra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-11 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A Ruby on Rails plugin that adds conversion capabilities to numeric objects"
17
+ email: manfred@fngtps.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - LICENSE
25
+ files:
26
+ - conversions.gemspec
27
+ - init.rb
28
+ - lib
29
+ - LICENSE
30
+ - rails
31
+ - Rakefile
32
+ - README
33
+ - test
34
+ - TODO
35
+ - lib/conversions/active_record_accessors.rb
36
+ - lib/conversions/ext.rb
37
+ - lib/conversions/unit.rb
38
+ - lib/conversions.rb
39
+ - rails/init.rb
40
+ - test/accessor_test.rb
41
+ - test/ext_test.rb
42
+ - test/test_helper.rb
43
+ - test/unit_test.rb
44
+ has_rdoc: true
45
+ homepage: http://github.com/Fingertips/conversions/tree/master
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --charset=utf-8
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.2.0
67
+ signing_key:
68
+ specification_version: 2
69
+ summary: A Ruby on Rails plugin that adds conversion capabilities to numeric objects"
70
+ test_files:
71
+ - test/unit_test.rb
72
+ - test/accessor_test.rb
73
+ - test/ext_test.rb
74
+ - test/test_helper.rb