measurement 0.2 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/lib/measurement.rb +55 -22
- data/measurement.gemspec +2 -2
- data/spec/lib/measurement_spec.rb +40 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
data/lib/measurement.rb
CHANGED
@@ -22,6 +22,8 @@ module Measurement
|
|
22
22
|
# Length.new(10).to_s(:qt, 3) => 0.005qt
|
23
23
|
#
|
24
24
|
class Base
|
25
|
+
include Comparable
|
26
|
+
|
25
27
|
# Define the base measurement unit. This method accepts
|
26
28
|
# a list of names for the base measurement, followed
|
27
29
|
# by the standard unit options. See #unit
|
@@ -39,14 +41,33 @@ module Measurement
|
|
39
41
|
# base unit.
|
40
42
|
#
|
41
43
|
def self.base(*args)
|
42
|
-
if args.any?
|
44
|
+
if args.any? || !@base
|
43
45
|
@base = Unit.new(1.0, *args)
|
44
46
|
add_unit(@base)
|
47
|
+
register_measurement
|
45
48
|
else
|
46
49
|
@base
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
53
|
+
def self.register_measurement
|
54
|
+
method_name = name.gsub(/\s/, '_').gsub(/.[A-Z]/) do |s|
|
55
|
+
s[0,1] + '_' + s[1,1].downcase
|
56
|
+
end.downcase
|
57
|
+
|
58
|
+
[Fixnum, Float].each do |klass|
|
59
|
+
klass.class_eval %Q{
|
60
|
+
def to_#{method_name}
|
61
|
+
#{name}.new(self)
|
62
|
+
end}
|
63
|
+
end
|
64
|
+
|
65
|
+
String.class_eval %Q{
|
66
|
+
def to_#{method_name}
|
67
|
+
#{name}.parse(self)
|
68
|
+
end}
|
69
|
+
end
|
70
|
+
|
50
71
|
def self.units # :nodoc:
|
51
72
|
@units ||= []
|
52
73
|
end
|
@@ -70,8 +91,8 @@ module Measurement
|
|
70
91
|
# * <tt>prefix</tt> - A prefix to use when formatting the unit.
|
71
92
|
# * <tt>suffix</tt> - A suffix to use when formatting the unit.
|
72
93
|
#
|
73
|
-
def self.unit(
|
74
|
-
add_unit(Unit.new(
|
94
|
+
def self.unit(unit, *args)
|
95
|
+
add_unit(Unit.new(unit, *args))
|
75
96
|
end
|
76
97
|
|
77
98
|
def self.add_unit(unit) # :nodoc:
|
@@ -91,16 +112,16 @@ module Measurement
|
|
91
112
|
end
|
92
113
|
end
|
93
114
|
|
94
|
-
def self.from(amount,
|
95
|
-
fetch_scale(
|
115
|
+
def self.from(amount, unit) # :nodoc:
|
116
|
+
fetch_scale(unit).from(amount)
|
96
117
|
end
|
97
118
|
|
98
|
-
def self.to(amount,
|
99
|
-
fetch_scale(
|
119
|
+
def self.to(amount, unit = nil) # :nodoc:
|
120
|
+
fetch_scale(unit).to(amount)
|
100
121
|
end
|
101
122
|
|
102
|
-
def self.format(amount,
|
103
|
-
fetch_scale(
|
123
|
+
def self.format(amount, unit = nil, precision = 2) #:nodoc:
|
124
|
+
fetch_scale(unit).format(amount, precision)
|
104
125
|
end
|
105
126
|
|
106
127
|
# Parse a string containing this measurement. The string
|
@@ -114,7 +135,7 @@ module Measurement
|
|
114
135
|
#
|
115
136
|
# If a valid unit cannot be found an error is raised:
|
116
137
|
#
|
117
|
-
# Weight.parse("180cm") => Measurement::
|
138
|
+
# Weight.parse("180cm") => Measurement::NoUnitException
|
118
139
|
#
|
119
140
|
def self.parse(string)
|
120
141
|
string = string.dup
|
@@ -122,15 +143,15 @@ module Measurement
|
|
122
143
|
|
123
144
|
while string =~ /(\d+(\.\d+)?)([^\d]*)/
|
124
145
|
amount = $1.to_f
|
125
|
-
|
146
|
+
unit = $3 && $3.strip
|
126
147
|
|
127
|
-
if
|
128
|
-
|
148
|
+
if unit && unit.length > 0
|
149
|
+
unit = find_scale(unit)
|
129
150
|
|
130
|
-
if
|
131
|
-
raise NoUnitFoundException.new(
|
151
|
+
if unit.nil?
|
152
|
+
raise NoUnitFoundException.new(unit)
|
132
153
|
else
|
133
|
-
base_amount +=
|
154
|
+
base_amount += unit.from(amount)
|
134
155
|
end
|
135
156
|
else
|
136
157
|
base_amount += amount
|
@@ -142,8 +163,8 @@ module Measurement
|
|
142
163
|
self.new(base_amount)
|
143
164
|
end
|
144
165
|
|
145
|
-
def initialize(amount = 0,
|
146
|
-
@amount = self.class.from(amount,
|
166
|
+
def initialize(amount = 0, unit = nil)
|
167
|
+
@amount = self.class.from(amount, unit)
|
147
168
|
end
|
148
169
|
|
149
170
|
# The base unit as an integer
|
@@ -155,6 +176,18 @@ module Measurement
|
|
155
176
|
def to_f
|
156
177
|
@amount.to_f
|
157
178
|
end
|
179
|
+
|
180
|
+
def <=>(anOther)
|
181
|
+
to_f <=> anOther.to_f
|
182
|
+
end
|
183
|
+
|
184
|
+
%w(+ - / *).each do |operator|
|
185
|
+
class_eval %Q{
|
186
|
+
def #{operator}(anOther)
|
187
|
+
self.class.new(self.to_f #{operator} anOther.to_f)
|
188
|
+
end
|
189
|
+
}
|
190
|
+
end
|
158
191
|
|
159
192
|
# This measurement converted to the specified unit.
|
160
193
|
#
|
@@ -173,11 +206,11 @@ module Measurement
|
|
173
206
|
|
174
207
|
def method_missing(method, *args) # :nodoc:
|
175
208
|
if method.to_s =~ /^(as|in)_(.*)/
|
176
|
-
|
177
|
-
if
|
178
|
-
to_s(
|
209
|
+
unit = $2
|
210
|
+
if unit =~ /and/
|
211
|
+
to_s(unit, *args)
|
179
212
|
else
|
180
|
-
as(
|
213
|
+
as(unit.to_sym, *args)
|
181
214
|
end
|
182
215
|
else
|
183
216
|
super
|
data/measurement.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{measurement}
|
5
|
-
s.version = "0.2"
|
5
|
+
s.version = "0.2.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Jeremy Wells"]
|
9
|
-
s.date = %q{2010-02-
|
9
|
+
s.date = %q{2010-02-28}
|
10
10
|
s.description = %q{A library for holding, converting and formatting measurements}
|
11
11
|
s.email = %q{jemmyw@gmail.com}
|
12
12
|
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.rdoc", "lib/measurement.rb", "lib/measurement/length.rb", "lib/measurement/unit.rb", "lib/measurement/weight.rb"]
|
@@ -1,6 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Measurement::Base do
|
4
|
+
describe '::base' do
|
5
|
+
it 'should define to_measurement on Fixnum and Float' do
|
6
|
+
Length
|
7
|
+
1.to_length.should be_a(Length)
|
8
|
+
1.to_length.to_f.should == 1.0
|
9
|
+
1.5.to_length.should be_a(Length)
|
10
|
+
1.5.to_length.to_f.should == 1.5
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should define to_measurement on String' do
|
14
|
+
Length
|
15
|
+
"10cm".to_length.should be_a(Length)
|
16
|
+
"10cm".to_length.to_s(:metre, 1).should == "0.1m"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
4
20
|
describe '::parse' do
|
5
21
|
it 'should parse in the base unit if no unit is specified' do
|
6
22
|
Length.parse('113').to_f.should == 113.0
|
@@ -33,6 +49,30 @@ describe Measurement::Base do
|
|
33
49
|
end
|
34
50
|
end
|
35
51
|
|
52
|
+
describe 'operators' do
|
53
|
+
before do
|
54
|
+
@length_1 = Length.new(1)
|
55
|
+
@length_2 = Length.new(2)
|
56
|
+
end
|
57
|
+
|
58
|
+
%w(+ - / *).each do |operator|
|
59
|
+
it 'should return a new object of the same type' do
|
60
|
+
@length_1.send(operator, @length_2).should be_a(Length)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should perform the operator' do
|
64
|
+
@value = @length_1.to_f.send(operator, @length_2.to_f)
|
65
|
+
@length_1.send(operator, @length_2).to_f.should == @value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#<=>' do
|
71
|
+
it 'should return the difference between the objects' do
|
72
|
+
(Length.new(1) <=> Length.new(2)).should == (1.0 <=> 2.0)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
36
76
|
describe '#method_missing' do
|
37
77
|
it 'should call as if passed in_scale' do
|
38
78
|
Length.new(10).in_cm.should == Length.new(10).as(:cm)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: measurement
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Wells
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-28 00:00:00 +13:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|