packer-config 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.rubocop.yml +340 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +17 -0
  6. data/LICENSE +176 -0
  7. data/README.md +107 -0
  8. data/Rakefile +47 -0
  9. data/TODO.md +8 -0
  10. data/lib/packer-config.rb +181 -0
  11. data/lib/packer/builder.rb +65 -0
  12. data/lib/packer/builders/all.rb +17 -0
  13. data/lib/packer/builders/amazon.rb +214 -0
  14. data/lib/packer/builders/docker.rb +47 -0
  15. data/lib/packer/builders/virtualbox.rb +169 -0
  16. data/lib/packer/dataobject.rb +128 -0
  17. data/lib/packer/envvar.rb +27 -0
  18. data/lib/packer/macro.rb +28 -0
  19. data/lib/packer/postprocessor.rb +77 -0
  20. data/lib/packer/postprocessors/all.rb +16 -0
  21. data/lib/packer/postprocessors/docker.rb +35 -0
  22. data/lib/packer/postprocessors/vagrant.rb +47 -0
  23. data/lib/packer/provisioner.rb +86 -0
  24. data/lib/packer/provisioners/all.rb +16 -0
  25. data/lib/packer/provisioners/file.rb +36 -0
  26. data/lib/packer/provisioners/shell.rb +60 -0
  27. data/packer-config.gemspec +46 -0
  28. data/spec/integration/README.md +14 -0
  29. data/spec/integration/builds/.gitignore +4 -0
  30. data/spec/integration/centos_vagrant_spec.rb +76 -0
  31. data/spec/integration/packer_cache/.gitignore +4 -0
  32. data/spec/integration/scripts/chef.sh +199 -0
  33. data/spec/integration/scripts/cleanup.sh +17 -0
  34. data/spec/integration/scripts/fix-slow-dns.sh +13 -0
  35. data/spec/integration/scripts/hello.sh +3 -0
  36. data/spec/integration/scripts/kickstart/centos-6.5-ks.cfg +71 -0
  37. data/spec/integration/scripts/minimize.sh +9 -0
  38. data/spec/integration/scripts/sshd.sh +6 -0
  39. data/spec/integration/scripts/vagrant.sh +10 -0
  40. data/spec/integration/scripts/vmtools.sh +39 -0
  41. data/spec/packer/builder_spec.rb +39 -0
  42. data/spec/packer/builders/amazon_spec.rb +88 -0
  43. data/spec/packer/builders/docker_spec.rb +25 -0
  44. data/spec/packer/builders/virtualbox_spec.rb +44 -0
  45. data/spec/packer/dataobject_spec.rb +239 -0
  46. data/spec/packer/envvar_spec.rb +38 -0
  47. data/spec/packer/macro_spec.rb +38 -0
  48. data/spec/packer/postprocessor_spec.rb +72 -0
  49. data/spec/packer/postprocessors/docker_import_spec.rb +27 -0
  50. data/spec/packer/postprocessors/docker_push_spec.rb +27 -0
  51. data/spec/packer/postprocessors/vagrant_spec.rb +27 -0
  52. data/spec/packer/provisioner_spec.rb +78 -0
  53. data/spec/packer/provisioners/file_spec.rb +63 -0
  54. data/spec/packer/provisioners/shell_spec.rb +116 -0
  55. data/spec/packer_config_spec.rb +197 -0
  56. data/spec/spec_helper.rb +19 -0
  57. data/spec/unit_helper.rb +15 -0
  58. metadata +220 -0
@@ -0,0 +1,27 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::PostProcessor::DockerImport do
18
+ let(:postprocessor) do
19
+ Packer::PostProcessor.get_postprocessor(Packer::PostProcessor::DOCKER_IMPORT)
20
+ end
21
+
22
+ describe '#initialize' do
23
+ it 'has a type of shell' do
24
+ expect(postprocessor.data['type']).to eq(Packer::PostProcessor::DOCKER_IMPORT)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::PostProcessor::DockerPush do
18
+ let(:postprocessor) do
19
+ Packer::PostProcessor.get_postprocessor(Packer::PostProcessor::DOCKER_PUSH)
20
+ end
21
+
22
+ describe '#initialize' do
23
+ it 'has a type of shell' do
24
+ expect(postprocessor.data['type']).to eq(Packer::PostProcessor::DOCKER_PUSH)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::PostProcessor::Vagrant do
18
+ let(:postprocessor) do
19
+ Packer::PostProcessor.get_postprocessor(Packer::PostProcessor::VAGRANT)
20
+ end
21
+
22
+ describe '#initialize' do
23
+ it 'has a type of shell' do
24
+ expect(postprocessor.data['type']).to eq(Packer::PostProcessor::VAGRANT)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,78 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::Provisioner do
18
+ PROVISIONER_TYPE = 'shell'
19
+
20
+ let(:provisioner) do
21
+ Packer::Provisioner.new
22
+ end
23
+
24
+ let(:overrides) do
25
+ {
26
+ "key1" => "value1",
27
+ "key2" => "value2"
28
+ }
29
+ end
30
+
31
+ describe '.get_provisioner' do
32
+ it 'returns a provisioner' do
33
+ expect(Packer::Provisioner.get_provisioner(PROVISIONER_TYPE)).to be_a_kind_of(Packer::Provisioner)
34
+ end
35
+
36
+ it 'raises an error when the provisioner type is not recognized' do
37
+ expect { Packer::Provisioner.get_provisioner('unknown-type') }.to raise_error
38
+ end
39
+ end
40
+
41
+ describe '#only' do
42
+ it 'adds an only exception' do
43
+ provisioner.only('thing1')
44
+ expect(provisioner.data['only']).to eq(%w[thing1])
45
+ provisioner.only('thing2')
46
+ expect(provisioner.data['only']).to eq(%w[thing1 thing2])
47
+ end
48
+ end
49
+
50
+ describe '#except' do
51
+ it 'adds an execpt exception' do
52
+ provisioner.except('thing3')
53
+ expect(provisioner.data['except']).to eq(%w[thing3])
54
+ provisioner.except('thing4')
55
+ expect(provisioner.data['except']).to eq(%w[thing3 thing4])
56
+ end
57
+ end
58
+
59
+ describe '#pause_before' do
60
+ it 'adds a pause time' do
61
+ provisioner.pause_before(10)
62
+ expect(provisioner.data['pause_before']).to eq("10")
63
+ provisioner.pause_before("10s")
64
+ expect(provisioner.data['pause_before']).to eq("10s")
65
+ end
66
+ end
67
+
68
+ describe '#override' do
69
+ it 'adds a hash overridef override values to a list of overrides' do
70
+ provisioner.override('build', overrides)
71
+ expect(provisioner.data['override']['build']).to eq(overrides)
72
+ end
73
+
74
+ it 'raises a TypeError when the overrides are not a hash' do
75
+ expect { provisioner.override('build', 10) }.to raise_error
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,63 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::Provisioner::File do
18
+ let(:provisioner) do
19
+ Packer::Provisioner.get_provisioner('file')
20
+ end
21
+
22
+ let(:some_string) do
23
+ 'some string'
24
+ end
25
+
26
+ let(:some_array_of_ints) do
27
+ [1, 2, 3]
28
+ end
29
+
30
+ describe '#initialize' do
31
+ it 'has a type of file' do
32
+ expect(provisioner.data['type']).to eq('file')
33
+ end
34
+ end
35
+
36
+ describe '#source' do
37
+ it 'accepts a string' do
38
+ provisioner.source(some_string)
39
+ expect(provisioner.data['source']).to eq(some_string)
40
+ provisioner.data.delete('source')
41
+ end
42
+
43
+ it 'converts any argument passed to a string' do
44
+ provisioner.source(some_array_of_ints)
45
+ expect(provisioner.data['source']).to eq(some_array_of_ints.to_s)
46
+ provisioner.data.delete('source')
47
+ end
48
+ end
49
+
50
+ describe '#destination' do
51
+ it 'accepts a string' do
52
+ provisioner.destination(some_string)
53
+ expect(provisioner.data['destination']).to eq(some_string)
54
+ provisioner.data.delete('destination')
55
+ end
56
+
57
+ it 'converts any argument passed to a string' do
58
+ provisioner.destination(some_array_of_ints)
59
+ expect(provisioner.data['destination']).to eq(some_array_of_ints.to_s)
60
+ provisioner.data.delete('destination')
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,116 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::Provisioner::Shell do
18
+ let(:provisioner) do
19
+ Packer::Provisioner.get_provisioner('shell')
20
+ end
21
+
22
+ let(:some_string) do
23
+ 'some string'
24
+ end
25
+
26
+ let(:some_array_of_strings) do
27
+ %w[commmand1 command2]
28
+ end
29
+
30
+ let(:some_array_of_ints) do
31
+ [1, 2, 3]
32
+ end
33
+
34
+ describe '#initialize' do
35
+ it 'has a type of shell' do
36
+ expect(provisioner.data['type']).to eq('shell')
37
+ end
38
+ end
39
+
40
+ describe '#inline' do
41
+ it 'accepts an array of commands' do
42
+ provisioner.inline(some_array_of_strings)
43
+ expect(provisioner.data['inline']).to eq(some_array_of_strings)
44
+ provisioner.data.delete('inline')
45
+ end
46
+
47
+ it 'converts all commands to strings' do
48
+ provisioner.inline(some_array_of_ints)
49
+ expect(provisioner.data['inline']).to eq(some_array_of_ints.map{ |c| c.to_s })
50
+ provisioner.data.delete('inline')
51
+ end
52
+
53
+ it 'raises an error if the commands argument cannot be made an Array' do
54
+ expect { provisioner.inline(some_string) }.to raise_error
55
+ end
56
+
57
+ it 'raises an error if #script or #scripts method was already called' do
58
+ provisioner.data['script'] = 1
59
+ expect { provisioner.inline(some_array_of_strings) }.to raise_error
60
+ provisioner.data.delete('script')
61
+ provisioner.data['scripts'] = 1
62
+ expect { provisioner.inline(some_array_of_strings) }.to raise_error
63
+ provisioner.data.delete('scripts')
64
+ end
65
+ end
66
+
67
+ describe '#script' do
68
+ it 'accepts a string' do
69
+ provisioner.script(some_string)
70
+ expect(provisioner.data['script']).to eq(some_string)
71
+ provisioner.data.delete('script')
72
+ end
73
+
74
+ it 'converts any argument passed to a string' do
75
+ provisioner.script(some_array_of_ints)
76
+ expect(provisioner.data['script']).to eq(some_array_of_ints.to_s)
77
+ provisioner.data.delete('script')
78
+ end
79
+
80
+ it 'raises an error if #inline or #scripts method was already called' do
81
+ provisioner.data['inline'] = 1
82
+ expect { provisioner.script(some_string) }.to raise_error
83
+ provisioner.data.delete('inline')
84
+ provisioner.data['scripts'] = 1
85
+ expect { provisioner.script(some_string) }.to raise_error
86
+ provisioner.data.delete('scripts')
87
+ end
88
+ end
89
+
90
+ describe '#scripts' do
91
+ it 'accepts an array of commands' do
92
+ provisioner.scripts(some_array_of_strings)
93
+ expect(provisioner.data['scripts']).to eq(some_array_of_strings)
94
+ provisioner.data.delete('scripts')
95
+ end
96
+
97
+ it 'converts all commands to strings' do
98
+ provisioner.scripts(some_array_of_ints)
99
+ expect(provisioner.data['scripts']).to eq(some_array_of_ints.map{ |c| c.to_s })
100
+ provisioner.data.delete('scripts')
101
+ end
102
+
103
+ it 'raises an error if the commands argument cannot be made an Array' do
104
+ expect { provisioner.scripts(some_string) }.to raise_error
105
+ end
106
+
107
+ it 'raises an error if #inline or #script method was already called' do
108
+ provisioner.data['script'] = 1
109
+ expect { provisioner.scripts(some_array_of_strings) }.to raise_error
110
+ provisioner.data.delete('scripts')
111
+ provisioner.data['inline'] = 1
112
+ expect { provisioner.scripts(some_array_of_strings) }.to raise_error
113
+ provisioner.data.delete('scripts')
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,197 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+ require 'fakefs/spec_helpers'
17
+
18
+ RSpec.describe Packer::Config do
19
+ let(:config_file) { 'config.json'}
20
+ let(:packer) { Packer::Config.new(config_file) }
21
+ let(:builder_type) { Packer::Builder::VIRTUALBOX_ISO }
22
+ let(:provisioner_type) { Packer::Provisioner::FILE }
23
+ let(:postprocessor_type) { Packer::PostProcessor::VAGRANT }
24
+ let(:json_representation) do
25
+ '{"variables":{"foo":"bar"},"builders":[{"type":"virtualbox-iso"}],"provisioners":[{"type":"file"}],"post-processors":[{"type":"vagrant"}]}'
26
+ end
27
+
28
+ describe '#initialize' do
29
+ it 'returns an instance' do
30
+ expect(packer).to be_a_kind_of(Packer::Config)
31
+ end
32
+ end
33
+
34
+ describe "#validate" do
35
+ it 'returns true for a valid instance' do
36
+ expect(packer.builders).to receive(:length).and_return(1)
37
+ open3 = class_double("Open3").as_stubbed_const(:transfer_nested_constants => true)
38
+ expect(open3).to receive(:capture3).and_return(['output', 'error', 0])
39
+ FakeFS do
40
+ expect(packer.validate).to be_truthy
41
+ end
42
+ end
43
+
44
+ it 'raises an error for an invalid instance' do
45
+ expect(packer.builders).to receive(:length).and_return(0)
46
+ FakeFS do
47
+ expect { packer.validate }.to raise_error
48
+ end
49
+ end
50
+ end
51
+
52
+ describe '#dump' do
53
+ it 'dumps a JSON-formatted configuration' do
54
+ packer.add_builder builder_type
55
+ packer.add_provisioner provisioner_type
56
+ packer.add_postprocessor postprocessor_type
57
+ packer.add_variable 'foo', 'bar'
58
+ expect(packer.dump).to eq(json_representation)
59
+ end
60
+
61
+ it 'raises an error if the format is not recognized' do
62
+ expect { packer.dump 'invalid-format' }.to raise_error
63
+ end
64
+ end
65
+
66
+ describe '#write' do
67
+ it 'writes a JSON-formatted configuration file to disk' do
68
+ packer.add_builder builder_type
69
+ packer.add_provisioner provisioner_type
70
+ packer.add_postprocessor postprocessor_type
71
+ packer.add_variable 'foo', 'bar'
72
+ FakeFS do
73
+ packer.write
74
+ expect(File.read(config_file)).to eq(json_representation)
75
+ end
76
+ end
77
+
78
+ it 'raises an error if the format is not recognized' do
79
+ FakeFS do
80
+ expect { packer.dump 'invalid-format' }.to raise_error
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#build" do
86
+ it 'returns successfully if the build command returns a successful exit code' do
87
+ expect(packer).to receive(:validate).and_return(true)
88
+ expect(packer).to receive(:write).and_return(true)
89
+ open3 = class_double("Open3").as_stubbed_const(:transfer_nested_constants => true)
90
+ expect(open3).to receive(:capture3).and_return(['output', 'error', 0])
91
+ FakeFS do
92
+ expect(packer.build).to be_truthy
93
+ end
94
+ end
95
+
96
+ it 'raises an error if the data is not valid' do
97
+ expect(packer).to receive(:validate).and_raise(Packer::DataObject::DataValidationError)
98
+ FakeFS do
99
+ expect { packer.build }.to raise_error
100
+ end
101
+ end
102
+
103
+ it 'raises an error if the config cannot be written to disk' do
104
+ expect(packer).to receive(:validate).and_return(true)
105
+ expect(packer).to receive(:write).and_raise(StandardError)
106
+ expect { packer.build }.to raise_error
107
+ end
108
+
109
+ it 'raises an error if the build command returns an unsuccessful exit code' do
110
+ expect(packer).to receive(:validate).and_return(true)
111
+ expect(packer).to receive(:write).and_return(true)
112
+ open3 = class_double("Open3").as_stubbed_const(:transfer_nested_constants => true)
113
+ expect(open3).to receive(:capture3).and_return(['output', 'error', 1])
114
+ FakeFS do
115
+ expect { packer.build }.to raise_error
116
+ end
117
+ end
118
+ end
119
+
120
+ describe "#add_builder" do
121
+ it 'returns a builder for a valid type' do
122
+ expect(packer.add_builder builder_type).to be_a_kind_of(Packer::Builder)
123
+ expect(packer.builders.length).to eq(1)
124
+ packer.builders = []
125
+ end
126
+
127
+ it 'raises an error for an invalid type' do
128
+ expect { packer.add_builder 'invalid' }.to raise_error
129
+ expect(packer.builders.length).to eq(0)
130
+ end
131
+ end
132
+
133
+ describe "#add_provisioner" do
134
+ it 'returns a provisioner for a valid type' do
135
+ expect(packer.add_provisioner provisioner_type).to be_a_kind_of(Packer::Provisioner)
136
+ expect(packer.provisioners.length).to eq(1)
137
+ packer.provisioners = []
138
+ end
139
+
140
+ it 'raises an error for an invalid type' do
141
+ expect { packer.add_provisioner 'invalid' }.to raise_error
142
+ expect(packer.provisioners.length).to eq(0)
143
+ end
144
+ end
145
+
146
+ describe "#add_postprocessor" do
147
+ it 'returns a post-processor for a valid type' do
148
+ expect(packer.add_postprocessor postprocessor_type).to be_a_kind_of(Packer::PostProcessor)
149
+ expect(packer.postprocessors.length).to eq(1)
150
+ packer.postprocessors = []
151
+ end
152
+
153
+ it 'raises an error for an invalid type' do
154
+ expect { packer.add_postprocessor 'invalid' }.to raise_error
155
+ expect(packer.postprocessors.length).to eq(0)
156
+ end
157
+ end
158
+
159
+ describe '#add_variable' do
160
+ it 'adds a new variable key/value pair' do
161
+ expect(packer.variables).to eq({})
162
+ packer.add_variable('key1', 'value1')
163
+ expect(packer.variables).to eq({'key1' => 'value1'})
164
+ packer.add_variable('key2', 'value2')
165
+ expect(packer.variables).to eq({'key1' => 'value1', 'key2' => 'value2'})
166
+ packer.data['variables'] = {}
167
+ end
168
+ end
169
+
170
+ describe '#variable' do
171
+ it 'creates a packer reference to a variable in the configuration' do
172
+ expect(packer.variables).to eq({})
173
+ packer.add_variable('key1', 'value1')
174
+ expect(packer.variable 'key1').to eq('{{user `key1`}}')
175
+ packer.data['variables'] = {}
176
+ end
177
+
178
+ it 'raises an error when the variable has not been defined in the configuration' do
179
+ expect(packer.variables).to eq({})
180
+ expect { packer.variable 'key1' }.to raise_error
181
+ packer.data['variables'] = {}
182
+ end
183
+ end
184
+
185
+ describe '#envvar' do
186
+ it 'creates a packer reference to an environment variable' do
187
+ expect(packer.envvar.TEST).to eq('{{env `TEST`}}')
188
+ end
189
+ end
190
+
191
+ describe '#macro' do
192
+ it 'creates a packer macro reference for any method call' do
193
+ expect(packer.macro.var).to eq('{{ .Var }}')
194
+ end
195
+ end
196
+
197
+ end