halite 1.0.0.rc.1
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/.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
|