gas-blender 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,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