Fingertips-conversions 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
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