nemah 0.1.1 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/Gemfile +4 -0
- data/README.md +7 -7
- data/lib/nemah.rb +1 -0
- data/lib/nemah/amount.rb +18 -0
- data/lib/nemah/fodder.rb +18 -0
- data/lib/nemah/fodder_list.rb +45 -0
- data/lib/nemah/nutrients.rb +20 -0
- data/lib/nemah/ration.rb +42 -0
- data/lib/nemah/specific_need/abstract_need.rb +4 -0
- data/lib/nemah/version.rb +1 -1
- data/nemah.gemspec +0 -1
- data/spec/nemah/amount_spec.rb +22 -0
- data/spec/nemah/fodder_list_spec.rb +102 -0
- data/spec/nemah/fodder_spec.rb +88 -0
- data/spec/nemah/ration_spec.rb +173 -0
- data/spec/nemah/specific_need/abstract_need_spec.rb +21 -0
- data/spec/spec_helper.rb +7 -1
- data/spec/support/shared_examples_for_a_specific_need.rb +2 -2
- metadata +18 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cf97baf48299379410e2eba6a236517e9f466c3
|
4
|
+
data.tar.gz: 164041b7b1042eaacabcbe5d08169d08c9cee769
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3d16f09f03c521916efbf78140e8c6644eccfa664a7096462131a5612c96255fa08635b7a8cd01c07bbf60dd5a7a79a4bef02e42382ca41f5299638d46ce93f
|
7
|
+
data.tar.gz: f76931c24a2c49dd9ee521d508bf824d76fa34a6b6bbfb77dee2424c6fd8929b26bf4156967250619fe9578acfe3615facdb3caf63de6c92db645865004d9d29
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@ Nemah is a library for calculating the proper amount of fodder for your horse. I
|
|
4
4
|
|
5
5
|
## Requirements
|
6
6
|
|
7
|
-
Given that Nemah is an Arabian princess, she wants as many rubies as possible, but no fewer than 2.0.
|
7
|
+
Given that Nemah is an Arabian princess, she wants as many rubies as possible, but no fewer than 2.0. Thus MRI and JRuby are supported, whereas Rubinius needs to [add support for keyword arguments](https://github.com/rubinius/rubinius/issues/2669).
|
8
8
|
|
9
9
|
## Installation.
|
10
10
|
|
@@ -22,18 +22,18 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
###
|
25
|
+
### Currently implemented functionality
|
26
26
|
|
27
|
-
* Calculate a horse's need of energy, protein, solids, macrominerals, and selenium.
|
27
|
+
* Calculate a working horse's need of energy, protein, solids, macrominerals, and selenium.
|
28
28
|
* Calculations are made internally with at least three digits precision. Public methods will return values rounded to two decimals by default.
|
29
|
+
* Balances, e.g. calcium-phosphor, protein-energy etc.
|
30
|
+
* Rations, i.e. given a horse with a need, and a fodder list, does the horse get enough nutrients in proper balances?
|
29
31
|
|
30
32
|
### Yet to be implemented
|
31
33
|
|
32
|
-
* Microminerals apart from selenium
|
33
|
-
* Balances
|
34
|
-
* Fodder
|
35
|
-
* Rations
|
34
|
+
* Microminerals and their specific balances apart from selenium.
|
36
35
|
* Given a horse, its needs, and a list of fodder, calculate suitable rations.
|
36
|
+
* Support horses with very specific needs, e.g. mares with foals, young horses, race horses etc.
|
37
37
|
|
38
38
|
## Contributing
|
39
39
|
|
data/lib/nemah.rb
CHANGED
data/lib/nemah/amount.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nemah
|
2
|
+
class Amount
|
3
|
+
attr_reader :unit
|
4
|
+
|
5
|
+
def initialize(value, unit)
|
6
|
+
@value = value
|
7
|
+
@unit = unit
|
8
|
+
end
|
9
|
+
|
10
|
+
def value(specified_unit = unit)
|
11
|
+
if specified_unit == :kg && unit == :percent_per_kg
|
12
|
+
@value / 100.0
|
13
|
+
else
|
14
|
+
@value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/nemah/fodder.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Nemah
|
2
|
+
class Fodder
|
3
|
+
attr_reader :name, *Nemah::Nutrients.names
|
4
|
+
|
5
|
+
def initialize(name, nutrients = {})
|
6
|
+
@name = name
|
7
|
+
set_nutrients nutrients
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def set_nutrients(nutrients)
|
13
|
+
Nemah::Nutrients.default_input_unit_mappings.each do |nutrient, unit|
|
14
|
+
instance_variable_set "@#{nutrient}", Nemah::Amount.new(nutrients.fetch(nutrient, 0.0), unit)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Nemah
|
2
|
+
class FodderList
|
3
|
+
def initialize(fodders = {})
|
4
|
+
self.fodders = Hash.new(0).merge fodders
|
5
|
+
end
|
6
|
+
|
7
|
+
def count
|
8
|
+
fodders.count
|
9
|
+
end
|
10
|
+
|
11
|
+
def amount_of(fodder)
|
12
|
+
fodders[fodder]
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(fodder, amount = 0)
|
16
|
+
fodders[fodder] += amount
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def remove(fodder, amount = :not_specified)
|
21
|
+
(amount == :not_specified) ? remove_fodder(fodder) : reduce_fodder(fodder, amount)
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_h
|
26
|
+
fodders.dup
|
27
|
+
end
|
28
|
+
|
29
|
+
def each(&block)
|
30
|
+
fodders.each &block
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_accessor :fodders
|
36
|
+
|
37
|
+
def reduce_fodder(fodder, amount)
|
38
|
+
fodders[fodder] = [fodders[fodder] - amount, 0].max
|
39
|
+
end
|
40
|
+
|
41
|
+
def remove_fodder(fodder)
|
42
|
+
fodders.delete_if { |key, _| key == fodder }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Nemah
|
2
|
+
class Nutrients
|
3
|
+
def self.default_input_unit_mappings
|
4
|
+
{
|
5
|
+
calcium: :g,
|
6
|
+
energy: :MJ,
|
7
|
+
magnesium: :g,
|
8
|
+
phosphor: :g,
|
9
|
+
protein: :g,
|
10
|
+
salt: :g,
|
11
|
+
selenium: :mg,
|
12
|
+
solids: :percent_per_kg
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.names
|
17
|
+
default_input_unit_mappings.keys
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/nemah/ration.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module Nemah
|
2
|
+
class Ration
|
3
|
+
attr_reader :fodder_list, :need
|
4
|
+
|
5
|
+
def initialize(need, fodder_list)
|
6
|
+
@need = need
|
7
|
+
@fodder_list = fodder_list
|
8
|
+
end
|
9
|
+
|
10
|
+
def balance(first_nutrient, second_nutrient)
|
11
|
+
total(first_nutrient) / total(second_nutrient)
|
12
|
+
end
|
13
|
+
|
14
|
+
def calcium_magnesium_in_balance?
|
15
|
+
(2.0..3.0).include? balance(:calcium, :magnesium)
|
16
|
+
end
|
17
|
+
|
18
|
+
def calcium_phosphor_in_balance?
|
19
|
+
(1.2..1.8).include? balance(:calcium, :phosphor)
|
20
|
+
end
|
21
|
+
|
22
|
+
def protein_energy_in_balance?
|
23
|
+
balance(:protein, :energy) >= 6.0
|
24
|
+
end
|
25
|
+
|
26
|
+
Nemah::Nutrients.names.each do |nutrient| # def enough_nutrient?
|
27
|
+
define_method("enough_#{nutrient}?") { enough?(nutrient) } # enough?(:nutrient)
|
28
|
+
end # end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def enough?(nutrient)
|
33
|
+
need.public_send(nutrient).min <= total(nutrient)
|
34
|
+
end
|
35
|
+
|
36
|
+
def total(nutrient)
|
37
|
+
fodder_list.each.inject(0) do |total, (fodder, amount)|
|
38
|
+
total += amount * fodder.public_send(nutrient).value(need.public_send(nutrient).unit)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/nemah/version.rb
CHANGED
data/nemah.gemspec
CHANGED
@@ -19,7 +19,6 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
-
spec.add_development_dependency 'byebug', '~> 2.5'
|
23
22
|
spec.add_development_dependency 'guard', '~> 2.2'
|
24
23
|
spec.add_development_dependency 'guard-rspec', '~> 4.2'
|
25
24
|
spec.add_development_dependency 'rake', '~> 10.1'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nemah::Amount do
|
4
|
+
describe '#unit' do
|
5
|
+
it 'returns the unit portion of the amount' do
|
6
|
+
amount = Nemah::Amount.new(5.5, :kg)
|
7
|
+
expect(amount.unit).to eq :kg
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#value' do
|
12
|
+
it 'returns the value portion of the amount' do
|
13
|
+
amount = Nemah::Amount.new(5.5, :kg)
|
14
|
+
expect(amount.value).to eq 5.5
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'can convert from percent of kilograms to kilograms' do
|
18
|
+
amount = Nemah::Amount.new(60.0, :percent_per_kg)
|
19
|
+
expect(amount.value(:kg)).to eq 0.60
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nemah::FodderList do
|
4
|
+
let(:fodder) { Nemah::Fodder.new('hay') }
|
5
|
+
|
6
|
+
it 'contains no fodders by default' do
|
7
|
+
fodder_list = build_fodder_list
|
8
|
+
expect(fodder_list.count).to eq 0
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#amount_of' do
|
12
|
+
it 'returns the amount of a given fodder' do
|
13
|
+
fodder_list = build_fodder_list(fodder => 5)
|
14
|
+
expect(fodder_list.amount_of fodder).to eq 5
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns zero if the fodder is not in the list' do
|
18
|
+
fodder_list = build_fodder_list
|
19
|
+
expect(fodder_list.amount_of :non_existing_fodder).to eq 0
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#add' do
|
24
|
+
subject(:fodder_list) { build_fodder_list }
|
25
|
+
|
26
|
+
it 'adds a fodder to the list' do
|
27
|
+
fodder_list.add fodder
|
28
|
+
expect(fodder_list.count).to eq 1
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'adds a specified amount of fodder to the list' do
|
32
|
+
fodder_list.add fodder, 0.5
|
33
|
+
expect(fodder_list.amount_of fodder).to eq 0.5
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'increases the amount of a fodder already in the list' do
|
37
|
+
fodder_list.add fodder, 1
|
38
|
+
fodder_list.add fodder, 2
|
39
|
+
expect(fodder_list.amount_of fodder).to eq 3
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns the fodder list' do
|
43
|
+
expect(fodder_list.add(fodder, 0.5)).to eq fodder_list
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#remove' do
|
48
|
+
subject(:fodder_list) { build_fodder_list(fodder => 5) }
|
49
|
+
|
50
|
+
it 'removes the fodder from the list if no amount is specified' do
|
51
|
+
fodder_list.remove fodder
|
52
|
+
expect(fodder_list.count).to eq 0
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'removes the given amount of a fodder, without removing the fodder from the list' do
|
56
|
+
fodder_list.remove(fodder, 1.5)
|
57
|
+
expect(fodder_list.amount_of fodder).to eq 3.5
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not reduce the amount below zero' do
|
61
|
+
fodder_list.remove(fodder, 100)
|
62
|
+
expect(fodder_list.amount_of fodder).to eq 0
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'returns the fodder list' do
|
66
|
+
expect(fodder_list.remove fodder).to eq fodder_list
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#to_h' do
|
71
|
+
let(:fodders) { { fodder => 10.0 } }
|
72
|
+
subject(:fodder_list) { build_fodder_list(fodders) }
|
73
|
+
|
74
|
+
it 'returns a hash representation of the list' do
|
75
|
+
expect(fodder_list.to_h).to eq fodders
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'changing the hash does not change the fodder list' do
|
79
|
+
fodder_list.to_h[fodder] = 0
|
80
|
+
expect(fodder_list.amount_of(fodder)).to eq 10.0
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#each' do
|
85
|
+
subject(:fodder_list) { build_fodder_list(fodder => 5.0) }
|
86
|
+
|
87
|
+
it 'returns an enumerator for the list when not given a block' do
|
88
|
+
expect(fodder_list.each.next).to eq [fodder, 5.0]
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'yields the fodder and amount pairs in the list when given a block' do
|
92
|
+
yielded_fodder_and_amount = :not_set
|
93
|
+
fodder_list.each { |fodder_and_amount| yielded_fodder_and_amount = fodder_and_amount }
|
94
|
+
|
95
|
+
expect(yielded_fodder_and_amount).to eq [fodder, 5.0]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def build_fodder_list(fodders = {})
|
101
|
+
Nemah::FodderList.new(fodders)
|
102
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'a nutrient' do
|
4
|
+
it 'returns 0.0 by default' do
|
5
|
+
expect(build_fodder.send(nutrient).value).to eq 0.0
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'returns the amount of the nutrient' do
|
9
|
+
fodder = build_fodder(nutrient => 1.5)
|
10
|
+
expect(fodder.send(nutrient).value).to eq 1.5
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns the nutrient unit' do
|
14
|
+
fodder = build_fodder(nutrient => 1.5)
|
15
|
+
expect(fodder.send(nutrient).unit).to eq unit
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Nemah::Fodder do
|
20
|
+
def build_fodder(nutrients = {})
|
21
|
+
Nemah::Fodder.new('hay', nutrients)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'has a name' do
|
25
|
+
expect(build_fodder.name).to eq 'hay'
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#calcium' do
|
29
|
+
it_behaves_like 'a nutrient' do
|
30
|
+
let(:nutrient) { :calcium }
|
31
|
+
let(:unit) { :g }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#energy' do
|
36
|
+
it_behaves_like 'a nutrient' do
|
37
|
+
let(:nutrient) { :energy }
|
38
|
+
let(:unit) { :MJ }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#magnesium' do
|
43
|
+
it_behaves_like 'a nutrient' do
|
44
|
+
let(:nutrient) { :magnesium }
|
45
|
+
let(:unit) { :g }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#phosphor' do
|
50
|
+
it_behaves_like 'a nutrient' do
|
51
|
+
let(:nutrient) { :phosphor }
|
52
|
+
let(:unit) { :g }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#protein' do
|
57
|
+
it_behaves_like 'a nutrient' do
|
58
|
+
let(:nutrient) { :protein }
|
59
|
+
let(:unit) { :g }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#salt' do
|
64
|
+
it_behaves_like 'a nutrient' do
|
65
|
+
let(:nutrient) { :salt }
|
66
|
+
let(:unit) { :g }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#selenium' do
|
71
|
+
it_behaves_like 'a nutrient' do
|
72
|
+
let(:nutrient) { :selenium }
|
73
|
+
let(:unit) { :mg }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#solids' do
|
78
|
+
it_behaves_like 'a nutrient' do
|
79
|
+
let(:nutrient) { :solids }
|
80
|
+
let(:unit) { :percent_per_kg }
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'returns the amount of solids in kilograms if specified' do
|
84
|
+
fodder = build_fodder(solids: 67.5)
|
85
|
+
expect(fodder.solids.value(:kg)).to eq 0.675
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'a nutrient requirement' do
|
4
|
+
it "returns true when the horse's nutrient need is met" do
|
5
|
+
expect(ration.public_send("enough_#{nutrient}?")).to be_true
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'returns false when the nutrient need is not met' do
|
9
|
+
expect(ration(0.1).public_send("enough_#{nutrient}?")).to be_false
|
10
|
+
end
|
11
|
+
|
12
|
+
def ration(modifier = 0)
|
13
|
+
nutrient_need = double(nutrient.to_s, min: nutrient_min + modifier, unit: nutrient_unit)
|
14
|
+
need = double('need', nutrient => nutrient_need)
|
15
|
+
fodder_list = Nemah::FodderList.new(fodders)
|
16
|
+
ration = Nemah::Ration.new(need, fodder_list)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Nemah::Ration do
|
21
|
+
describe '#enough_calcium?' do
|
22
|
+
it_behaves_like 'a nutrient requirement' do
|
23
|
+
let(:nutrient) { :calcium }
|
24
|
+
let(:nutrient_min) { 35.6 }
|
25
|
+
let(:nutrient_unit) { :g }
|
26
|
+
let(:fodders) { { Nemah::Fodder.new('hay', { nutrient => 3.56 }) => 10 } }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#enough_energy?' do
|
31
|
+
it_behaves_like 'a nutrient requirement' do
|
32
|
+
let(:nutrient) { :energy }
|
33
|
+
let(:nutrient_min) { 65 }
|
34
|
+
let(:nutrient_unit) { :MJ }
|
35
|
+
let(:fodders) { { Nemah::Fodder.new('hay', { nutrient => 6.5 }) => 10 } }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#enough_magnesium?' do
|
40
|
+
it_behaves_like 'a nutrient requirement' do
|
41
|
+
let(:nutrient) { :magnesium }
|
42
|
+
let(:nutrient_min) { 25 }
|
43
|
+
let(:nutrient_unit) { :g }
|
44
|
+
let(:fodders) { { Nemah::Fodder.new('hay', { nutrient => 2.5 }) => 10 } }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#enough_phosphor?' do
|
49
|
+
it_behaves_like 'a nutrient requirement' do
|
50
|
+
let(:nutrient) { :phosphor }
|
51
|
+
let(:nutrient_min) { 24.4 }
|
52
|
+
let(:nutrient_unit) { :g }
|
53
|
+
let(:fodders) { { Nemah::Fodder.new('hay', { nutrient => 2.44 }) => 10 } }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#enough_protein?' do
|
58
|
+
it_behaves_like 'a nutrient requirement' do
|
59
|
+
let(:nutrient) { :protein }
|
60
|
+
let(:nutrient_min) { 330 }
|
61
|
+
let(:nutrient_unit) { :g }
|
62
|
+
let(:fodders) { { Nemah::Fodder.new('hay', { nutrient => 33 }) => 10 } }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#enough_salt?' do
|
67
|
+
it_behaves_like 'a nutrient requirement' do
|
68
|
+
let(:nutrient) { :salt }
|
69
|
+
let(:nutrient_min) { 7.8 }
|
70
|
+
let(:nutrient_unit) { :g }
|
71
|
+
let(:fodders) { { Nemah::Fodder.new('hay', { nutrient => 0.78 }) => 10 } }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#enough_selenium?' do
|
76
|
+
it_behaves_like 'a nutrient requirement' do
|
77
|
+
let(:nutrient) { :selenium }
|
78
|
+
let(:nutrient_min) { 12.1 }
|
79
|
+
let(:nutrient_unit) { :mg }
|
80
|
+
let(:fodders) { { Nemah::Fodder.new('hay', { nutrient => 1.21 }) => 10 } }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#enough_solids?' do
|
85
|
+
it_behaves_like 'a nutrient requirement' do
|
86
|
+
let(:nutrient) { :solids }
|
87
|
+
let(:nutrient_min) { 7 }
|
88
|
+
let(:nutrient_unit) { :kg }
|
89
|
+
let(:fodders) { { Nemah::Fodder.new('hay', { nutrient => 70 }) => 10 } }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
shared_examples_for 'a balance' do
|
94
|
+
let(:need) do
|
95
|
+
double('fake_need',
|
96
|
+
first_nutrient.name => double(first_nutrient.name.to_s, unit: first_nutrient.unit),
|
97
|
+
second_nutrient.name => double(second_nutrient.name.to_s, unit: second_nutrient.unit))
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'returns true when the ratio is the lowest allowed' do
|
101
|
+
expect(ration(allowed.first).public_send("#{balance}_in_balance?")).to be_true
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'returns true when the ratio is the highest allowed' do
|
105
|
+
expect(ration(allowed.last).public_send("#{balance}_in_balance?")).to be_true
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'returns false when the ratio is below the allowed range' do
|
109
|
+
expect(ration(allowed.first - 0.01).public_send("#{balance}_in_balance?")).to be_false
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'returns false when the ratio is above the allowed range' do
|
113
|
+
expect(ration(allowed.last + 0.01).public_send("#{balance}_in_balance?")).to be_false
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def ration(value)
|
119
|
+
fodder_list = Nemah::FodderList.new({ Nemah::Fodder.new('hay', { first_nutrient.name => value, second_nutrient.name => 1 }) => 5 })
|
120
|
+
Nemah::Ration.new(need, fodder_list)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '#calcium_magnesium_in_balance?' do
|
125
|
+
it_behaves_like 'a balance' do
|
126
|
+
let(:balance) { :calcium_magnesium }
|
127
|
+
let(:first_nutrient) { double(name: :calcium, unit: :g) }
|
128
|
+
let(:second_nutrient) { double(name: :magnesium, unit: :g) }
|
129
|
+
let(:allowed) { 2.0..3.0 }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe '#calcium_phosphor_in_balance?' do
|
134
|
+
it_behaves_like 'a balance' do
|
135
|
+
let(:balance) { :calcium_phosphor }
|
136
|
+
let(:first_nutrient) { double(name: :calcium, unit: :g) }
|
137
|
+
let(:second_nutrient) { double(name: :phosphor, unit: :g) }
|
138
|
+
let(:allowed) { 1.2..1.8 }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe '#protein_energy_in_balance?' do
|
143
|
+
it 'returns true when at least 6g protein per MJ energy' do
|
144
|
+
expect(ration(protein: 6.0).protein_energy_in_balance?).to be_true
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'returns false when less than 6g protein per MJ energy' do
|
148
|
+
expect(ration(protein: 5.9).protein_energy_in_balance?).to be_false
|
149
|
+
end
|
150
|
+
|
151
|
+
def ration(protein: :not_specified)
|
152
|
+
need = double('fake_need', energy: double('energy', unit: :MJ), protein: double('protein', unit: :g))
|
153
|
+
fodder_list = Nemah::FodderList.new({ Nemah::Fodder.new('hay', { :energy => 1, :protein => protein }) => 5 })
|
154
|
+
ration = Nemah::Ration.new(need, fodder_list)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe 'balance' do
|
159
|
+
it 'returns the calcium-magnesium balance' do
|
160
|
+
expect(ration.balance(:calcium, :magnesium)).to eq 1.3
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'returns the calcium-phosphor balance' do
|
164
|
+
expect(ration.balance(:calcium, :phosphor)).to eq 2.0
|
165
|
+
end
|
166
|
+
|
167
|
+
def ration
|
168
|
+
need = double('fake_need', calcium: double('calcium', unit: :g), magnesium: double('magnesium', unit: :g), phosphor: double('phosphor', unit: :g))
|
169
|
+
fodder_list = Nemah::FodderList.new({ Nemah::Fodder.new('hay', { calcium: 2.6, magnesium: 2.0, phosphor: 1.3 }) => 5 })
|
170
|
+
Nemah::Ration.new(need, fodder_list)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class FakeNeed < Nemah::SpecificNeed::AbstractNeed
|
4
|
+
def min
|
5
|
+
78.67
|
6
|
+
end
|
7
|
+
|
8
|
+
def unit
|
9
|
+
'ghostscreams'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Nemah::SpecificNeed::AbstractNeed do
|
14
|
+
describe '#to_s' do
|
15
|
+
let(:fake_need) { FakeNeed.new(double) }
|
16
|
+
|
17
|
+
it 'combines the minimum need with the unit' do
|
18
|
+
expect(fake_need.to_s).to eq '78.67 ghostscreams'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
shared_examples_for 'a specific need' do
|
2
|
-
subject(:
|
2
|
+
subject(:specific_need) { described_class.new(double('need for a horse')) }
|
3
3
|
|
4
4
|
describe 'the common interface' do
|
5
5
|
it { should respond_to(:to_rounded_range) }
|
@@ -8,5 +8,5 @@ shared_examples_for 'a specific need' do
|
|
8
8
|
it { should respond_to(:max) }
|
9
9
|
end
|
10
10
|
|
11
|
-
specify { expect(
|
11
|
+
specify { expect(specific_need.unit).to eq unit }
|
12
12
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nemah
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kim Persson
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-02-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -25,20 +25,6 @@ dependencies:
|
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '1.3'
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
name: byebug
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
31
|
-
requirements:
|
32
|
-
- - "~>"
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version: '2.5'
|
35
|
-
type: :development
|
36
|
-
prerelease: false
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - "~>"
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
version: '2.5'
|
42
28
|
- !ruby/object:Gem::Dependency
|
43
29
|
name: guard
|
44
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,8 +98,13 @@ files:
|
|
112
98
|
- README.md
|
113
99
|
- Rakefile
|
114
100
|
- lib/nemah.rb
|
101
|
+
- lib/nemah/amount.rb
|
102
|
+
- lib/nemah/fodder.rb
|
103
|
+
- lib/nemah/fodder_list.rb
|
115
104
|
- lib/nemah/horse.rb
|
116
105
|
- lib/nemah/need.rb
|
106
|
+
- lib/nemah/nutrients.rb
|
107
|
+
- lib/nemah/ration.rb
|
117
108
|
- lib/nemah/specific_need/abstract_need.rb
|
118
109
|
- lib/nemah/specific_need/calcium.rb
|
119
110
|
- lib/nemah/specific_need/energy.rb
|
@@ -127,8 +118,13 @@ files:
|
|
127
118
|
- lib/nemah/version.rb
|
128
119
|
- lib/nemah/workload.rb
|
129
120
|
- nemah.gemspec
|
121
|
+
- spec/nemah/amount_spec.rb
|
122
|
+
- spec/nemah/fodder_list_spec.rb
|
123
|
+
- spec/nemah/fodder_spec.rb
|
130
124
|
- spec/nemah/horse_spec.rb
|
131
125
|
- spec/nemah/need_spec.rb
|
126
|
+
- spec/nemah/ration_spec.rb
|
127
|
+
- spec/nemah/specific_need/abstract_need_spec.rb
|
132
128
|
- spec/nemah/specific_need/calcium_spec.rb
|
133
129
|
- spec/nemah/specific_need/energy_spec.rb
|
134
130
|
- spec/nemah/specific_need/magnesium_spec.rb
|
@@ -161,13 +157,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
157
|
version: '0'
|
162
158
|
requirements: []
|
163
159
|
rubyforge_project:
|
164
|
-
rubygems_version: 2.2.0
|
160
|
+
rubygems_version: 2.2.0.rc.1
|
165
161
|
signing_key:
|
166
162
|
specification_version: 4
|
167
163
|
summary: Horse fodder calculations library.
|
168
164
|
test_files:
|
165
|
+
- spec/nemah/amount_spec.rb
|
166
|
+
- spec/nemah/fodder_list_spec.rb
|
167
|
+
- spec/nemah/fodder_spec.rb
|
169
168
|
- spec/nemah/horse_spec.rb
|
170
169
|
- spec/nemah/need_spec.rb
|
170
|
+
- spec/nemah/ration_spec.rb
|
171
|
+
- spec/nemah/specific_need/abstract_need_spec.rb
|
171
172
|
- spec/nemah/specific_need/calcium_spec.rb
|
172
173
|
- spec/nemah/specific_need/energy_spec.rb
|
173
174
|
- spec/nemah/specific_need/magnesium_spec.rb
|