fpm-cookery 0.32.0 → 0.33.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +5 -2
- data/CHANGELOG.md +19 -0
- data/Rakefile +34 -0
- data/docs/index.rst +1 -0
- data/docs/pages/using-hiera.rst +285 -0
- data/fpm-cookery.gemspec +6 -1
- data/lib/fpm/cookery/book.rb +29 -2
- data/lib/fpm/cookery/book_hook.rb +1 -0
- data/lib/fpm/cookery/chain_packager.rb +4 -2
- data/lib/fpm/cookery/cli.rb +45 -5
- data/lib/fpm/cookery/config.rb +2 -1
- data/lib/fpm/cookery/environment.rb +17 -8
- data/lib/fpm/cookery/exceptions.rb +3 -1
- data/lib/fpm/cookery/facts.rb +50 -35
- data/lib/fpm/cookery/hiera.rb +35 -0
- data/lib/fpm/cookery/hiera/defaults.rb +50 -0
- data/lib/fpm/cookery/hiera/scope.rb +35 -0
- data/lib/fpm/cookery/inheritable_attr.rb +222 -0
- data/lib/fpm/cookery/log/hiera.rb +21 -0
- data/lib/fpm/cookery/omnibus_packager.rb +4 -2
- data/lib/fpm/cookery/package/package.rb +1 -0
- data/lib/fpm/cookery/package/version.rb +11 -4
- data/lib/fpm/cookery/packager.rb +13 -11
- data/lib/fpm/cookery/recipe.rb +167 -105
- data/lib/fpm/cookery/source.rb +6 -8
- data/lib/fpm/cookery/source_handler.rb +18 -3
- data/lib/fpm/cookery/source_handler/curl.rb +2 -2
- data/lib/fpm/cookery/source_handler/directory.rb +10 -11
- data/lib/fpm/cookery/source_handler/noop.rb +1 -2
- data/lib/fpm/cookery/source_handler/svn.rb +1 -1
- data/lib/fpm/cookery/version.rb +1 -1
- data/lib/hiera/fpm_cookery_logger.rb +12 -0
- data/recipes/redis/config/common.yaml +11 -0
- data/recipes/redis/config/git_2.4.2_tag.yaml +4 -0
- data/recipes/redis/config/git_2.4.yaml +4 -0
- data/recipes/redis/config/git_sha_072a905.yaml +4 -0
- data/recipes/redis/config/svn_r2400.yaml +4 -0
- data/recipes/redis/config/svn_trunk.yaml +3 -0
- data/recipes/redis/recipe.rb +2 -27
- data/spec/book_spec.rb +34 -0
- data/spec/config_spec.rb +19 -0
- data/spec/environment_spec.rb +37 -0
- data/spec/facts_spec.rb +54 -31
- data/spec/fixtures/hiera_config/CentOS.yaml +1 -0
- data/spec/fixtures/hiera_config/common.yaml +12 -0
- data/spec/fixtures/hiera_config/custom.yaml +3 -0
- data/spec/fixtures/hiera_config/rpm.yaml +12 -0
- data/spec/hiera_spec.rb +158 -0
- data/spec/inheritable_attr_spec.rb +202 -0
- data/spec/package_dir_spec.rb +37 -0
- data/spec/package_maintainer_spec.rb +4 -1
- data/spec/package_version_spec.rb +50 -0
- data/spec/path_spec.rb +20 -0
- data/spec/recipe_spec.rb +161 -56
- data/spec/source_integrity_check_spec.rb +7 -6
- data/spec/spec_helper.rb +14 -0
- data/spec/support/shared_context.rb +71 -0
- metadata +108 -4
@@ -0,0 +1 @@
|
|
1
|
+
post_install: '%{scope("workdir")}/fix_ldconfig.sh'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
name: fake_package
|
2
|
+
description: >
|
3
|
+
For testing purposes on %{scope("platform")} only - you've been warned ;)
|
4
|
+
version: 1.0.2
|
5
|
+
source:
|
6
|
+
- http://www.dummy-url.com/archive/%{hiera("name")}-%{hiera("version")}.tar.gz
|
7
|
+
- :with: :git
|
8
|
+
|
9
|
+
environment:
|
10
|
+
PREFIX: '/opt'
|
11
|
+
|
12
|
+
post_install: '%{scope("workdir")}/default.sh'
|
data/spec/hiera_spec.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fpm/cookery/book'
|
3
|
+
require 'fpm/cookery/book_hook'
|
4
|
+
require 'fpm/cookery/facts'
|
5
|
+
require 'fpm/cookery/hiera'
|
6
|
+
require 'fpm/cookery/recipe'
|
7
|
+
require 'hiera/fpm_cookery_logger'
|
8
|
+
require 'facter'
|
9
|
+
|
10
|
+
describe 'Hiera' do
|
11
|
+
describe 'Defaults' do
|
12
|
+
subject { FPM::Cookery::Hiera::Defaults }
|
13
|
+
|
14
|
+
describe '.hiera_logger' do
|
15
|
+
it 'provides a default logger key for Hiera' do
|
16
|
+
expect(subject.hiera_logger).to eq 'fpm_cookery'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.hiera_hierarchy' do
|
21
|
+
it 'provides a default lookup hierarchy for Hiera' do
|
22
|
+
expect(subject.hiera_hierarchy).to contain_exactly('common')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '.hiera_backends' do
|
27
|
+
it 'provides a default backend list for Hiera' do
|
28
|
+
expect(subject.hiera_backends).to contain_exactly(:yaml, :json)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'Fpm_cookery_logger' do
|
34
|
+
it 'aliases Hiera::Fpm_cookery_logger to FPM::Cookery::Log::Hiera' do
|
35
|
+
expect(Hiera.const_get("Fpm_cookery_logger")).to be (FPM::Cookery::Log::Hiera)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'Scope' do
|
40
|
+
let(:scope) { FPM::Cookery::Hiera::Scope.new(recipe) }
|
41
|
+
include_context "recipe class", __FILE__, :platform => nil, :hiera_config => nil,
|
42
|
+
:data_dir => fixture_path('hiera_config')
|
43
|
+
|
44
|
+
describe '[]' do
|
45
|
+
context 'given an argument corresponding to a recipe class method' do
|
46
|
+
it 'returns the value returned by the class method' do
|
47
|
+
expect(scope['workdir']).to eq(recipe.workdir)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'given an argument corresponding to an FPM::Cookery::Fact class method' do
|
52
|
+
it 'returns the value returned by the class method' do
|
53
|
+
expect(scope['osmajorrelease']).to eq(FPM::Cookery::Facts.osmajorrelease)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'given an otherwise unresolvable argument' do
|
58
|
+
it 'consults Facter' do
|
59
|
+
expect(scope['processorcount']).to eq(Facter['processorcount'].value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#lookup' do
|
66
|
+
include_context "recipe class", __FILE__, :platform => nil, :hiera_config => nil,
|
67
|
+
:data_dir => fixture_path('hiera_config')
|
68
|
+
|
69
|
+
context "given default options and unset `platform' fact" do
|
70
|
+
it "returns values from `common.yaml' only" do
|
71
|
+
expect(recipe.lookup('environment')).to eq('PREFIX' => '/opt')
|
72
|
+
expect(recipe.lookup('version')).to eq('1.0.2')
|
73
|
+
expect(recipe.lookup('post_install')).to eq((recipe.workdir / 'default.sh').to_s)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'given a platform' do
|
78
|
+
before(:each) { allow(config).to receive(:platform).and_return('CentOS') }
|
79
|
+
|
80
|
+
it "prefers values from `\#{platform}.yaml'" do
|
81
|
+
expect(recipe.lookup('post_install')).to eq((recipe.workdir / 'fix_ldconfig.sh').to_s)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'given a value for ENV["FPM_HIERARCHY"]' do
|
86
|
+
around(:each) do |example|
|
87
|
+
ENV['FPM_HIERARCHY'] = env
|
88
|
+
example.run
|
89
|
+
ENV.delete('FPM_HIERARCHY')
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'that does not correspond to an existing data file' do
|
93
|
+
let(:env) { 'fake' }
|
94
|
+
|
95
|
+
it 'uses data from the default data file' do
|
96
|
+
expect(recipe.lookup('environment')).to eq('PREFIX' => '/opt')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'that corresponds to an existing data file' do
|
101
|
+
let(:env) { 'custom' }
|
102
|
+
|
103
|
+
it 'prefers data from that file' do
|
104
|
+
expect(recipe.lookup('environment')).to eq('PREFIX' => '/usr/local', 'AUTOMATED_TESTING' => 1)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "#new" do
|
111
|
+
context "given a string as the option to `:config'" do
|
112
|
+
let(:hiera) { FPM::Cookery::Hiera::Instance.new(recipe, :config => filename) }
|
113
|
+
|
114
|
+
let(:recipe) do
|
115
|
+
double('Recipe').as_null_object
|
116
|
+
end
|
117
|
+
|
118
|
+
context "that does not refer to an existing hiera.yaml file" do
|
119
|
+
let(:filename) { "/probably/does/not/exist/pretty/sure/anyway" }
|
120
|
+
|
121
|
+
it "raises an error when Hiera config file does not exist" do
|
122
|
+
expect { hiera }.to raise_error(RuntimeError)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "that refers to an existing hiera.yaml file" do
|
127
|
+
let(:filename) { 'hiera.yaml' }
|
128
|
+
|
129
|
+
around(:each) do |example|
|
130
|
+
Dir.mktmpdir do |dir|
|
131
|
+
Dir.chdir(dir) do
|
132
|
+
File.open(filename, 'w') do |config_file|
|
133
|
+
config_file.print <<-CONFIG_FILE
|
134
|
+
:backends:
|
135
|
+
- json
|
136
|
+
:json:
|
137
|
+
:datadir: '/hey/i/am/a/datadir'
|
138
|
+
:hierarchy:
|
139
|
+
- yakko
|
140
|
+
- wakko
|
141
|
+
- dot
|
142
|
+
CONFIG_FILE
|
143
|
+
end
|
144
|
+
|
145
|
+
example.run
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
it "loads settings from that file" do
|
151
|
+
expect(hiera.config[:backends]).to contain_exactly('json')
|
152
|
+
expect(hiera.config[:json]).to eq(:datadir => '/hey/i/am/a/datadir')
|
153
|
+
expect(hiera.config[:hierarchy]).to contain_exactly(*%w{yakko wakko dot})
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fpm/cookery/inheritable_attr'
|
3
|
+
require 'fpm/cookery/path'
|
4
|
+
|
5
|
+
def dsl_klass(name = nil)
|
6
|
+
(klass = Class.new).send(:extend, FPM::Cookery::InheritableAttr)
|
7
|
+
klass.class_eval(&Proc.new) if block_given?
|
8
|
+
klass
|
9
|
+
end
|
10
|
+
|
11
|
+
shared_examples 'attribute registration' do |attr_method, registry_method|
|
12
|
+
context "given an attribute created with .#{attr_method}" do
|
13
|
+
it "registers the attribute in the .#{registry_method} list" do
|
14
|
+
klass = Class.new do
|
15
|
+
extend FPM::Cookery::InheritableAttr
|
16
|
+
|
17
|
+
instance_eval %Q{
|
18
|
+
#{attr_method} :dummy_attr
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
expect(klass).to respond_to(registry_method)
|
23
|
+
expect(klass.send(registry_method)).to include(:dummy_attr)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
shared_context 'class inheritance' do
|
29
|
+
let(:superklass) { dsl_klass }
|
30
|
+
let(:subklass) { Class.new(superklass) }
|
31
|
+
end
|
32
|
+
|
33
|
+
shared_examples 'attribute inheritance' do |attr_method, default_value, attr_name = :dummy_attr|
|
34
|
+
# A default implementation. Useful for +.attr_rw+, but should probably be
|
35
|
+
# overridden for the other DSL methods.
|
36
|
+
let(:attr_setter) {
|
37
|
+
Class.new do
|
38
|
+
def self.call(k, m, v)
|
39
|
+
k.send(m, v)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
44
|
+
describe 'created attribute' do
|
45
|
+
it 'is defined on class' do
|
46
|
+
expect(superklass).to respond_to(attr_name)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "is #{default_value.inspect} by default" do
|
50
|
+
expect(superklass.send(attr_name)).to eq(default_value)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'sets the attribute' do
|
54
|
+
attr_setter.(superklass, attr_name, value)
|
55
|
+
expect(superklass.send(attr_name)).to eq value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe 'child class' do
|
60
|
+
describe 'inherited attribute' do
|
61
|
+
it 'inherits its value from the superclass' do
|
62
|
+
attr_setter.(superklass, attr_name, value)
|
63
|
+
expect(subklass.send(attr_name)).to eq value
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when altered' do
|
67
|
+
it 'does not propagate to the superclass' do
|
68
|
+
attr_setter.(superklass, attr_name, value)
|
69
|
+
attr_setter.(subklass, attr_name, child_value)
|
70
|
+
expect(superklass.send(attr_name)).to eq value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
shared_context 'inheritable attributes' do |attr_method, default_value, attr_name = :dummy_attr|
|
78
|
+
include_context 'class inheritance'
|
79
|
+
include_examples 'attribute inheritance', attr_method, default_value
|
80
|
+
|
81
|
+
before(:example) do
|
82
|
+
missing = [:value, :child_value].reject { |m| respond_to?(m) }
|
83
|
+
raise "Missing required methods: #{missing.join(', ')}" unless missing.empty?
|
84
|
+
|
85
|
+
superklass.instance_eval do
|
86
|
+
send(attr_method, attr_name)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe FPM::Cookery::InheritableAttr do
|
92
|
+
describe '.register_attrs' do
|
93
|
+
describe '.attr_rw' do
|
94
|
+
include_examples 'attribute registration', 'attr_rw', 'scalar_attrs'
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '.attr_rw_list' do
|
98
|
+
include_examples 'attribute registration', 'attr_rw_list', 'list_attrs'
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '.attr_rw_hash' do
|
102
|
+
include_examples 'attribute registration', 'attr_rw_hash', 'hash_attrs'
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '.attr_rw_path' do
|
106
|
+
include_examples 'attribute registration', 'attr_rw_path', 'path_attrs'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '.attr_rw' do
|
111
|
+
include_context 'inheritable attributes', 'attr_rw', nil do
|
112
|
+
let(:value) { 'that' }
|
113
|
+
let(:child_value) { 'the other' }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '.attr_rw_list' do
|
118
|
+
include_context 'inheritable attributes', 'attr_rw_list', [] do
|
119
|
+
let(:attr_setter) {
|
120
|
+
Class.new do
|
121
|
+
def self.call(k, m, v)
|
122
|
+
k.send(m, *v)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
}
|
126
|
+
|
127
|
+
let(:value) { %w{so la ti do} }
|
128
|
+
let(:child_value) { %w{fee fi fo fum} }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '.attr_rw_hash' do
|
133
|
+
include_context 'inheritable attributes', 'attr_rw_hash', {} do
|
134
|
+
let(:value) { {:name => 'mike', :rank => 'colonel' } }
|
135
|
+
let(:child_value) { {:name => 'mike', :favorite_color => 'puce' } }
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'created attribute' do
|
139
|
+
before do
|
140
|
+
superklass.instance_eval do
|
141
|
+
attr_rw_hash :metadata
|
142
|
+
end
|
143
|
+
|
144
|
+
superklass.metadata({ :radius => 4.172, :weight => 4 })
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'merges its argument into the existing attribute value' do
|
148
|
+
superklass.metadata({ :weight => 7, :height => 12.3 })
|
149
|
+
expect(superklass.metadata).to eq({
|
150
|
+
:height => 12.3,
|
151
|
+
:weight => 7,
|
152
|
+
:radius => 4.172
|
153
|
+
})
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'supports []= assignment' do
|
157
|
+
expect { superklass.metadata[:age] = 10000 }.not_to raise_error
|
158
|
+
expect(superklass.metadata).to include(:age => 10000)
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'from child class' do
|
162
|
+
it 'does not propagate changes to the parent class' do
|
163
|
+
superklass.metadata[:tags] = %w{a b c}
|
164
|
+
subklass.metadata[:tags] << 'd'
|
165
|
+
expect(superklass.metadata[:tags]).not_to include('d')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe '.attr_rw_path' do
|
172
|
+
include_context 'inheritable attributes', 'attr_rw_path', nil do
|
173
|
+
let(:attr_setter) {
|
174
|
+
Class.new do
|
175
|
+
def self.call(k, m, v)
|
176
|
+
k.send(:"#{m}=", v)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
}
|
180
|
+
|
181
|
+
let(:value) { FPM::Cookery::Path.new('/var/spool') }
|
182
|
+
let(:child_value) { FPM::Cookery::Path.new('/proc/self') }
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'returns an FPM::Cookery::Path object' do
|
186
|
+
superklass.attr_rw_path :home
|
187
|
+
superklass.home = "/where/the/heart/is"
|
188
|
+
expect(superklass.home).to be_an(FPM::Cookery::Path)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe '.inherit_for' do
|
193
|
+
include_context 'class inheritance'
|
194
|
+
|
195
|
+
context 'given a method name that the superclass does not respond to' do
|
196
|
+
it 'returns nil' do
|
197
|
+
expect(superklass).not_to respond_to(:blech)
|
198
|
+
expect(FPM::Cookery::InheritableAttr.inherit_for(subklass, :blech)).to be nil
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fpm/cookery/package/dir'
|
3
|
+
require 'fpm/cookery/recipe'
|
4
|
+
|
5
|
+
describe FPM::Cookery::Package::Dir do
|
6
|
+
let(:config) { { :input => input } }
|
7
|
+
let(:input) { %w{foo bar baz} }
|
8
|
+
|
9
|
+
let(:recipe) do
|
10
|
+
Class.new(FPM::Cookery::Recipe) do
|
11
|
+
description 'a test package'
|
12
|
+
name 'boo'
|
13
|
+
version '8.5'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:package) do
|
18
|
+
described_class.new(recipe, config)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:fpm) do
|
22
|
+
double('FPM').as_null_object
|
23
|
+
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
allow(recipe).to receive(:config).and_return(double('Config').as_null_object)
|
27
|
+
allow(FPM::Package::Dir).to receive(:new).and_return(fpm)
|
28
|
+
end
|
29
|
+
|
30
|
+
context '#package_input' do
|
31
|
+
it 'calls the fpm package creation with a clean environment' do
|
32
|
+
expect(fpm).to receive(:input).exactly(input.length).times
|
33
|
+
|
34
|
+
package # Trigger object creation and package_input call.
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -58,7 +58,10 @@ describe 'Maintainer' do
|
|
58
58
|
|
59
59
|
context 'without valid git data' do
|
60
60
|
before do
|
61
|
-
allow(FPM::Cookery::Shellout).to receive(:git_config_get).
|
61
|
+
allow(FPM::Cookery::Shellout).to receive(:git_config_get).and_raise(
|
62
|
+
FPM::Cookery::Shellout::CommandFailed, 'whoops!'
|
63
|
+
)
|
64
|
+
|
62
65
|
allow(Socket).to receive(:gethostname).and_return('hostname')
|
63
66
|
end
|
64
67
|
|
@@ -140,4 +140,54 @@ describe 'Version' do
|
|
140
140
|
expect(version.to_str).to eq('1.3-1.foo')
|
141
141
|
end
|
142
142
|
end
|
143
|
+
|
144
|
+
describe '#version' do
|
145
|
+
context 'given a colon-delimited string in recipe.version' do
|
146
|
+
context 'where version and epoch are defined' do
|
147
|
+
before(:each) { recipe.version = '8675309:3.1.1'}
|
148
|
+
|
149
|
+
it 'returns the version and epoch' do
|
150
|
+
expect(version.version).to eq('3.1.1')
|
151
|
+
expect(version.epoch).to eq('8675309')
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'where only version is defined' do
|
156
|
+
before(:each) { recipe.version = ':2.1' }
|
157
|
+
|
158
|
+
it 'returns the version and sets epoch to nil' do
|
159
|
+
expect(version.version).to eq('2.1')
|
160
|
+
expect(version.epoch).to be nil
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'where only epoch is defined' do
|
165
|
+
before(:each) { recipe.version = '12345:' }
|
166
|
+
|
167
|
+
it 'returns the epoch as version and sets epoch to nil' do
|
168
|
+
expect(version.version).to eq('12345')
|
169
|
+
expect(version.epoch).to be nil
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'given a nil recipe.version' do
|
176
|
+
before(:each) { recipe.version = nil }
|
177
|
+
|
178
|
+
it 'returns the default version' do
|
179
|
+
expect(version.version).to eq(klass::DEFAULT_VERSION)
|
180
|
+
expect(version.epoch).to be nil
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'given a recipe.version containing the empty string' do
|
185
|
+
before(:each) { recipe.version = '' }
|
186
|
+
|
187
|
+
it 'returns the default version' do
|
188
|
+
expect(version.version).to eq(klass::DEFAULT_VERSION)
|
189
|
+
expect(version.epoch).to be nil
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
143
193
|
end
|