halite 1.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +10 -0
- data/Gemfile +15 -0
- data/LICENSE +202 -0
- data/README.md +75 -0
- data/Rakefile +22 -0
- data/halite.gemspec +33 -0
- data/lib/berkshelf/halite.rb +2 -0
- data/lib/halite.rb +12 -0
- data/lib/halite/berkshelf/helper.rb +69 -0
- data/lib/halite/berkshelf/source.rb +56 -0
- data/lib/halite/converter.rb +17 -0
- data/lib/halite/converter/libraries.rb +40 -0
- data/lib/halite/converter/metadata.rb +21 -0
- data/lib/halite/converter/other.rb +19 -0
- data/lib/halite/converter/readme.rb +20 -0
- data/lib/halite/dependencies.rb +72 -0
- data/lib/halite/error.rb +4 -0
- data/lib/halite/gem.rb +82 -0
- data/lib/halite/rake_helper.rb +151 -0
- data/lib/halite/rake_tasks.rb +2 -0
- data/lib/halite/spec_helper.rb +134 -0
- data/lib/halite/spec_helper/empty/README.md +1 -0
- data/lib/halite/spec_helper/runner.rb +43 -0
- data/lib/halite/version.rb +3 -0
- data/spec/converter/libraries_spec.rb +152 -0
- data/spec/converter/metadata_spec.rb +60 -0
- data/spec/converter/other_spec.rb +56 -0
- data/spec/converter/readme_spec.rb +55 -0
- data/spec/converter_spec.rb +14 -0
- data/spec/data/gems/test1/Rakefile +1 -0
- data/spec/data/gems/test1/lib/test1.rb +2 -0
- data/spec/data/gems/test1/lib/test1/version.rb +3 -0
- data/spec/data/gems/test1/test1.gemspec +25 -0
- data/spec/data/gems/test2/Rakefile +1 -0
- data/spec/data/gems/test2/chef/attributes.rb +0 -0
- data/spec/data/gems/test2/chef/recipes/default.rb +0 -0
- data/spec/data/gems/test2/chef/templates/default/conf.erb +0 -0
- data/spec/data/gems/test2/lib/test2.rb +4 -0
- data/spec/data/gems/test2/lib/test2/resource.rb +6 -0
- data/spec/data/gems/test2/lib/test2/version.rb +3 -0
- data/spec/data/gems/test2/test2.gemspec +24 -0
- data/spec/data/gems/test3/Rakefile +1 -0
- data/spec/data/gems/test3/chef/recipes/default.rb +1 -0
- data/spec/data/gems/test3/lib/test3.rb +4 -0
- data/spec/data/gems/test3/lib/test3/dsl.rb +15 -0
- data/spec/data/gems/test3/lib/test3/version.rb +3 -0
- data/spec/data/gems/test3/test3.gemspec +24 -0
- data/spec/data/integration_cookbooks/test1/libraries/test1.rb +3 -0
- data/spec/data/integration_cookbooks/test1/libraries/test1__version.rb +4 -0
- data/spec/data/integration_cookbooks/test1/metadata.rb +4 -0
- data/spec/data/integration_cookbooks/test2/attributes.rb +0 -0
- data/spec/data/integration_cookbooks/test2/libraries/test2.rb +5 -0
- data/spec/data/integration_cookbooks/test2/libraries/test2__resource.rb +7 -0
- data/spec/data/integration_cookbooks/test2/libraries/test2__version.rb +4 -0
- data/spec/data/integration_cookbooks/test2/metadata.rb +4 -0
- data/spec/data/integration_cookbooks/test2/recipes/default.rb +0 -0
- data/spec/data/integration_cookbooks/test2/templates/default/conf.erb +0 -0
- data/spec/data/integration_cookbooks/test3/libraries/test3.rb +5 -0
- data/spec/data/integration_cookbooks/test3/libraries/test3__dsl.rb +16 -0
- data/spec/data/integration_cookbooks/test3/libraries/test3__version.rb +4 -0
- data/spec/data/integration_cookbooks/test3/metadata.rb +4 -0
- data/spec/data/integration_cookbooks/test3/recipes/default.rb +1 -0
- data/spec/dependencies_spec.rb +167 -0
- data/spec/gem_spec.rb +164 -0
- data/spec/integration_spec.rb +104 -0
- data/spec/spec_helper.rb +28 -0
- metadata +307 -0
@@ -0,0 +1,134 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
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
|
+
#
|
16
|
+
|
17
|
+
require 'halite/spec_helper/runner'
|
18
|
+
|
19
|
+
module Halite
|
20
|
+
module SpecHelper
|
21
|
+
extend RSpec::SharedContext
|
22
|
+
let(:step_into) { [] }
|
23
|
+
|
24
|
+
# An alias for slightly more semantic meaning, just forces the lazy #subject to run.
|
25
|
+
def run_chef
|
26
|
+
subject
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def patch_module(mod, name, obj, &block)
|
32
|
+
class_name = Chef::Mixin::ConvertToClassName.convert_to_class_name(name.to_s)
|
33
|
+
if mod.const_defined?(class_name, false)
|
34
|
+
old_class = mod.const_get(class_name, false)
|
35
|
+
# We are only allowed to patch over things installed by patch_module
|
36
|
+
raise "#{mod.name}::#{class_name} is already defined" if !old_class.instance_variable_get(:@poise_spec_helper)
|
37
|
+
# Remove it before setting to avoid the redefinition warning
|
38
|
+
mod.send(:remove_const, class_name)
|
39
|
+
end
|
40
|
+
# Tag our objects so we know we are allows to overwrite those, but not other stuff.
|
41
|
+
obj.instance_variable_set(:@poise_spec_helper, true)
|
42
|
+
mod.const_set(class_name, obj)
|
43
|
+
begin
|
44
|
+
block.call
|
45
|
+
ensure
|
46
|
+
# Same as above, have to remove before set because warnings
|
47
|
+
mod.send(:remove_const, class_name)
|
48
|
+
mod.const_set(class_name, old_class) if old_class
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module ClassMethods
|
53
|
+
def recipe(&block)
|
54
|
+
# Keep the actual logic in a let in case I want to define the subject as something else
|
55
|
+
let(:chef_run) { Halite::SpecHelper::Runner.new(step_into: step_into).converge(&block) }
|
56
|
+
subject { chef_run }
|
57
|
+
end
|
58
|
+
|
59
|
+
# A note about the :parent option below: You can't use resources that
|
60
|
+
# are defined via these helpers because they don't have a global const
|
61
|
+
# name until the actual tests are executing.
|
62
|
+
|
63
|
+
def resource(name, options={}, &block)
|
64
|
+
options = {auto: true, parent: Chef::Resource}.merge(options)
|
65
|
+
# Create the resource class
|
66
|
+
resource_class = Class.new(options[:parent]) do
|
67
|
+
class_exec(&block) if block
|
68
|
+
# Wrap some stuff around initialize because I'm lazy
|
69
|
+
if options[:auto]
|
70
|
+
old_init = instance_method(:initialize)
|
71
|
+
define_method(:initialize) do |*args|
|
72
|
+
# Fill in the resource name because I know it
|
73
|
+
@resource_name = name.to_sym
|
74
|
+
old_init.bind(self).call(*args)
|
75
|
+
# ChefSpec doesn't seem to work well with action :nothing
|
76
|
+
if @action == :nothing
|
77
|
+
@action = :run
|
78
|
+
@allowed_actions |= [:run]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Figure out the available actions
|
85
|
+
resource_class.new(nil, nil).allowed_actions.each do |action|
|
86
|
+
define_method("#{action}_#{name}") do |resource_name|
|
87
|
+
ChefSpec::Matchers::ResourceMatcher.new(name, action, resource_name)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
around do |ex|
|
92
|
+
# Automatically step in to our new resource
|
93
|
+
step_into << name
|
94
|
+
# Patch the resource in to Chef
|
95
|
+
patch_module(Chef::Resource, name, resource_class) { ex.run }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def provider(name, options={}, &block)
|
100
|
+
options = {auto: true, rspec: true, parent: Chef::Provider}.merge(options)
|
101
|
+
provider_class = Class.new(options[:parent]) do
|
102
|
+
# Pull in RSpec expectations
|
103
|
+
if options[:rspec]
|
104
|
+
include RSpec::Matchers
|
105
|
+
include RSpec::Mocks::ExampleMethods
|
106
|
+
end
|
107
|
+
|
108
|
+
if options[:auto]
|
109
|
+
# Default blank impl to avoid error
|
110
|
+
def load_current_resource
|
111
|
+
end
|
112
|
+
|
113
|
+
# Blank action because I do that so much
|
114
|
+
def action_run
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class_exec(&block) if block
|
119
|
+
end
|
120
|
+
|
121
|
+
around do |ex|
|
122
|
+
patch_module(Chef::Provider, name, provider_class) { ex.run }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def included(klass)
|
127
|
+
super
|
128
|
+
klass.extend ClassMethods
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
extend ClassMethods
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
This folder is intentionally empty except for this README. It is used by Halite::SpecHelper::Runner.
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
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
|
+
#
|
16
|
+
|
17
|
+
require 'chef/recipe'
|
18
|
+
|
19
|
+
module Halite
|
20
|
+
module SpecHelper
|
21
|
+
class Runner < ChefSpec::SoloRunner
|
22
|
+
def self.converge(&block)
|
23
|
+
new.tap do |instance|
|
24
|
+
instance.converge(&block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def converge(&block)
|
29
|
+
super do
|
30
|
+
recipe = Chef::Recipe.new(nil, nil, run_context)
|
31
|
+
recipe.instance_exec(&block)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Don't try to autodetect
|
38
|
+
def calling_cookbook_path(kaller)
|
39
|
+
File.expand_path('../empty', __FILE__)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'halite/converter/libraries'
|
3
|
+
|
4
|
+
describe Halite::Converter::Libraries do
|
5
|
+
|
6
|
+
describe '#generate' do
|
7
|
+
let(:data) { '' }
|
8
|
+
let(:entry_point) { false }
|
9
|
+
let(:cookbook_dependencies) { [] }
|
10
|
+
subject { described_class.generate(double(name: 'mygem', cookbook_dependencies: cookbook_dependencies.map {|dep| Halite::Dependencies::Dependency.new(dep, nil, :dependencies) }), data, entry_point) }
|
11
|
+
|
12
|
+
context 'with a single require' do
|
13
|
+
let(:data) { "x = 1\nrequire 'mygem/version'\n" }
|
14
|
+
it { is_expected.to eq <<-EOH }
|
15
|
+
if ENV['HALITE_LOAD']; x = 1
|
16
|
+
require_relative 'mygem__version'
|
17
|
+
end
|
18
|
+
EOH
|
19
|
+
end # /context with a single require
|
20
|
+
|
21
|
+
context 'with two requires' do
|
22
|
+
let(:data) { "require 'mygem/foo/bar'\nrequire 'another'" }
|
23
|
+
it { is_expected.to eq <<-EOH }
|
24
|
+
if ENV['HALITE_LOAD']; require_relative 'mygem__foo__bar'
|
25
|
+
require 'another'
|
26
|
+
end
|
27
|
+
EOH
|
28
|
+
end # /context with two requires
|
29
|
+
|
30
|
+
context 'with an entry point' do
|
31
|
+
let(:data) { "x = 1\nrequire 'mygem/version'\n" }
|
32
|
+
let(:entry_point) { true }
|
33
|
+
it { is_expected.to eq <<-EOH }
|
34
|
+
ENV['HALITE_LOAD'] = '1'; begin; x = 1
|
35
|
+
require_relative 'mygem__version'
|
36
|
+
ensure; ENV.delete('HALITE_LOAD'); end
|
37
|
+
EOH
|
38
|
+
end # /context with an entry point
|
39
|
+
|
40
|
+
context 'with a big script' do
|
41
|
+
let(:data) { <<-EOH }
|
42
|
+
require 'mygem/something'
|
43
|
+
require 'mygem/utils'
|
44
|
+
require 'activesupport' # ಠ_ಠ
|
45
|
+
class Resource
|
46
|
+
attribute :source
|
47
|
+
end
|
48
|
+
EOH
|
49
|
+
it { is_expected.to eq <<-EOH }
|
50
|
+
if ENV['HALITE_LOAD']; require_relative 'mygem__something'
|
51
|
+
require_relative 'mygem__utils'
|
52
|
+
require 'activesupport' # ಠ_ಠ
|
53
|
+
class Resource
|
54
|
+
attribute :source
|
55
|
+
end
|
56
|
+
end
|
57
|
+
EOH
|
58
|
+
end # /context with a big script
|
59
|
+
|
60
|
+
context 'with external dependencies' do
|
61
|
+
let(:cookbook_dependencies) { ['other'] }
|
62
|
+
let(:data) { <<-EOH }
|
63
|
+
require 'mygem/something'
|
64
|
+
require 'mygem/utils'
|
65
|
+
require "mygem"
|
66
|
+
require 'other'
|
67
|
+
class Resource
|
68
|
+
attribute :source
|
69
|
+
end
|
70
|
+
EOH
|
71
|
+
it { is_expected.to eq <<-EOH }
|
72
|
+
if ENV['HALITE_LOAD']; require_relative 'mygem__something'
|
73
|
+
require_relative 'mygem__utils'
|
74
|
+
require_relative 'mygem'
|
75
|
+
require_relative '../../other/libraries/other'
|
76
|
+
class Resource
|
77
|
+
attribute :source
|
78
|
+
end
|
79
|
+
end
|
80
|
+
EOH
|
81
|
+
end # /context with a big script
|
82
|
+
end # /describe #generate
|
83
|
+
|
84
|
+
describe '#write' do
|
85
|
+
let(:library_files) { [] }
|
86
|
+
let(:output) { [] }
|
87
|
+
let(:spec) do
|
88
|
+
spec = double(name: 'mygem')
|
89
|
+
allow(spec).to receive(:each_library_file) do |&block|
|
90
|
+
library_files.each {|path| block.call(File.join('/source', path), path) }
|
91
|
+
end
|
92
|
+
spec
|
93
|
+
end
|
94
|
+
before do
|
95
|
+
first = true
|
96
|
+
library_files.each do |path|
|
97
|
+
input_sentinel = double("content of #{path}")
|
98
|
+
output_sentinel = double("generated output for #{path}")
|
99
|
+
allow(IO).to receive(:read).with(File.join('/source', path)).and_return(input_sentinel)
|
100
|
+
allow(described_class).to receive(:generate).with(spec, input_sentinel, first).and_return(output_sentinel)
|
101
|
+
first = false
|
102
|
+
output << output_sentinel
|
103
|
+
end
|
104
|
+
allow(File).to receive(:directory?).and_return(false) # Always blank
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'with a single file' do
|
108
|
+
let(:library_files) { ['mygem.rb'] }
|
109
|
+
|
110
|
+
it 'writes a single file' do
|
111
|
+
expect(Dir).to receive(:mkdir).with('/test/libraries')
|
112
|
+
expect(IO).to receive(:write).with('/test/libraries/mygem.rb', output[0])
|
113
|
+
described_class.write(spec, '/test')
|
114
|
+
end
|
115
|
+
end # /context with a single file
|
116
|
+
|
117
|
+
context 'with multiple files' do
|
118
|
+
let(:library_files) { ['mygem.rb', 'mygem/one.rb', 'mygem/two.rb'] }
|
119
|
+
|
120
|
+
it 'writes multiple files' do
|
121
|
+
expect(Dir).to receive(:mkdir).with('/test/libraries')
|
122
|
+
expect(IO).to receive(:write).with('/test/libraries/mygem.rb', output[0])
|
123
|
+
expect(IO).to receive(:write).with('/test/libraries/mygem__one.rb', output[1])
|
124
|
+
expect(IO).to receive(:write).with('/test/libraries/mygem__two.rb', output[2])
|
125
|
+
described_class.write(spec, '/test')
|
126
|
+
end
|
127
|
+
end # /context with multiple files
|
128
|
+
|
129
|
+
context 'with an explicit entry point name' do
|
130
|
+
let(:library_files) { ['mygem.rb', 'other.rb'] }
|
131
|
+
|
132
|
+
it 'selects the correct entry point' do
|
133
|
+
expect(Dir).to receive(:mkdir).with('/test/libraries')
|
134
|
+
expect(IO).to receive(:write).with('/test/libraries/mygem.rb', output[0])
|
135
|
+
expect(IO).to receive(:write).with('/test/libraries/other.rb', output[1])
|
136
|
+
described_class.write(spec, '/test', 'mygem')
|
137
|
+
end
|
138
|
+
end # /context with an explicit entry point name
|
139
|
+
|
140
|
+
context 'with an explicit entry point name ending in .rb' do
|
141
|
+
let(:library_files) { ['mygem.rb', 'other.rb'] }
|
142
|
+
|
143
|
+
it 'selects the correct entry point' do
|
144
|
+
expect(Dir).to receive(:mkdir).with('/test/libraries')
|
145
|
+
expect(IO).to receive(:write).with('/test/libraries/mygem.rb', output[0])
|
146
|
+
expect(IO).to receive(:write).with('/test/libraries/other.rb', output[1])
|
147
|
+
described_class.write(spec, '/test', 'mygem.rb')
|
148
|
+
end
|
149
|
+
end # /context with an explicit entry point name
|
150
|
+
|
151
|
+
end # /describe #write
|
152
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'halite/converter/metadata'
|
3
|
+
require 'halite/dependencies'
|
4
|
+
|
5
|
+
describe Halite::Converter::Metadata do
|
6
|
+
describe '#generate' do
|
7
|
+
let(:gem_name) { 'mygem' }
|
8
|
+
let(:cookbook_name) { gem_name }
|
9
|
+
let(:version) { '1.0.0' }
|
10
|
+
let(:license_header) { '' }
|
11
|
+
let(:cookbook_dependencies) { [] }
|
12
|
+
let(:spec) { double(name: gem_name, cookbook_name: cookbook_name, version: version, license_header: license_header, cookbook_dependencies: cookbook_dependencies.map {|dep| Halite::Dependencies::Dependency.new(*dep) }) }
|
13
|
+
subject { described_class.generate(spec) }
|
14
|
+
|
15
|
+
context 'with simple data' do
|
16
|
+
it { is_expected.to eq <<-EOH }
|
17
|
+
name "mygem"
|
18
|
+
version "1.0.0"
|
19
|
+
EOH
|
20
|
+
end # /context with simple data
|
21
|
+
|
22
|
+
context 'with a license header' do
|
23
|
+
let(:license_header) { "# header\n" }
|
24
|
+
it { is_expected.to eq <<-EOH }
|
25
|
+
# header
|
26
|
+
name "mygem"
|
27
|
+
version "1.0.0"
|
28
|
+
EOH
|
29
|
+
end # /context with a license header
|
30
|
+
|
31
|
+
context 'with one dependency' do
|
32
|
+
let(:cookbook_dependencies) { [['other', '>= 0']] }
|
33
|
+
it { is_expected.to eq <<-EOH }
|
34
|
+
name "mygem"
|
35
|
+
version "1.0.0"
|
36
|
+
depends "other", ">= 0"
|
37
|
+
EOH
|
38
|
+
end # /context with one dependency
|
39
|
+
|
40
|
+
context 'with two dependencies' do
|
41
|
+
let(:cookbook_dependencies) { [['other', '~> 1.0'], ['another', '~> 2.0.0']] }
|
42
|
+
it { is_expected.to eq <<-EOH }
|
43
|
+
name "mygem"
|
44
|
+
version "1.0.0"
|
45
|
+
depends "other", "~> 1.0"
|
46
|
+
depends "another", "~> 2.0.0"
|
47
|
+
EOH
|
48
|
+
end # /context with two dependencies
|
49
|
+
end # /describe #generate
|
50
|
+
|
51
|
+
describe '#write' do
|
52
|
+
let(:output) { double('output') } # sentinel
|
53
|
+
before { allow(described_class).to receive(:generate).and_return(output) }
|
54
|
+
|
55
|
+
it 'should write out metadata' do
|
56
|
+
expect(IO).to receive(:write).with('/test/metadata.rb', output)
|
57
|
+
described_class.write(nil, '/test')
|
58
|
+
end
|
59
|
+
end # /describe #write
|
60
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'halite/converter/other'
|
3
|
+
|
4
|
+
describe Halite::Converter::Other do
|
5
|
+
|
6
|
+
describe '#write' do
|
7
|
+
let(:files) { [] }
|
8
|
+
let(:input) { [] }
|
9
|
+
let(:output) { [] }
|
10
|
+
let(:spec) do
|
11
|
+
spec = double(name: 'mygem')
|
12
|
+
allow(spec).to receive(:each_file) do |&block|
|
13
|
+
files.each {|path| block.call(File.join('/source', path), path) }
|
14
|
+
end
|
15
|
+
spec
|
16
|
+
end
|
17
|
+
before do
|
18
|
+
files.each do |path|
|
19
|
+
input_sentinel = double("content of #{path}")
|
20
|
+
output_sentinel = double("generated output for #{path}")
|
21
|
+
allow(File).to receive(:open).with(File.join('/source', path), 'rb').and_yield(input_sentinel)
|
22
|
+
input << input_sentinel
|
23
|
+
output << output_sentinel
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with a single file' do
|
28
|
+
let(:files) { ['recipes/default.rb'] }
|
29
|
+
|
30
|
+
it 'writes a single file' do
|
31
|
+
expect(FileUtils).to receive(:mkdir_p).with('/test/recipes')
|
32
|
+
expect(File).to receive(:open).with('/test/recipes/default.rb', 'wb').and_yield(output[0])
|
33
|
+
expect(IO).to receive(:copy_stream).with(input[0], output[0])
|
34
|
+
described_class.write(spec, '/test')
|
35
|
+
end
|
36
|
+
end # /context with a single file
|
37
|
+
|
38
|
+
context 'with multiple files' do
|
39
|
+
let(:files) { ['attributes.rb', 'recipes/default.rb', 'templates/default/conf.erb'] }
|
40
|
+
|
41
|
+
it 'writes multiple files' do
|
42
|
+
expect(FileUtils).to receive(:mkdir_p).with('/test/recipes')
|
43
|
+
expect(FileUtils).to receive(:mkdir_p).with('/test/templates/default')
|
44
|
+
expect(File).to receive(:open).with('/test/attributes.rb', 'wb').and_yield(output[0])
|
45
|
+
expect(IO).to receive(:copy_stream).with(input[0], output[0])
|
46
|
+
expect(File).to receive(:open).with('/test/recipes/default.rb', 'wb').and_yield(output[1])
|
47
|
+
expect(IO).to receive(:copy_stream).with(input[1], output[1])
|
48
|
+
expect(File).to receive(:open).with('/test/templates/default/conf.erb', 'wb').and_yield(output[2])
|
49
|
+
expect(IO).to receive(:copy_stream).with(input[2], output[2])
|
50
|
+
described_class.write(spec, '/test')
|
51
|
+
end
|
52
|
+
end # /context with a single file
|
53
|
+
|
54
|
+
end # /describe #write
|
55
|
+
|
56
|
+
end
|