gas-blender 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c2d08271e4a3efb7c9e14dfca0eb6e5b8ebca38c
4
+ data.tar.gz: 7dc1a5fb5875854107e64ded6e1355354b1627d6
5
+ SHA512:
6
+ metadata.gz: 599ca17e9b87996f84ea6e751ef96cbc0141b7aaf95a20d0a65767aeb6c98c6c2fd5fa6e1abf0edbc0fc763f77e5175847bc11e0dbe1a56ea182e41743e468c2
7
+ data.tar.gz: 30dfbfaa0fc66a1c481063eda6429f306cbf51ab6200d78adb5b49c7fcef5cfcf779098af171757725902ba5244c0c968babb2a2f87556cb09a335df52eecc29
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .rspec
@@ -0,0 +1 @@
1
+ 2.0.0-p481
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gas-blender.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Ken Mayer
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Gas::Blender
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'gas-blender'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install gas-blender
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/gas-blender/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ desc "Run specs"
7
+ task :default => :spec
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gas-blender/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "gas-blender"
8
+ spec.version = GasBlender::VERSION
9
+ spec.authors = ["Ken Mayer"]
10
+ spec.email = ["ken@bitwrangler.com"]
11
+ spec.summary = %q{Gas blending tools for SCUBA divers}
12
+ spec.description = %q{Gas blending tools for SCUBA divers. A thought experiment.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
@@ -0,0 +1,67 @@
1
+ require_relative "gas-blender/version"
2
+ require_relative "gas-blender/pressure"
3
+ require_relative "gas-blender/length"
4
+ require_relative "gas-blender/tank"
5
+ require_relative "gas-blender/fill"
6
+ require_relative "gas-blender/mix"
7
+
8
+ module GasBlender
9
+ module_function
10
+
11
+ def Pressure(arg)
12
+ case arg
13
+ when Bar, PSI
14
+ arg
15
+ when String
16
+ string_conversion(arg)
17
+ else
18
+ raise TypeError, "Can not convert #{arg.inspect} to Pressure"
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def self.string_conversion(arg)
25
+ case
26
+ when arg =~ /(\d.*) bar/
27
+ Bar.new($1.to_f)
28
+ when arg =~ /(\d.*) psi/
29
+ PSI.new($1.to_f)
30
+ else
31
+ raise TypeError, "Can not convert #{arg.inspect} to Pressure"
32
+ end
33
+ end
34
+ end
35
+
36
+ class Fixnum
37
+ def bar
38
+ GasBlender::Bar.new(self)
39
+ end
40
+ def psi
41
+ GasBlender::PSI.new(self)
42
+ end
43
+ def ean
44
+ GasBlender::Mix.new(self / 100.0)
45
+ end
46
+ def feet
47
+ GasBlender::Feet.new(self)
48
+ end
49
+ def meters
50
+ GasBlender::Meter.new(self)
51
+ end
52
+ end
53
+
54
+ class Float
55
+ def bar
56
+ GasBlender::Bar.new(self)
57
+ end
58
+ def psi
59
+ GasBlender::PSI.new(self)
60
+ end
61
+ def feet
62
+ GasBlender::Feet.new(self)
63
+ end
64
+ def meters
65
+ GasBlender::Meter.new(self)
66
+ end
67
+ end
@@ -0,0 +1,83 @@
1
+ module GasBlender
2
+ class Fill
3
+ attr_reader :mix
4
+ attr_reader :tank
5
+ attr_reader :fill_mix
6
+ attr_reader :top_off_mix
7
+
8
+ def initialize(attributes)
9
+ @mix = attributes.delete(:mix) || Mix.new(0.21)
10
+ @tank = attributes.delete(:tank)
11
+ @fill_mix = attributes.delete(:fill_mix) || Mix.new(1.0)
12
+ @top_off_mix = attributes.delete(:top_off_mix) || Mix.new(0.21)
13
+ raise RuntimeError, "Invalid attributes: #{attributes.keys.inspect}" unless attributes == {}
14
+ end
15
+
16
+ def pressure
17
+ if !pressure_need.zero?
18
+ (pressure_need * ((fO2_need - top_off_mix) / (fill_mix - top_off_mix))) + pressure_have
19
+ else
20
+ (pressure_want * (fO2_want - top_off_mix)) / (fO2_have - top_off_mix)
21
+ end
22
+ end
23
+
24
+ def mod(max_ppO2)
25
+ case tank.service_pressure
26
+ when GasBlender::PSI
27
+ mod_fsw(max_ppO2)
28
+ when GasBlender::Bar
29
+ mod_msw(max_ppO2)
30
+ else
31
+ raise TypeError, "Unknown tank service pressure, #{tank.inspect}"
32
+ end
33
+ end
34
+
35
+ def mod_fsw(max_ppO2)
36
+ mod_atm(max_ppO2).to_fsw - GasBlender::ATM.new(1.0).to_fsw
37
+ end
38
+
39
+ def mod_msw(max_ppO2)
40
+ mod_atm(max_ppO2).to_msw - GasBlender::ATM.new(1.0).to_msw
41
+ end
42
+
43
+ private
44
+
45
+ alias :fO2_want :mix
46
+
47
+ def fO2_have
48
+ Mix.new(tank.current_mix)
49
+ end
50
+
51
+ def fO2_need
52
+ Mix.new(ppO2_need / pressure_need)
53
+ end
54
+
55
+ def ppO2_want
56
+ tank.service_pressure * fO2_want
57
+ end
58
+
59
+ def ppO2_have
60
+ tank.current_pressure * fO2_have
61
+ end
62
+
63
+ def ppO2_need
64
+ ppO2_want - ppO2_have
65
+ end
66
+
67
+ def pressure_want
68
+ tank.service_pressure
69
+ end
70
+
71
+ def pressure_have
72
+ tank.current_pressure
73
+ end
74
+
75
+ def pressure_need
76
+ pressure_want - pressure_have
77
+ end
78
+
79
+ def mod_atm(max_ppO2)
80
+ GasBlender::ATM.new((max_ppO2.to_bar / mix) / Bar.new(1.0))
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "measure"
2
+
3
+ module GasBlender
4
+ class Length < Measure
5
+ end
6
+
7
+ class Feet < Length
8
+ def to_s
9
+ "%.#{PRECISION}f feet" % magnitude
10
+ end
11
+ end
12
+ class Meter < Length
13
+ def to_s
14
+ "%.#{PRECISION}f m" % magnitude
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,54 @@
1
+ module GasBlender
2
+ class Measure
3
+ include Comparable
4
+
5
+ PRECISION = 8
6
+
7
+ def initialize(magnitude)
8
+ @magnitude = magnitude.to_f
9
+ freeze
10
+ end
11
+
12
+ def inspect
13
+ "%.#{PRECISION}f" % magnitude
14
+ end
15
+
16
+ def <=>(other)
17
+ other.is_a?(self.class) && magnitude <=> other.magnitude
18
+ end
19
+ alias_method :eql?, :==
20
+
21
+ def hash
22
+ [magnitude, self.class].hash
23
+ end
24
+
25
+ def -(other)
26
+ raise TypeError, "#{other.inspect} is not a #{self.class}" unless other.is_a?(self.class)
27
+ self.class.new(magnitude - other.magnitude)
28
+ end
29
+
30
+ def *(factor)
31
+ self.class.new(magnitude * factor.to_f)
32
+ end
33
+
34
+ def /(denominator)
35
+ if denominator.class == self.class
36
+ magnitude / denominator.magnitude.to_f
37
+ else
38
+ self.class.new(magnitude / denominator.to_f)
39
+ end
40
+ end
41
+
42
+ def abs
43
+ self.class.new(magnitude.abs)
44
+ end
45
+
46
+ def zero?
47
+ magnitude.round(PRECISION) == 0.0
48
+ end
49
+
50
+ protected
51
+
52
+ attr_reader :magnitude
53
+ end
54
+ end
@@ -0,0 +1,9 @@
1
+ require_relative "measure"
2
+
3
+ module GasBlender
4
+ class Mix < Measure
5
+ def to_f
6
+ magnitude
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,70 @@
1
+ require_relative "measure"
2
+
3
+ module GasBlender
4
+ class Pressure < Measure
5
+ def <=>(other)
6
+ other = GasBlender::Pressure(other)
7
+ magnitude.round(PRECISION) <=> other.send(converter).magnitude.round(PRECISION)
8
+ end
9
+
10
+ def -(other)
11
+ other = GasBlender::Pressure(other)
12
+ self.class.new(magnitude - other.send(converter).magnitude)
13
+ end
14
+
15
+ def +(other)
16
+ other = GasBlender::Pressure(other)
17
+ self.class.new(magnitude + other.send(converter).magnitude)
18
+ end
19
+ end
20
+
21
+ class Bar < Pressure
22
+ def to_s
23
+ "%.#{PRECISION}f bar" % magnitude
24
+ end
25
+
26
+ def converter
27
+ :to_bar
28
+ end
29
+
30
+ def to_bar
31
+ self
32
+ end
33
+
34
+ def to_psi
35
+ PSI.new(magnitude * 14.5037738)
36
+ end
37
+ end
38
+
39
+ class PSI < Pressure
40
+ def to_s
41
+ "%.#{PRECISION}f psi" % magnitude
42
+ end
43
+
44
+ def converter
45
+ :to_psi
46
+ end
47
+
48
+ def to_psi
49
+ self
50
+ end
51
+
52
+ def to_bar
53
+ Bar.new(magnitude * 0.0689475729)
54
+ end
55
+ end
56
+
57
+ class ATM < Pressure
58
+ def to_s
59
+ "%.#{PRECISION}f atm" % magnitude
60
+ end
61
+
62
+ def to_fsw
63
+ Feet.new(33) * self.magnitude
64
+ end
65
+
66
+ def to_msw
67
+ Meter.new(10) * self.magnitude
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,14 @@
1
+ module GasBlender
2
+ class Tank
3
+ attr_reader :service_pressure
4
+ attr_reader :current_pressure
5
+ attr_reader :current_mix
6
+
7
+ def initialize(attributes = {})
8
+ @service_pressure = GasBlender::Pressure(attributes.delete(:service_pressure))
9
+ @current_pressure = GasBlender::Pressure(attributes.delete(:current_pressure) || service_pressure.class.new(0))
10
+ @current_mix = attributes.delete(:current_mix) || 0.21
11
+ raise RuntimeError, "Invalid attributes: #{attributes.keys.inspect}" unless attributes == {}
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module GasBlender
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,155 @@
1
+ require "gas-blender"
2
+
3
+ module GasBlender
4
+ describe Fill do
5
+ describe "top off pressure" do
6
+ it "given an empty tank, fill to 200 bar with EAN32" do
7
+ tank = Tank.new(
8
+ service_pressure: 200.bar
9
+ )
10
+ fill = Fill.new(
11
+ mix: 32.ean,
12
+ tank: tank
13
+ )
14
+ expect(fill.pressure).to be_within(0.05.bar).of(27.8.bar)
15
+ end
16
+
17
+ it "given an empty tank, fill to 3000 psi with EAN36" do
18
+ tank = Tank.new(
19
+ service_pressure: 3000.psi
20
+ )
21
+ fill = Fill.new(
22
+ mix: 36.ean,
23
+ tank: tank
24
+ )
25
+ expect(fill.pressure).to be_within(0.05.psi).of(569.6.psi)
26
+ end
27
+
28
+ it "given a tank with 1467 psi of EAN29, fill to 200 bar of EAN 36" do
29
+ tank = Tank.new(
30
+ service_pressure: 200.bar,
31
+ current_pressure: 67.bar,
32
+ current_mix: 32.ean
33
+ )
34
+ fill = Fill.new(
35
+ mix: 36.ean,
36
+ tank: tank
37
+ )
38
+ expect(fill.pressure).to be_within(0.05.bar).of(tank.current_pressure + 28.6.bar)
39
+ end
40
+
41
+ it "given a tank with 1000 psi of EAN28, fill to 3000 psi of EAN36 with EAN50" do
42
+ tank = Tank.new(
43
+ service_pressure: 3000.psi,
44
+ current_pressure: 1000.psi,
45
+ current_mix: 28.ean
46
+ )
47
+ fill = Fill.new(
48
+ mix: 36.ean,
49
+ tank: tank,
50
+ fill_mix: 50.ean
51
+ )
52
+ expect(fill.pressure).to be_within(0.5.psi).of(tank.current_pressure + 1310.psi)
53
+ end
54
+
55
+ it "given an empty tank, fill to 232 bar of EAN36 with EAN100, top off with EAN32" do
56
+ tank = Tank.new(
57
+ service_pressure: 232.bar
58
+ )
59
+ fill = Fill.new(
60
+ mix: 36.ean,
61
+ tank: tank,
62
+ top_off_mix: 32.ean
63
+ )
64
+ expect(fill.pressure).to be_within(0.05.bar).of(tank.current_pressure + 13.6.bar)
65
+ end
66
+
67
+ it "given a tank with 220 bar of EAN36, bleed to 161.3 and fill with air" do
68
+ tank = Tank.new(
69
+ service_pressure: 220.bar,
70
+ current_pressure: 220.bar,
71
+ current_mix: 36.ean
72
+ )
73
+ fill = Fill.new(
74
+ mix: 32.ean,
75
+ tank: tank
76
+ )
77
+ expect(fill.pressure).to be_within(0.05.bar).of(tank.current_pressure - 58.7.bar)
78
+ end
79
+
80
+ # Some more examples from the workbook
81
+ it "given a tank with 720 psi of 31.3, fill to 3000 psi of EAN31" do
82
+ tank = Tank.new(
83
+ service_pressure: 3000.psi,
84
+ current_pressure: 720.psi,
85
+ current_mix: Mix.new(0.313)
86
+ )
87
+ fill = Fill.new(
88
+ mix: 31.ean,
89
+ tank: tank
90
+ )
91
+ expect(fill.pressure).to be_within(1.psi).of(1005.psi)
92
+ end
93
+
94
+ it "given an empty tank, fill to 3000 psi with EAN31" do
95
+ tank = Tank.new(service_pressure: 3000.psi)
96
+ fill = Fill.new(mix: 31.ean, tank: tank)
97
+ expect(fill.pressure).to be_within(1.psi).of(380.psi)
98
+ end
99
+
100
+ it "given a tank with 190 psi of 31.7%, fill to 3000 psi of EAN31" do
101
+ tank = Tank.new(
102
+ service_pressure: 3000.psi,
103
+ current_pressure: 190.psi,
104
+ current_mix: Mix.new(0.317)
105
+ )
106
+ fill = Fill.new(
107
+ mix: 31.ean,
108
+ tank: tank
109
+ )
110
+ expect(fill.pressure).to be_within(1.psi).of(544.psi)
111
+ end
112
+ end
113
+
114
+ describe "maximum operating depth" do
115
+ # http://en.wikipedia.org/wiki/Maximum_operating_depth
116
+ context "Imperial" do
117
+ let(:tank) { Tank.new(service_pressure: 3000.psi)}
118
+
119
+ it "given EAN36 and max ppO2 of 1.4" do
120
+ fill = Fill.new(mix: 36.ean, tank: tank)
121
+ expect(fill.mod(1.4.bar)).to be_within(0.1.feet).of(95.3.feet)
122
+ end
123
+
124
+ it "EAN3 and max ppO2 of 1.6" do
125
+ fill = Fill.new(mix: 3.ean)
126
+ expect(fill.mod_fsw(1.6.bar)).to be_within(1.feet).of(1727.feet)
127
+ end
128
+
129
+ it "EAN100 and max ppO2 of 1.2" do
130
+ fill = Fill.new(mix: 100.ean)
131
+ expect(fill.mod_fsw(1.2.bar)).to be_within(1.feet).of(6.feet)
132
+ end
133
+ end
134
+
135
+ context "Metric" do
136
+ let(:tank) { Tank.new(service_pressure: 200.bar)}
137
+
138
+ it "given EAN36 and ppO2 of 1.4" do
139
+ fill = Fill.new(mix: 36.ean, tank: tank)
140
+ expect(fill.mod(1.4.bar)).to be_within(0.1.meters).of(28.9.meters)
141
+ end
142
+
143
+ it "EAN3 and max ppO2 of 1.2" do
144
+ fill = Fill.new(mix: 3.ean)
145
+ expect(fill.mod_msw(1.2.bar)).to be_within(0.1.meters).of(390.0.meters)
146
+ end
147
+
148
+ it "EAN100 and max ppO2 of 1.6" do
149
+ fill = Fill.new(mix: 100.ean)
150
+ expect(fill.mod_msw(1.6.bar)).to be_within(0.1.meters).of(6.0.meters)
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,25 @@
1
+ require "gas-blender"
2
+
3
+ module GasBlender
4
+ describe Mix do
5
+ subject(:mix) { Mix.new(0.32) }
6
+ it "is immutable" do
7
+ expect(mix).to be_frozen
8
+ end
9
+
10
+ it "can convert to a float" do
11
+ expect(mix.to_f).to eq(0.32)
12
+ end
13
+
14
+ it "implements Comparable" do
15
+ expect(Mix.new(0.36) <=> Mix.new(0.28)).to eq(1)
16
+ expect(Mix.new(0.28) <=> Mix.new(0.28)).to eq(0)
17
+ expect(Mix.new(0.28) <=> Mix.new(0.36)).to eq(-1)
18
+ end
19
+
20
+ it "is hashable" do
21
+ expect(Mix.new(0.36).hash).to eq(Mix.new(0.36).hash)
22
+ expect(Mix.new(0.36)).to be_eql(Mix.new(0.36))
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,108 @@
1
+ require "gas-blender"
2
+
3
+ module GasBlender
4
+ describe Pressure do
5
+ subject(:pressure) { Pressure.new(1) }
6
+
7
+ it "is immutable" do
8
+ expect(pressure).to be_frozen
9
+ end
10
+
11
+ it "is hashes by magnitude and class" do
12
+ expect(Pressure.new(1).hash).to eq(Pressure.new(1).hash)
13
+ expect(Pressure.new(1).hash).not_to eq(Bar.new(1).hash)
14
+ end
15
+ end
16
+
17
+ describe Bar do
18
+ subject(:pressure) { Bar.new(1) }
19
+
20
+ it "has a nice string representation" do
21
+ expect(pressure.to_s).to eq("1.00000000 bar")
22
+ end
23
+
24
+ it "is equal by value" do
25
+ expect(pressure).to eq(Bar.new(1))
26
+ end
27
+
28
+ it "equal values have eql? hashes" do
29
+ expect(Bar.new(1)).to be_eql(Bar.new(1))
30
+ end
31
+
32
+ it "is not rude by comparison" do
33
+ expect(pressure).to_not eq("fish")
34
+ end
35
+
36
+ it "will implicitly convert, however" do
37
+ expect(pressure).to eq(PSI.new(14.5037738))
38
+ end
39
+
40
+ it "implements Comparable" do
41
+ expect(Bar.new(9) <=> Bar.new(5)).to eq(1)
42
+ expect(Bar.new(5) <=> Bar.new(5)).to eq(0)
43
+ expect(Bar.new(5) <=> Bar.new(9)).to eq(-1)
44
+ end
45
+
46
+ it "converts to bar" do
47
+ expect(pressure.to_bar).to eq(Bar.new(1))
48
+ end
49
+
50
+ it "converts to psi" do
51
+ expect(pressure.to_psi).to eq(PSI.new(14.5037738))
52
+ end
53
+ end
54
+
55
+ describe PSI do
56
+ subject(:pressure) { PSI.new(1) }
57
+
58
+ it "has a nice string representation" do
59
+ expect(pressure.to_s).to eq("1.00000000 psi")
60
+ end
61
+
62
+ it "is equal by value" do
63
+ expect(pressure).to eq(PSI.new(1))
64
+ end
65
+
66
+ it "equal values have eql? hashes" do
67
+ expect(PSI.new(1)).to be_eql(PSI.new(1))
68
+ end
69
+
70
+ it "is not rude by comparison" do
71
+ expect(pressure).to_not eq("fish")
72
+ end
73
+
74
+ it "will implicitly convert, however" do
75
+ expect(pressure).to eq(Bar.new(0.0689475729))
76
+ end
77
+
78
+ it "converts to bar" do
79
+ expect(pressure.to_bar).to eq(Bar.new(0.0689475729))
80
+ end
81
+
82
+ it "converts to psi" do
83
+ expect(pressure.to_psi).to eq(PSI.new(1))
84
+ end
85
+ end
86
+
87
+ describe "Conversion function" do
88
+ it "is idempotent" do
89
+ expect(GasBlender::Pressure(Bar.new(1))).to eq(Bar.new(1))
90
+ expect(GasBlender::Pressure(PSI.new(1))).to eq(PSI.new(1))
91
+ end
92
+
93
+ it "parses strings" do
94
+ expect(GasBlender::Pressure("1 bar")).to eq(Bar.new(1))
95
+ expect(GasBlender::Pressure("1 psi")).to eq(PSI.new(1))
96
+ end
97
+
98
+ it "raises a helpful error" do
99
+ expect {
100
+ GasBlender::Pressure(1.0)
101
+ }.to raise_error(TypeError)
102
+ end
103
+
104
+ it "EAN" do
105
+ expect(32.ean).to eq(Mix.new(0.32))
106
+ end
107
+ end
108
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gas-blender
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ken Mayer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Gas blending tools for SCUBA divers. A thought experiment.
56
+ email:
57
+ - ken@bitwrangler.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .ruby-version
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - gas-blender.gemspec
69
+ - lib/gas-blender.rb
70
+ - lib/gas-blender/fill.rb
71
+ - lib/gas-blender/length.rb
72
+ - lib/gas-blender/measure.rb
73
+ - lib/gas-blender/mix.rb
74
+ - lib/gas-blender/pressure.rb
75
+ - lib/gas-blender/tank.rb
76
+ - lib/gas-blender/version.rb
77
+ - spec/gas-blender/fill_spec.rb
78
+ - spec/gas-blender/mix_spec.rb
79
+ - spec/gas-blender/pressure_spec.rb
80
+ homepage: ''
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.0.14
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Gas blending tools for SCUBA divers
104
+ test_files:
105
+ - spec/gas-blender/fill_spec.rb
106
+ - spec/gas-blender/mix_spec.rb
107
+ - spec/gas-blender/pressure_spec.rb