nrb-beerxml 0.0.2
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 +7 -0
- data/LICENSE +674 -0
- data/README.md +33 -0
- data/lib/beerxml.rb +24 -0
- data/lib/beerxml/builder.rb +30 -0
- data/lib/beerxml/equipment.rb +38 -0
- data/lib/beerxml/fermentable.rb +33 -0
- data/lib/beerxml/hop.rb +38 -0
- data/lib/beerxml/inflector.rb +27 -0
- data/lib/beerxml/mash.rb +35 -0
- data/lib/beerxml/mash_step.rb +26 -0
- data/lib/beerxml/misc.rb +24 -0
- data/lib/beerxml/parser.rb +114 -0
- data/lib/beerxml/recipe.rb +109 -0
- data/lib/beerxml/record.rb +49 -0
- data/lib/beerxml/record_set.rb +39 -0
- data/lib/beerxml/record_validators.rb +8 -0
- data/lib/beerxml/record_validators/boolean_validator.rb +16 -0
- data/lib/beerxml/record_validators/percentage_validator.rb +38 -0
- data/lib/beerxml/style.rb +49 -0
- data/lib/beerxml/version.rb +6 -0
- data/lib/beerxml/water.rb +26 -0
- data/lib/beerxml/yeast.rb +38 -0
- data/spec/cases/beerxml/builder_spec.rb +107 -0
- data/spec/cases/beerxml/equipment_spec.rb +38 -0
- data/spec/cases/beerxml/fermentable_spec.rb +17 -0
- data/spec/cases/beerxml/hop_spec.rb +21 -0
- data/spec/cases/beerxml/mash_spec.rb +25 -0
- data/spec/cases/beerxml/mash_step_spec.rb +39 -0
- data/spec/cases/beerxml/misc_spec.rb +14 -0
- data/spec/cases/beerxml/parser_spec.rb +30 -0
- data/spec/cases/beerxml/recipe_spec.rb +98 -0
- data/spec/cases/beerxml/record_set_spec.rb +36 -0
- data/spec/cases/beerxml/record_spec.rb +15 -0
- data/spec/cases/beerxml/record_validators/boolean_validator_spec.rb +50 -0
- data/spec/cases/beerxml/record_validators/percentage_validator_spec.rb +98 -0
- data/spec/cases/beerxml/style_spec.rb +36 -0
- data/spec/cases/beerxml/version_spec.rb +13 -0
- data/spec/cases/beerxml/water_spec.rb +25 -0
- data/spec/cases/beerxml/yeast_spec.rb +20 -0
- data/spec/cases/beerxml_spec.rb +3 -0
- data/spec/fixtures/equipment.xml +28 -0
- data/spec/fixtures/recipes.xml +1412 -0
- data/spec/shared/active_model_lint.rb +21 -0
- data/spec/shared/record_typing.rb +19 -0
- data/spec/spec_helper.rb +8 -0
- metadata +210 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'shared/active_model_lint'
|
2
|
+
|
3
|
+
describe NRB::BeerXML::Hop do
|
4
|
+
|
5
|
+
it_behaves_like :ActiveModel
|
6
|
+
|
7
|
+
it { should validate_presence_of :alpha }
|
8
|
+
it { should validate_presence_of :amount }
|
9
|
+
it { should validate_presence_of :time }
|
10
|
+
it { should validate_presence_of :use }
|
11
|
+
|
12
|
+
it { should validate_inclusion_of(:form).in_array( ["Leaf", "Pellet", "Plug"] ) }
|
13
|
+
|
14
|
+
it { should validate_numericality_of(:amount).is_greater_than_or_equal_to(0) }
|
15
|
+
it { should validate_inclusion_of(:type).in_array(%w(Aroma Bittering Both) ) }
|
16
|
+
it { should validate_inclusion_of(:use).in_array( [ "Aroma", "Boil", "Dry Hop", "First Wort", "Mash" ] ) }
|
17
|
+
|
18
|
+
it { should validate_numericality_of(:time).is_greater_than_or_equal_to(0) }
|
19
|
+
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'shared/active_model_lint'
|
2
|
+
describe NRB::BeerXML::Mash do
|
3
|
+
|
4
|
+
it_behaves_like :ActiveModel
|
5
|
+
|
6
|
+
it { should validate_presence_of :grain_temp }
|
7
|
+
it { should validate_presence_of :mash_steps }
|
8
|
+
|
9
|
+
it { should validate_numericality_of :grain_temp }
|
10
|
+
it { should validate_numericality_of(:ph).is_greater_than_or_equal_to(0).is_less_than_or_equal_to(14) }
|
11
|
+
it { should validate_numericality_of :sparge_temp }
|
12
|
+
it { should validate_numericality_of(:tun_specific_heat).is_greater_than_or_equal_to(0) }
|
13
|
+
it { should validate_numericality_of :tun_temp }
|
14
|
+
it { should validate_numericality_of(:tun_weight).is_greater_than_or_equal_to(0) }
|
15
|
+
|
16
|
+
|
17
|
+
it 'should start with empty mash steps' do
|
18
|
+
expect( subject.mash_steps ).to be_a(NRB::BeerXML::RecordSet)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'mash steps should be a RecordSet of mash_steps' do
|
22
|
+
expect( subject.mash_steps.record_type ).to eq :mash_step
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'shared/active_model_lint'
|
2
|
+
|
3
|
+
describe NRB::BeerXML::MashStep do
|
4
|
+
|
5
|
+
it_behaves_like :ActiveModel
|
6
|
+
|
7
|
+
let(:subject) { described_class.new type: type }
|
8
|
+
let(:type) { "Temperature" }
|
9
|
+
|
10
|
+
it { should validate_presence_of(:step_temp) }
|
11
|
+
it { should validate_presence_of(:step_time) }
|
12
|
+
it { should validate_presence_of(:type) }
|
13
|
+
|
14
|
+
it { should validate_inclusion_of(:type).in_array(%w(Decoction Infusion Temperature)) }
|
15
|
+
|
16
|
+
it { should validate_numericality_of(:end_temp) }
|
17
|
+
it { should validate_numericality_of(:infuse_amount) }
|
18
|
+
it { should validate_numericality_of(:ramp_time).is_greater_than_or_equal_to(0) }
|
19
|
+
it { should validate_numericality_of(:step_temp) }
|
20
|
+
it { should validate_numericality_of(:step_time).is_greater_than_or_equal_to(0) }
|
21
|
+
|
22
|
+
context "Decoction steps" do
|
23
|
+
let(:type) { "Decoction" }
|
24
|
+
it { should_not validate_presence_of :infuse_amount }
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
context "Infusion steps" do
|
29
|
+
let(:type) { "Infusion" }
|
30
|
+
it { should validate_presence_of :infuse_amount }
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
context "Temperature steps" do
|
35
|
+
let(:type) { "Temperature" }
|
36
|
+
it { should_not validate_presence_of :infuse_amount }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
describe NRB::BeerXML::Misc do
|
2
|
+
|
3
|
+
it { should validate_presence_of :amount }
|
4
|
+
it { should validate_presence_of :time }
|
5
|
+
it { should validate_presence_of :type }
|
6
|
+
it { should validate_presence_of :use }
|
7
|
+
|
8
|
+
it { should validate_numericality_of(:amount).is_greater_than_or_equal_to(0) }
|
9
|
+
it { should validate_numericality_of(:time).is_greater_than_or_equal_to(0) }
|
10
|
+
|
11
|
+
it { should validate_inclusion_of(:type).in_array(["Fining", "Flavor", "Herb", "Other", "Spice", "Water Agent"]) }
|
12
|
+
it { should validate_inclusion_of(:use).in_array(%w(Boil Bottling Mash Primary Secondary)) }
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
describe NRB::BeerXML::Parser do
|
2
|
+
|
3
|
+
context 'Parsing' do
|
4
|
+
|
5
|
+
let(:base_dir) { File.expand_path File.join('..','..','..'), __FILE__ }
|
6
|
+
let(:fixture_dir) { File.join base_dir,'fixtures' }
|
7
|
+
let(:fixture_path) { File.join fixture_dir, 'recipes.xml' }
|
8
|
+
|
9
|
+
it 'does not raise error when parsing a path name' do
|
10
|
+
expect { subject.parse fixture_path }.to_not raise_error
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
it 'does not raise error when parsing a stream' do
|
15
|
+
expect { subject.parse File.open(fixture_path) }.to_not raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
it 'raises an error when parsing something else' do
|
20
|
+
expect { subject.parse Array.new }.to raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
it 'returns a NRB::BeerXML::Parser' do
|
25
|
+
expect( subject.parse fixture_path ).to be_a(NRB::BeerXML::RecordSet)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'shared/active_model_lint'
|
2
|
+
|
3
|
+
describe NRB::BeerXML::Recipe do
|
4
|
+
|
5
|
+
it_behaves_like :ActiveModel
|
6
|
+
|
7
|
+
it { should_not validate_presence_of :age }
|
8
|
+
it { should_not validate_presence_of :age_temp }
|
9
|
+
it { should_not validate_presence_of :asst_brewer }
|
10
|
+
it { should validate_presence_of :batch_size }
|
11
|
+
it { should validate_presence_of :boil_size }
|
12
|
+
it { should validate_presence_of :boil_time }
|
13
|
+
it { should validate_presence_of :brewer }
|
14
|
+
it { should_not validate_presence_of :carbonation }
|
15
|
+
it { should_not validate_presence_of :carbonation_temp }
|
16
|
+
it { should_not validate_presence_of :date }
|
17
|
+
it { should validate_presence_of :equipment }
|
18
|
+
it { should validate_presence_of :fermentables }
|
19
|
+
it { should_not validate_presence_of :fermentation_stages }
|
20
|
+
it { should_not validate_presence_of :fg }
|
21
|
+
it { should_not validate_presence_of :forced_carbonation }
|
22
|
+
it { should validate_presence_of :hops }
|
23
|
+
it { should_not validate_presence_of :keg_priming_factor }
|
24
|
+
it { should validate_presence_of :mash }
|
25
|
+
it { should validate_presence_of :miscs }
|
26
|
+
it { should_not validate_presence_of :notes }
|
27
|
+
it { should_not validate_presence_of :og }
|
28
|
+
it { should_not validate_presence_of :primary_age }
|
29
|
+
it { should_not validate_presence_of :primary_temp }
|
30
|
+
it { should_not validate_presence_of :priming_sugar_equiv }
|
31
|
+
it { should_not validate_presence_of :priming_sugar_name }
|
32
|
+
it { should_not validate_presence_of :secondary_age }
|
33
|
+
it { should_not validate_presence_of :secondary_temp }
|
34
|
+
it { should validate_presence_of :style }
|
35
|
+
it { should_not validate_presence_of :taste_notes }
|
36
|
+
it { should_not validate_presence_of :taste_rating }
|
37
|
+
it { should_not validate_presence_of :tertiary_age }
|
38
|
+
it { should_not validate_presence_of :tertiary_temp }
|
39
|
+
it { should validate_presence_of :type }
|
40
|
+
it { should validate_presence_of :waters }
|
41
|
+
it { should validate_presence_of :yeasts }
|
42
|
+
|
43
|
+
it { should validate_inclusion_of(:type).in_array([ "All Grain", "Extract", "Partial Mash" ]) }
|
44
|
+
|
45
|
+
it { should validate_numericality_of(:age).is_greater_than_or_equal_to(0) }
|
46
|
+
it { should validate_numericality_of(:age_temp) }
|
47
|
+
it { should validate_numericality_of(:batch_size).is_greater_than_or_equal_to(0) }
|
48
|
+
it { should validate_numericality_of(:boil_size).is_greater_than_or_equal_to(0) }
|
49
|
+
it { should validate_numericality_of(:boil_time).is_greater_than_or_equal_to(0) }
|
50
|
+
it { should validate_numericality_of(:carbonation).is_greater_than_or_equal_to(0) }
|
51
|
+
it { should validate_numericality_of(:carbonation_temp) }
|
52
|
+
it { should validate_numericality_of(:fermentation_stages).only_integer }
|
53
|
+
it { should validate_numericality_of(:fg) }
|
54
|
+
it { should validate_numericality_of(:og) }
|
55
|
+
it { should validate_numericality_of(:primary_age).is_greater_than_or_equal_to(0) }
|
56
|
+
it { should validate_numericality_of(:primary_temp) }
|
57
|
+
it { should validate_numericality_of(:secondary_age).is_greater_than_or_equal_to(0) }
|
58
|
+
it { should validate_numericality_of(:secondary_temp) }
|
59
|
+
it { should validate_numericality_of(:tertiary_age).is_greater_than_or_equal_to(0) }
|
60
|
+
it { should validate_numericality_of(:tertiary_temp) }
|
61
|
+
|
62
|
+
|
63
|
+
%i(fermentable hop misc water yeast).each do |record_type|
|
64
|
+
it "#{record_type}s should be a RecordSet" do
|
65
|
+
expect(subject.send("#{record_type}s")).to be_a(NRB::BeerXML::RecordSet)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "its #{record_type}s RecordSet should be of type #{record_type}" do
|
69
|
+
expect(subject.send("#{record_type}s").record_type).to eq record_type
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
shared_examples_for :restricted_assignment do
|
75
|
+
it "allows assignment of the correct type" do
|
76
|
+
expect{ subject.send("#{record_type}=", good) }.to_not raise_exception
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'disallows non-Styles' do
|
80
|
+
expect{ subject.send("#{record_type}=", bad) }.to raise_exception
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "assigning equipment" do
|
85
|
+
let(:bad) { NRB::BeerXML::Hop.new }
|
86
|
+
let(:good) { NRB::BeerXML::Equipment.new }
|
87
|
+
let(:record_type) { :equipment }
|
88
|
+
it_behaves_like :restricted_assignment
|
89
|
+
end
|
90
|
+
|
91
|
+
context "assigning style" do
|
92
|
+
let(:bad) { NRB::BeerXML::Hop.new }
|
93
|
+
let(:good) { NRB::BeerXML::Style.new }
|
94
|
+
let(:record_type) { :style }
|
95
|
+
it_behaves_like :restricted_assignment
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
describe NRB::BeerXML::RecordSet do
|
2
|
+
|
3
|
+
context "initialization" do
|
4
|
+
|
5
|
+
described_class.valid_record_types.each do |record_type|
|
6
|
+
it "does not blow up given #{record_type}" do
|
7
|
+
expect { described_class.new record_type: record_type }.to_not raise_exception
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'blows up when given a blark' do
|
12
|
+
expect { described_class.new record_type: :blark }.to raise_exception
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
context 'adding records' do
|
19
|
+
|
20
|
+
let(:invalid_record) { NRB::BeerXML::Mash.new }
|
21
|
+
let(:record_set) { described_class.new record_type: record_type }
|
22
|
+
let(:record_type) { :hop }
|
23
|
+
let(:valid_record) { NRB::BeerXML::Hop.new }
|
24
|
+
|
25
|
+
it 'lets you add valid records' do
|
26
|
+
expect { record_set << valid_record }.to_not raise_exception
|
27
|
+
end
|
28
|
+
|
29
|
+
it "doesen't let you add invalid records" do
|
30
|
+
expect { record_set << inalid_record }.to raise_exception
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'shared/active_model_lint'
|
2
|
+
describe NRB::BeerXML::Record do
|
3
|
+
|
4
|
+
it { should validate_presence_of :name }
|
5
|
+
it { should validate_presence_of :version }
|
6
|
+
|
7
|
+
it { should validate_numericality_of(:version).only_integer }
|
8
|
+
|
9
|
+
it 'tells you its name' do
|
10
|
+
expect(subject.record_type).to be_a(Symbol)
|
11
|
+
end
|
12
|
+
|
13
|
+
it_behaves_like :ActiveModel
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'beerxml/record_validators/boolean_validator'
|
2
|
+
module NRB
|
3
|
+
module Fake
|
4
|
+
class FakeBooleanObject
|
5
|
+
include ActiveModel::Model
|
6
|
+
attr_accessor :boolean
|
7
|
+
validates :boolean, boolean: true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe NRB::BeerXML::RecordValidators::BooleanValidator do
|
13
|
+
|
14
|
+
shared_examples_for :a_borked_record do
|
15
|
+
|
16
|
+
it 'is invalid' do
|
17
|
+
expect(record).to_not be_valid
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'tells you why the record is invalid' do
|
21
|
+
record.valid?
|
22
|
+
expect(record.errors[:boolean]).to include('must be false or true')
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
let(:record) { NRB::Fake::FakeBooleanObject.new boolean: boolean }
|
29
|
+
|
30
|
+
|
31
|
+
context 'an invalid record' do
|
32
|
+
let(:boolean) { :false }
|
33
|
+
it_behaves_like :a_borked_record
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
context 'false is valid' do
|
38
|
+
let(:boolean) { false }
|
39
|
+
it { expect(record).to be_valid }
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
context 'true is valid' do
|
44
|
+
let(:boolean) { true }
|
45
|
+
it { expect(record).to be_valid }
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'beerxml/record_validators/percentage_validator'
|
2
|
+
module NRB
|
3
|
+
module Fake
|
4
|
+
class FakePercentage
|
5
|
+
include ActiveModel::Model
|
6
|
+
attr_accessor :percentage
|
7
|
+
end
|
8
|
+
class NoMaxFakePercentage < FakePercentage
|
9
|
+
validates :percentage, percentage: { give_110: true }
|
10
|
+
end
|
11
|
+
class NoMinFakePercentage < FakePercentage
|
12
|
+
validates :percentage, percentage: { allow_negative: true }
|
13
|
+
end
|
14
|
+
class VanillaFakePercentage < FakePercentage
|
15
|
+
validates :percentage, percentage: true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe NRB::BeerXML::RecordValidators::PercentageValidator do
|
21
|
+
|
22
|
+
let(:nan) { :a }
|
23
|
+
|
24
|
+
shared_examples_for :a_borked_record do
|
25
|
+
|
26
|
+
it 'is invalid' do
|
27
|
+
expect(record).to_not be_valid
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'tells you why the record is invalid' do
|
31
|
+
record.valid?
|
32
|
+
expect(record.errors[:percentage]).to include('must be a BeerXML percentage (a number between 0 & 100)')
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
shared_examples_for :rejects_nan do
|
39
|
+
let(:percentage) { nan }
|
40
|
+
it_behaves_like :a_borked_record
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
shared_examples_for :goldilocks do
|
45
|
+
let(:percentage) { okay }
|
46
|
+
it 'is valid' do
|
47
|
+
expect(record).to be_valid
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
shared_examples_for :rejects_large do
|
53
|
+
let(:percentage) { too_big }
|
54
|
+
it_behaves_like :a_borked_record
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
shared_examples_for :rejects_small do
|
59
|
+
let(:percentage) { too_small }
|
60
|
+
it_behaves_like :a_borked_record
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
context 'a vanilla percentage validator' do
|
65
|
+
let(:okay) { 88 }
|
66
|
+
let(:record) { NRB::Fake::VanillaFakePercentage.new percentage: percentage }
|
67
|
+
let(:too_big) { 101 }
|
68
|
+
let(:too_small) { -1 }
|
69
|
+
|
70
|
+
it_behaves_like :goldilocks
|
71
|
+
it_behaves_like :rejects_large
|
72
|
+
it_behaves_like :rejects_nan
|
73
|
+
it_behaves_like :rejects_small
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
context 'with no maximum' do
|
78
|
+
let(:okay) { 1000 }
|
79
|
+
let(:record) { NRB::Fake::NoMaxFakePercentage.new percentage: percentage }
|
80
|
+
let(:too_small) { -1 }
|
81
|
+
|
82
|
+
it_behaves_like :goldilocks
|
83
|
+
it_behaves_like :rejects_small
|
84
|
+
it_behaves_like :rejects_nan
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
context 'with no minimum' do
|
89
|
+
let(:okay) { -10 }
|
90
|
+
let(:record) { NRB::Fake::NoMinFakePercentage.new percentage: percentage }
|
91
|
+
let(:too_big) { 101 }
|
92
|
+
|
93
|
+
it_behaves_like :goldilocks
|
94
|
+
it_behaves_like :rejects_large
|
95
|
+
it_behaves_like :rejects_nan
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'shared/active_model_lint'
|
2
|
+
|
3
|
+
describe NRB::BeerXML::Style do
|
4
|
+
|
5
|
+
it_behaves_like :ActiveModel
|
6
|
+
|
7
|
+
it { should validate_presence_of :category }
|
8
|
+
it { should validate_presence_of :category_number }
|
9
|
+
it { should validate_presence_of :color_max }
|
10
|
+
it { should validate_presence_of :color_min }
|
11
|
+
it { should validate_presence_of :fg_max }
|
12
|
+
it { should validate_presence_of :fg_min }
|
13
|
+
it { should validate_presence_of :ibu_max }
|
14
|
+
it { should validate_presence_of :ibu_min }
|
15
|
+
it { should validate_presence_of :og_max }
|
16
|
+
it { should validate_presence_of :og_min }
|
17
|
+
it { should validate_presence_of :style_guide }
|
18
|
+
it { should validate_presence_of :style_letter }
|
19
|
+
it { should validate_presence_of :type }
|
20
|
+
|
21
|
+
it { should validate_inclusion_of(:type).in_array(%w(Ale Cider Lager Mead Mixed Wheat) ) }
|
22
|
+
|
23
|
+
it { should validate_numericality_of(:abv_max).is_greater_than_or_equal_to(0) }
|
24
|
+
it { should validate_numericality_of(:abv_min).is_greater_than_or_equal_to(0) }
|
25
|
+
it { should validate_numericality_of(:carb_max).is_greater_than_or_equal_to(0) }
|
26
|
+
it { should validate_numericality_of(:carb_min).is_greater_than_or_equal_to(0) }
|
27
|
+
it { should validate_numericality_of(:color_max).is_greater_than_or_equal_to(0) }
|
28
|
+
it { should validate_numericality_of(:color_min).is_greater_than_or_equal_to(0) }
|
29
|
+
it { should validate_numericality_of(:fg_max).is_greater_than_or_equal_to(0) }
|
30
|
+
it { should validate_numericality_of(:fg_min).is_greater_than_or_equal_to(0) }
|
31
|
+
it { should validate_numericality_of(:ibu_max).is_greater_than_or_equal_to(0) }
|
32
|
+
it { should validate_numericality_of(:ibu_min).is_greater_than_or_equal_to(0) }
|
33
|
+
it { should validate_numericality_of(:og_max).is_greater_than_or_equal_to(0) }
|
34
|
+
it { should validate_numericality_of(:og_min).is_greater_than_or_equal_to(0) }
|
35
|
+
|
36
|
+
end
|