height 0.0.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.
@@ -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