height 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ class Height
2
+ module Units
3
+ class Base
4
+ include Comparable
5
+ include Math
6
+ attr_reader :value
7
+
8
+ def self.round_value(value)
9
+ key = self.name.split('::').last.downcase.to_sym
10
+
11
+ precision = ::Height.units_precision[key]
12
+
13
+ value.round(precision)
14
+ end
15
+
16
+ def initialize(value)
17
+ @value = self.class.round_value(value)
18
+ end
19
+
20
+ def <=>(other)
21
+ value <=> other_value(other)
22
+ end
23
+
24
+ def +(other)
25
+ result = value + other_value(other)
26
+ self.class.new(result)
27
+ end
28
+
29
+ def -(other)
30
+ result = value - other_value(other)
31
+
32
+ self.class.new(result)
33
+ end
34
+
35
+ def *(other)
36
+ result = value * other_value(other)
37
+ self.class.new(result)
38
+ end
39
+
40
+ def /(other)
41
+ result = value / other_value(other)
42
+ self.class.new(result)
43
+ end
44
+
45
+ def to_unit(klass)
46
+ class_name = klass.name.split('::').last.downcase
47
+ method = "to_#{class_name}"
48
+ send(method)
49
+ end
50
+
51
+ def to_s
52
+ "%g" % ("%0.2f" % value)
53
+ end
54
+
55
+ private
56
+ def other_value(other)
57
+ if other.respond_to? :to_unit
58
+ other.to_unit(self.class).value
59
+ else
60
+ other
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,31 @@
1
+ class Height
2
+ module Units
3
+ class Centimeters < Base
4
+
5
+ def to_millimeters
6
+ millimeters = value * MILLIMETERS_IN_CENTIMETER
7
+ Millimeters.new(millimeters)
8
+ end
9
+
10
+ def to_centimeters
11
+ self
12
+ end
13
+
14
+ def to_meters
15
+ to_millimeters.to_meters
16
+ end
17
+
18
+ def to_inches
19
+ to_millimeters.to_inches
20
+ end
21
+
22
+ def to_feet
23
+ to_inches.to_feet
24
+ end
25
+
26
+ def to_s
27
+ value.round.to_s
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+ class Height
2
+ module Units
3
+ class Feet < Base
4
+
5
+ def to_feet
6
+ self
7
+ end
8
+
9
+ def to_inches
10
+ inches = value * Height::INCHES_IN_FOOT
11
+ Inches.new(inches)
12
+ end
13
+
14
+ def to_millimeters
15
+ to_inches.to_millimeters
16
+ end
17
+
18
+ def to_centimeters
19
+ to_millimeters.to_centimeters
20
+ end
21
+
22
+ def to_meters
23
+ to_millimeters.to_meters
24
+ end
25
+
26
+ def feet
27
+ self.class.new(value.floor)
28
+ end
29
+
30
+ def inches
31
+ inches = value.modulo(1) * Height::INCHES_IN_FOOT
32
+ Inches.new(inches)
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ class Height
2
+ module Units
3
+ class Inches < Base
4
+
5
+ def to_inches
6
+ self
7
+ end
8
+
9
+ def to_millimeters
10
+ millimeters = value * Height::MILLIMETERS_IN_INCH
11
+ Millimeters.new(millimeters)
12
+ end
13
+
14
+ def to_centimeters
15
+ to_millimeters.to_centimeters
16
+ end
17
+
18
+ def to_meters
19
+ to_centimeters.to_meters
20
+ end
21
+
22
+ def to_feet
23
+ feet = value / Height::INCHES_IN_FOOT.to_f
24
+ Feet.new(feet)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ class Height
2
+ module Units
3
+ class Meters < Base
4
+
5
+ def to_millimeters
6
+ millimeters = value * MILLIMETERS_IN_METER
7
+ Millimeters.new(millimeters)
8
+ end
9
+
10
+ def to_centimeters
11
+ to_millimeters.to_centimeters
12
+ end
13
+
14
+ def to_meters
15
+ self
16
+ end
17
+
18
+ def to_inches
19
+ to_centimeters.to_inches
20
+ end
21
+
22
+ def to_feet
23
+ to_inches.to_feet
24
+ end
25
+
26
+ def meters
27
+ Meters.new(value.floor)
28
+ end
29
+
30
+ def centimeters
31
+ millimeters = (to_millimeters.value - meters.to_millimeters.value)
32
+
33
+ Millimeters.new(millimeters).to_centimeters
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ class Height
2
+ module Units
3
+ class Millimeters < Base
4
+
5
+ def to_millimeters
6
+ self
7
+ end
8
+
9
+ def to_centimeters
10
+ centimeters = value / Height::MILLIMETERS_IN_CENTIMETER.to_f
11
+ Centimeters.new(centimeters)
12
+ end
13
+
14
+ def to_meters
15
+ meters = value / Height::MILLIMETERS_IN_METER.to_f
16
+ Meters.new(meters)
17
+ end
18
+
19
+ def to_inches
20
+ inches = value / Height::MILLIMETERS_IN_INCH.to_f
21
+ Inches.new(inches)
22
+ end
23
+
24
+ def to_feet
25
+ to_inches.to_feet
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ class Height
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe Numeric do
5
+ describe '#to_height' do
6
+ it { 191.to_height.should == Height.new(191) }
7
+ it { 191.5.to_height.should == Height.new(191.5) }
8
+ end
9
+ end
10
+
11
+ describe String do
12
+ describe '#to_height' do
13
+ it { '191 cm'.to_height.should == Height.new(191) }
14
+ end
15
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ describe Height::Formatters::Imperial do
3
+ describe '#format' do
4
+
5
+ context 'without I18n' do
6
+ it 'formats' do
7
+ units.each do |unit|
8
+ Height::Formatters::Imperial.new(unit).format.should == "6 ft 3 in"
9
+ end
10
+ end
11
+ end
12
+
13
+ context 'with I18n' do
14
+ before do
15
+ ::I18n.backend.store_translations :en,
16
+ height: {
17
+ format: {
18
+ imperial: {
19
+ default: '%{feet}\' %{inches}"'
20
+ }
21
+ }
22
+ }
23
+ end
24
+
25
+ after do
26
+ reset_i18n
27
+ end
28
+
29
+ it 'uses i18n formats' do
30
+ units.each do |unit|
31
+ Height::Formatters::Imperial.new(unit).format.should == '6\' 3"'
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ describe Height::Formatters::Metric do
3
+ describe '#format' do
4
+ context 'without I18n' do
5
+ it 'formats' do
6
+ units.each do |unit|
7
+ Height::Formatters::Metric.new(unit).format.should == '1m 91cm'
8
+ end
9
+ end
10
+ end
11
+
12
+ context 'with I18n' do
13
+ before do
14
+ I18n.backend.store_translations :en,
15
+ height: {
16
+ format: {
17
+ metric: {
18
+ default: '%{meters}meters %{centimeters}centimeters',
19
+ only_meters: '%{only_meters} meters',
20
+ only_centimeters: '%{only_centimeters} centimeters'
21
+ }
22
+ }
23
+ }
24
+ end
25
+
26
+ after do
27
+ reset_i18n
28
+ end
29
+
30
+ it 'formats' do
31
+ units.each do |unit|
32
+ formatter = Height::Formatters::Metric.new(unit)
33
+ formatter.format.should == '1meters 91centimeters'
34
+ formatter.format(:only_meters).should == '1.91 meters'
35
+ formatter.format(:only_centimeters).should == '191 centimeters'
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe Height do
4
+ it 'is comparable' do
5
+ Height.new(191).should > Height.new(190)
6
+ Height.new(191).should == Height.new(191)
7
+ end
8
+
9
+ describe '.system_of_units' do
10
+ it 'can be changed in Height class' do
11
+ Height.system_of_units = :imperial
12
+ Height.new(191).to_s.should == '6 ft 3 in'
13
+ Height.system_of_units = :metric
14
+ end
15
+ end
16
+
17
+ describe '.units_precision' do
18
+ before do
19
+ @previous_unit_precision = Height.units_precision.dup
20
+ end
21
+
22
+ it 'can be changed in Height class' do
23
+ Height.units_precision[:centimeters] = 2
24
+ Height.new(190.5).centimeters.should == 190.50
25
+ end
26
+
27
+ after do
28
+ Height.units_precision = @previous_unit_precision
29
+ end
30
+ end
31
+
32
+ it '+' do
33
+ (Height.new(200) + Height.new(10)).should == Height.new(210)
34
+ end
35
+
36
+ it '-' do
37
+ (Height.new(200) - Height.new(10)).should == Height.new(190)
38
+ end
39
+
40
+ describe '#initialize' do
41
+ it 'accepts Height::Units' do
42
+ centimeters = Height::Units::Centimeters.new(191)
43
+
44
+ Height.new(centimeters).centimeters.should == centimeters
45
+ end
46
+ end
47
+
48
+ describe '#to_s' do
49
+ it 'works without arguments' do
50
+ Height.new(191).to_s.should == '1m 91cm'
51
+ end
52
+
53
+ it 'formats with metric system' do
54
+ Height.new(191).to_s(:default, :metric).should == '1m 91cm'
55
+ end
56
+
57
+ it 'formats with imperial system' do
58
+ Height.new('6ft 3in').to_s(:default, :imperial).should == '6 ft 3 in'
59
+ end
60
+
61
+ it 'raises when invalid system provided' do
62
+ expect { Height.new(191).to_s(:default, :alien) }.to raise_error(ArgumentError)
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Height::Parser do
4
+ describe '#centimeters' do
5
+ it { Height::Parser.new(191).centimeters.should == Height::Units::Centimeters.new(191) }
6
+ it { Height::Parser.new('191').centimeters.should == Height::Units::Centimeters.new(191) }
7
+ it { Height::Parser.new('1m 91cm').centimeters.should == Height::Units::Centimeters.new(191) }
8
+ it { Height::Parser.new('6 feet 3 inches').centimeters.should == Height::Units::Centimeters.new(191) }
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Height::Parsers::Imperial do
4
+ it { Height::Parsers::Imperial.new('6 feet 3 inches').inches.should == Height::Units::Inches.new(75) }
5
+ it { Height::Parsers::Imperial.new('6 feet').centimeters.should == Height::Units::Centimeters.new(183) }
6
+ it { Height::Parsers::Imperial.new('6 \'').meters.should == Height::Units::Meters.new(1.83) }
7
+ it { Height::Parsers::Imperial.new('6\' 3"').feet.should == Height::Units::Feet.new(6.25) }
8
+ it { Height::Parsers::Imperial.new('6ft 3in').feet.should == Height::Units::Feet.new(6.25) }
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Height::Parsers::Metric do
4
+ it { Height::Parsers::Metric.new(191).centimeters.should == Height::Units::Centimeters.new(191) }
5
+ it { Height::Parsers::Metric.new('191').centimeters.should == Height::Units::Centimeters.new(191) }
6
+ it { Height::Parsers::Metric.new('191 cm').centimeters.should == Height::Units::Centimeters.new(191) }
7
+ it { Height::Parsers::Metric.new('1m 91cm').inches.should == Height::Units::Inches.new(75) }
8
+ it { Height::Parsers::Metric.new('1m').meters.should == Height::Units::Meters.new(1) }
9
+ end
@@ -0,0 +1,16 @@
1
+ require 'height'
2
+ require 'pry'
3
+ require 'i18n'
4
+
5
+ def reset_i18n
6
+ I18n.backend = I18n::Backend::Simple.new
7
+ end
8
+
9
+ def units
10
+ [
11
+ Height::Units::Feet.new(6.25),
12
+ Height::Units::Inches.new(75),
13
+ Height::Units::Meters.new(1.91),
14
+ Height::Units::Centimeters.new(191)
15
+ ]
16
+ end