chefspec 3.1.0.beta.1 → 3.1.0
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 +4 -4
- data/lib/chefspec.rb +19 -0
- data/lib/chefspec/berkshelf.rb +1 -4
- data/lib/chefspec/coverage.rb +16 -3
- data/lib/chefspec/errors.rb +27 -88
- data/lib/chefspec/extensions/chef/conditional.rb +4 -1
- data/lib/chefspec/extensions/chef/data_query.rb +12 -3
- data/lib/chefspec/librarian.rb +2 -4
- data/lib/chefspec/macros.rb +2 -0
- data/lib/chefspec/runner.rb +9 -38
- data/lib/chefspec/server.rb +74 -43
- data/lib/chefspec/util.rb +58 -0
- data/lib/chefspec/version.rb +1 -1
- metadata +24 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bf78a43443b7bf6d169b3de994c43635190082f
|
4
|
+
data.tar.gz: d6dd0630dc5f670e7037594fce9f2073bf5bc0e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d12dc6f4f2fcc138e9b36be1e5a4b8f87011906edf358b749acf28a7b8d84524efae0f33e07bb3e0c1e393265c1d5271f3067bbe1350bf8ff1d5b020f824e9dc
|
7
|
+
data.tar.gz: a9a7bf4ae1e7d085697eaec8c872113c65310bc82b13eae615fa789a8f070ab78a3d2a10566914cd0f9d8d38505671a037de447ec1cf96f8ab0cbd67afb5d87a
|
data/lib/chefspec.rb
CHANGED
@@ -30,4 +30,23 @@ require_relative 'chefspec/matchers'
|
|
30
30
|
require_relative 'chefspec/renderer'
|
31
31
|
require_relative 'chefspec/rspec'
|
32
32
|
require_relative 'chefspec/runner'
|
33
|
+
require_relative 'chefspec/util'
|
33
34
|
require_relative 'chefspec/version'
|
35
|
+
|
36
|
+
module ChefSpec
|
37
|
+
extend self
|
38
|
+
|
39
|
+
#
|
40
|
+
# The source root of the ChefSpec gem. This is useful when requiring files
|
41
|
+
# that are relative to the root of the project.
|
42
|
+
#
|
43
|
+
# @return [Pathname]
|
44
|
+
#
|
45
|
+
def root
|
46
|
+
@root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
require 'i18n'
|
51
|
+
I18n.enforce_available_locales = false
|
52
|
+
I18n.load_path << Dir[ChefSpec.root.join('locales', '*.yml').to_s]
|
data/lib/chefspec/berkshelf.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
begin
|
2
2
|
require 'berkshelf'
|
3
3
|
rescue LoadError
|
4
|
-
raise
|
5
|
-
" installed on your system before requiring chefspec/berkshelf. Install" \
|
6
|
-
" berkshelf by running:\n\n gem install berkshelf\n\nor add Berkshelf" \
|
7
|
-
" to your Gemfile:\n\n gem 'berkshelf'\n\n"
|
4
|
+
raise ChefSpec::Error::GemLoadError.new(gem: 'berkshelf', name: 'Berkshelf')
|
8
5
|
end
|
9
6
|
|
10
7
|
module ChefSpec
|
data/lib/chefspec/coverage.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
module ChefSpec
|
2
2
|
class Coverage
|
3
|
+
|
4
|
+
attr_accessor :filters
|
5
|
+
|
3
6
|
class << self
|
4
7
|
extend Forwardable
|
5
|
-
def_delegators :instance, :add, :cover!, :report
|
8
|
+
def_delegators :instance, :add, :cover!, :report!, :filters
|
6
9
|
end
|
7
10
|
|
8
11
|
include Singleton
|
@@ -12,6 +15,7 @@ module ChefSpec
|
|
12
15
|
#
|
13
16
|
def initialize
|
14
17
|
@collection = {}
|
18
|
+
@filters = []
|
15
19
|
end
|
16
20
|
|
17
21
|
#
|
@@ -20,7 +24,7 @@ module ChefSpec
|
|
20
24
|
# @param [Chef::Resource] resource
|
21
25
|
#
|
22
26
|
def add(resource)
|
23
|
-
@collection[resource.to_s] = ResourceWrapper.new(resource)
|
27
|
+
@collection[resource.to_s] = ResourceWrapper.new(resource) if filtered?(resource)
|
24
28
|
end
|
25
29
|
|
26
30
|
#
|
@@ -29,11 +33,20 @@ module ChefSpec
|
|
29
33
|
# @param [Chef::Resource] resource
|
30
34
|
#
|
31
35
|
def cover!(resource)
|
32
|
-
if wrapper = find(resource)
|
36
|
+
if filtered?(resource) && (wrapper = find(resource))
|
33
37
|
wrapper.touch!
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
41
|
+
#
|
42
|
+
# Called to check if a resource belongs to a cookbook from the specified directories
|
43
|
+
#
|
44
|
+
# @param [Chef::Resource] resource
|
45
|
+
#
|
46
|
+
def filtered?(resource)
|
47
|
+
filters.empty? || filters.any? { |f| resource.source_line =~/^#{f}/ }
|
48
|
+
end
|
49
|
+
|
37
50
|
#
|
38
51
|
# Generate a coverage report. This report **must** be generated +at_exit+
|
39
52
|
# or else the entire resource collection may not be complete!
|
data/lib/chefspec/errors.rb
CHANGED
@@ -1,99 +1,38 @@
|
|
1
1
|
module ChefSpec
|
2
|
-
|
2
|
+
module Error
|
3
|
+
class ChefSpecError < StandardError
|
4
|
+
def initialize(options = {})
|
5
|
+
class_name = self.class.to_s.split('::').last
|
6
|
+
error_key = options[:_error_key] || Util.underscore(class_name)
|
3
7
|
|
4
|
-
|
5
|
-
def initialize(command)
|
6
|
-
message = "Real commands are disabled. Unregistered command: `#{command}`"
|
7
|
-
message << "\n\n"
|
8
|
-
message << "You can stub this command with:"
|
9
|
-
message << "\n\n"
|
10
|
-
message << " #{Stubs::CommandStub.new(command).and_return(true).signature}"
|
11
|
-
|
12
|
-
unless Stubs::CommandRegistry.stubs.empty?
|
13
|
-
message << "\n\n"
|
14
|
-
message << "registered command stubs:"
|
15
|
-
message << "\n"
|
16
|
-
|
17
|
-
Stubs::CommandRegistry.stubs.each do |command|
|
18
|
-
message << "\n #{command.signature}"
|
19
|
-
end
|
8
|
+
super I18n.t("chefspec.errors.#{error_key}", options)
|
20
9
|
end
|
21
|
-
|
22
|
-
message << "\n\n"
|
23
|
-
message << "="*60
|
24
|
-
super(message)
|
25
10
|
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class SearchNotStubbedError < Error
|
29
|
-
def initialize(type, query)
|
30
|
-
message = "Real searches are disabled. Unregistered search: search(#{type.inspect}, #{query.inspect})"
|
31
|
-
message << "\n\n"
|
32
|
-
message << "You can stub this search with:"
|
33
|
-
message << "\n\n"
|
34
|
-
message << " #{Stubs::SearchStub.new(type, query).and_return({}).signature}"
|
35
11
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
12
|
+
class NotStubbed < ChefSpecError
|
13
|
+
def initialize(options = {})
|
14
|
+
name = self.class.name.to_s.split('::').last
|
15
|
+
type = Util.underscore(name).gsub('_not_stubbed', '')
|
16
|
+
klass = Stubs.const_get(name.gsub('NotStubbed', '') + 'Stub')
|
17
|
+
stub = klass.new(*options[:args]).and_return('...').signature
|
18
|
+
|
19
|
+
signature = "#{type}(#{options[:args].map(&:inspect).join(', ')})"
|
20
|
+
|
21
|
+
super({
|
22
|
+
type: type,
|
23
|
+
signature: signature,
|
24
|
+
stub: stub,
|
25
|
+
_error_key: :not_stubbed,
|
26
|
+
}.merge(options))
|
44
27
|
end
|
45
|
-
|
46
|
-
message << "\n\n"
|
47
|
-
message << "="*60
|
48
|
-
super(message)
|
49
28
|
end
|
50
|
-
end
|
51
29
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
message << "You can stub this data_bag with:"
|
57
|
-
message << "\n\n"
|
58
|
-
message << " #{Stubs::DataBagStub.new(bag).and_return({}).signature}"
|
30
|
+
class CommandNotStubbed < NotStubbed; end
|
31
|
+
class SearchNotStubbed < NotStubbed; end
|
32
|
+
class DataBagNotStubbed < NotStubbed; end
|
33
|
+
class DataBagItemNotStubbed < NotStubbed; end
|
59
34
|
|
60
|
-
|
61
|
-
|
62
|
-
message << "registered data_bag stubs:"
|
63
|
-
message << "\n"
|
64
|
-
|
65
|
-
Stubs::DataBagRegistry.stubs.each do |data_bag|
|
66
|
-
message << "\n #{data_bag.signature}"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
message << "\n\n"
|
71
|
-
message << "="*60
|
72
|
-
super(message)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
class DataBagItemNotStubbedError < Error
|
77
|
-
def initialize(bag, id)
|
78
|
-
message = "Real data_bag_items are disabled. Unregistered search: data_bag_item(#{bag.inspect}, #{id.inspect})"
|
79
|
-
message << "\n\n"
|
80
|
-
message << "You can stub this data_bag_item with:"
|
81
|
-
message << "\n\n"
|
82
|
-
message << " #{Stubs::DataBagItemStub.new(bag, id).and_return({}).signature}"
|
83
|
-
|
84
|
-
unless Stubs::DataBagItemRegistry.stubs.empty?
|
85
|
-
message << "\n\n"
|
86
|
-
message << "registered data_bag_item stubs:"
|
87
|
-
message << "\n"
|
88
|
-
|
89
|
-
Stubs::DataBagItemRegistry.stubs.each do |data_bag_item|
|
90
|
-
message << "\n #{data_bag_item.signature}"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
message << "\n\n"
|
95
|
-
message << "="*60
|
96
|
-
super(message)
|
97
|
-
end
|
35
|
+
class CookbookPathNotFound < ChefSpecError; end
|
36
|
+
class GemLoadError < ChefSpecError; end
|
98
37
|
end
|
99
38
|
end
|
@@ -4,7 +4,10 @@ class Chef::Resource::Conditional
|
|
4
4
|
# @see Chef::Resource::Conditional#evaluate_command
|
5
5
|
def evaluate_command
|
6
6
|
stub = ChefSpec::Stubs::CommandRegistry.stub_for(@command)
|
7
|
-
|
7
|
+
|
8
|
+
if stub.nil?
|
9
|
+
raise ChefSpec::Error::CommandNotStubbed.new(args: [@command])
|
10
|
+
end
|
8
11
|
|
9
12
|
stub.result
|
10
13
|
end
|
@@ -9,7 +9,10 @@ module Chef::DSL::DataQuery
|
|
9
9
|
type = args[0]
|
10
10
|
query = args[1] || '*:*'
|
11
11
|
stub = ChefSpec::Stubs::SearchRegistry.stub_for(type, query)
|
12
|
-
|
12
|
+
|
13
|
+
if stub.nil?
|
14
|
+
raise ChefSpec::Error::SearchNotStubbed.new(args: [type, query])
|
15
|
+
end
|
13
16
|
|
14
17
|
stub.result
|
15
18
|
end
|
@@ -20,7 +23,10 @@ module Chef::DSL::DataQuery
|
|
20
23
|
return old_data_bag(bag) unless Chef::Config[:solo]
|
21
24
|
|
22
25
|
stub = ChefSpec::Stubs::DataBagRegistry.stub_for(bag)
|
23
|
-
|
26
|
+
|
27
|
+
if stub.nil?
|
28
|
+
raise ChefSpec::Error::DataBagNotStubbed.new(args: [bag])
|
29
|
+
end
|
24
30
|
|
25
31
|
stub.result
|
26
32
|
end
|
@@ -31,7 +37,10 @@ module Chef::DSL::DataQuery
|
|
31
37
|
return old_data_bag_item(bag, id) unless Chef::Config[:solo]
|
32
38
|
|
33
39
|
stub = ChefSpec::Stubs::DataBagItemRegistry.stub_for(bag, id)
|
34
|
-
|
40
|
+
|
41
|
+
if stub.nil?
|
42
|
+
raise ChefSpec::Error::DataBagItemNotStubbed.new(args: [bag, id])
|
43
|
+
end
|
35
44
|
|
36
45
|
stub.result
|
37
46
|
end
|
data/lib/chefspec/librarian.rb
CHANGED
@@ -3,10 +3,8 @@ begin
|
|
3
3
|
require 'librarian/action/resolve'
|
4
4
|
require 'librarian/action/install'
|
5
5
|
rescue LoadError
|
6
|
-
raise
|
7
|
-
|
8
|
-
" Install it by running:\n\n gem install librarian-chef\n\nor add" \
|
9
|
-
" Librarian to your Gemfile:\n\n gem 'librarian-chef'\n\n"
|
6
|
+
raise ChefSpec::Error::GemLoadError.new(
|
7
|
+
gem: 'librarian-chef', name: 'Librarian')
|
10
8
|
end
|
11
9
|
|
12
10
|
module ChefSpec
|
data/lib/chefspec/macros.rb
CHANGED
@@ -167,6 +167,8 @@ module ChefSpec
|
|
167
167
|
# @option options [Hash] :ohai
|
168
168
|
# a Hash of Ohai attributes to mock on the node
|
169
169
|
#
|
170
|
+
# @return [Chef::Node]
|
171
|
+
#
|
170
172
|
def stub_node(name = 'node.example', options = {}, &block)
|
171
173
|
fauxhai = Fauxhai.mock(options).data
|
172
174
|
fauxhai = fauxhai.merge(options[:ohai] || {})
|
data/lib/chefspec/runner.rb
CHANGED
@@ -87,43 +87,6 @@ module ChefSpec
|
|
87
87
|
yield node if block_given?
|
88
88
|
end
|
89
89
|
|
90
|
-
#
|
91
|
-
# Execute the specified recipes on the node, without actually converging
|
92
|
-
# the node. This is the equivalent of `chef-apply`.
|
93
|
-
#
|
94
|
-
# @example Converging a single recipe
|
95
|
-
# chef_run.apply('example::default')
|
96
|
-
#
|
97
|
-
# @example Converging multiple recipes
|
98
|
-
# chef_run.apply('example::default', 'example::secondary')
|
99
|
-
#
|
100
|
-
#
|
101
|
-
# @param [Array] recipe_names
|
102
|
-
# The names of the recipe or recipes to apply
|
103
|
-
#
|
104
|
-
# @return [ChefSpec::Runner]
|
105
|
-
# A reference to the calling Runner (for chaining purposes)
|
106
|
-
#
|
107
|
-
def apply(*recipe_names)
|
108
|
-
recipe_names.each do |recipe_name|
|
109
|
-
cookbook, recipe = Chef::Recipe.parse_recipe_name(recipe_name)
|
110
|
-
recipe_path = File.join(Dir.pwd, 'recipes', "#{recipe}.rb")
|
111
|
-
|
112
|
-
recipe = Chef::Recipe.new(cookbook, recipe, run_context)
|
113
|
-
recipe.from_file(recipe_path)
|
114
|
-
end
|
115
|
-
|
116
|
-
# Expand the run_list
|
117
|
-
expand_run_list!
|
118
|
-
|
119
|
-
# Setup the run_context
|
120
|
-
@run_context = Chef::RunContext.new(client.node, {}, client.events)
|
121
|
-
|
122
|
-
@converging = true
|
123
|
-
@client.converge(@run_context)
|
124
|
-
self
|
125
|
-
end
|
126
|
-
|
127
90
|
#
|
128
91
|
# Execute the given `run_list` on the node, without actually converging
|
129
92
|
# the node.
|
@@ -150,8 +113,13 @@ module ChefSpec
|
|
150
113
|
# Expand the run_list
|
151
114
|
expand_run_list!
|
152
115
|
|
116
|
+
# Save the node back to the server for searching purposes
|
117
|
+
unless Chef::Config[:solo]
|
118
|
+
client.register
|
119
|
+
node.save
|
120
|
+
end
|
121
|
+
|
153
122
|
# Setup the run_context
|
154
|
-
client.register unless Chef::Config[:solo]
|
155
123
|
@run_context = client.setup_run_context
|
156
124
|
|
157
125
|
# Allow stubbing/mocking after the cookbook has been compiled but before the converge
|
@@ -299,6 +267,8 @@ module ChefSpec
|
|
299
267
|
#
|
300
268
|
def calling_cookbook_path(kaller)
|
301
269
|
calling_spec = kaller.find { |line| line =~ /\/spec/ }
|
270
|
+
raise Error::CookbookPathNotFound if calling_spec.nil?
|
271
|
+
|
302
272
|
bits = calling_spec.split(':', 2).first.split(File::SEPARATOR)
|
303
273
|
spec_dir = bits.index('spec') || 0
|
304
274
|
|
@@ -331,6 +301,7 @@ module ChefSpec
|
|
331
301
|
@client.ohai.data = Mash.from_hash(Fauxhai.mock(options).data)
|
332
302
|
@client.load_node
|
333
303
|
@client.build_node
|
304
|
+
@client.save_updated_node
|
334
305
|
@client
|
335
306
|
end
|
336
307
|
|
data/lib/chefspec/server.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
begin
|
2
2
|
require 'chef_zero/server'
|
3
3
|
rescue LoadError
|
4
|
-
raise
|
5
|
-
" installed on your system before requiring chefspec/server. Install" \
|
6
|
-
" Chef Zero by running:\n\n gem install chef-zero\n\nor add Chef Zero" \
|
7
|
-
" to your Gemfile:\n\n gem 'chef-zero'\n\n"
|
4
|
+
raise ChefSpec::Error::GemLoadError.new(gem: 'chef-zero', name: 'Chef Zero')
|
8
5
|
end
|
9
6
|
|
10
7
|
require 'chef/cookbook_loader'
|
@@ -64,6 +61,73 @@ module ChefSpec
|
|
64
61
|
instance.send(m, *args, &block)
|
65
62
|
end
|
66
63
|
|
64
|
+
#
|
65
|
+
# @macro entity
|
66
|
+
# @method create_$1(name, data = {})
|
67
|
+
# Create a new $1 on the Chef Server
|
68
|
+
#
|
69
|
+
# @param [String] name
|
70
|
+
# the name of the $1
|
71
|
+
# @param [Hash] data
|
72
|
+
# the list of data to load
|
73
|
+
#
|
74
|
+
#
|
75
|
+
# @method $1(name)
|
76
|
+
# Find a $1 at the given name
|
77
|
+
#
|
78
|
+
# @param [String] name
|
79
|
+
# the name of the $1
|
80
|
+
#
|
81
|
+
# @return [$2, nil]
|
82
|
+
#
|
83
|
+
#
|
84
|
+
# @method $3
|
85
|
+
# The list of $1 on the Chef Server
|
86
|
+
#
|
87
|
+
# @return [Array<Hash>]
|
88
|
+
# all the $1 on the Chef Server
|
89
|
+
#
|
90
|
+
#
|
91
|
+
# @method has_$1?(name)
|
92
|
+
# Determine if the Chef Server has the given $1
|
93
|
+
#
|
94
|
+
# @param [String] name
|
95
|
+
# the name of the $1 to find
|
96
|
+
#
|
97
|
+
# @return [Boolean]
|
98
|
+
#
|
99
|
+
def self.entity(method, klass, key)
|
100
|
+
class_eval <<-EOH, __FILE__, __LINE__ + 1
|
101
|
+
def create_#{method}(name, data = {})
|
102
|
+
data = JSON.fast_generate(data) unless '#{key}' == 'data'
|
103
|
+
@server.load_data('#{key}' => { name => data })
|
104
|
+
end
|
105
|
+
|
106
|
+
def #{method}(name)
|
107
|
+
data = @server.data_store.get(['#{key}', name])
|
108
|
+
json = JSON.parse(data)
|
109
|
+
|
110
|
+
if #{klass}.respond_to?(:json_create)
|
111
|
+
#{klass}.json_create(json)
|
112
|
+
else
|
113
|
+
#{klass}.new(json)
|
114
|
+
end
|
115
|
+
rescue ChefZero::DataStore::DataNotFoundError
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
|
119
|
+
def #{key}
|
120
|
+
@server.data_store.list(['#{key}'])
|
121
|
+
end
|
122
|
+
|
123
|
+
def has_#{method}?(name)
|
124
|
+
!@server.data_store.get(['#{key}', name]).nil?
|
125
|
+
rescue ChefZero::DataStore::DataNotFoundError
|
126
|
+
false
|
127
|
+
end
|
128
|
+
EOH
|
129
|
+
end
|
130
|
+
|
67
131
|
include Singleton
|
68
132
|
|
69
133
|
attr_reader :server
|
@@ -78,6 +142,12 @@ module ChefSpec
|
|
78
142
|
)
|
79
143
|
end
|
80
144
|
|
145
|
+
entity :client, Chef::Client, 'clients'
|
146
|
+
entity :data_bag, Chef::DataBag, 'data'
|
147
|
+
entity :environment, Chef::Environment, 'environments'
|
148
|
+
entity :node, Chef::Node, 'nodes'
|
149
|
+
entity :role, Chef::Role, 'roles'
|
150
|
+
|
81
151
|
#
|
82
152
|
# The path to the insecure Chef Zero private key on disk. Because Chef
|
83
153
|
# requires the path to a file instead of the contents of the key (why),
|
@@ -122,45 +192,6 @@ module ChefSpec
|
|
122
192
|
FileUtils.rm_rf(cache_dir)
|
123
193
|
end
|
124
194
|
|
125
|
-
#
|
126
|
-
# Create a client on the Chef Server.
|
127
|
-
#
|
128
|
-
def create_client(name, data = {})
|
129
|
-
load_data(:clients, name, data)
|
130
|
-
end
|
131
|
-
|
132
|
-
#
|
133
|
-
# Create a data_bag on the Chef Server.
|
134
|
-
#
|
135
|
-
def create_data_bag(name, data = {})
|
136
|
-
@server.load_data('data' => { name => data })
|
137
|
-
end
|
138
|
-
|
139
|
-
#
|
140
|
-
# Create an environment on the Chef Server.
|
141
|
-
#
|
142
|
-
def create_environment(name, data = {})
|
143
|
-
load_data(:environments, name, data)
|
144
|
-
end
|
145
|
-
|
146
|
-
#
|
147
|
-
# Create a node on the Chef Server.
|
148
|
-
#
|
149
|
-
# @note
|
150
|
-
# The current node (chefspec) is automatically registered and added to
|
151
|
-
# the Chef Server
|
152
|
-
#
|
153
|
-
def create_node(name, data = {})
|
154
|
-
load_data(:nodes, name, data)
|
155
|
-
end
|
156
|
-
|
157
|
-
#
|
158
|
-
# Create a role on the Chef Server.
|
159
|
-
#
|
160
|
-
def create_role(name, data = {})
|
161
|
-
load_data(:roles, name, data)
|
162
|
-
end
|
163
|
-
|
164
195
|
private
|
165
196
|
|
166
197
|
#
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module ChefSpec
|
2
|
+
module Util
|
3
|
+
extend self
|
4
|
+
|
5
|
+
#
|
6
|
+
# Covert the given CaMelCaSeD string to under_score. Graciously borrowed
|
7
|
+
# from http://stackoverflow.com/questions/1509915.
|
8
|
+
#
|
9
|
+
# @param [String] string
|
10
|
+
# the string to use for transformation
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
def underscore(string)
|
15
|
+
string
|
16
|
+
.to_s
|
17
|
+
.gsub(/::/, '/')
|
18
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
19
|
+
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
20
|
+
.tr('-', '_')
|
21
|
+
.downcase
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Convert an underscored string to it's camelcase equivalent constant.
|
26
|
+
#
|
27
|
+
# @param [String] string
|
28
|
+
# the string to convert
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
#
|
32
|
+
def camelize(string)
|
33
|
+
string
|
34
|
+
.to_s
|
35
|
+
.split('_')
|
36
|
+
.map { |e| e.capitalize }
|
37
|
+
.join
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Truncate the given string to a certain number of characters.
|
42
|
+
#
|
43
|
+
# @param [String] string
|
44
|
+
# the string to truncate
|
45
|
+
# @param [Hash] options
|
46
|
+
# the list of options (such as +length+)
|
47
|
+
#
|
48
|
+
def truncate(string, options = {})
|
49
|
+
length = options[:length] || 30
|
50
|
+
|
51
|
+
if string.length > length
|
52
|
+
string[0..length-3] + '...'
|
53
|
+
else
|
54
|
+
string
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/chefspec/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chefspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Crump
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: chef
|
@@ -53,6 +53,20 @@ dependencies:
|
|
53
53
|
- - ~>
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '2.14'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: i18n
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.6'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.6'
|
56
70
|
- !ruby/object:Gem::Dependency
|
57
71
|
name: chef-zero
|
58
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,6 +143,8 @@ executables: []
|
|
129
143
|
extensions: []
|
130
144
|
extra_rdoc_files: []
|
131
145
|
files:
|
146
|
+
- lib/chefspec.rb
|
147
|
+
- lib/chefspec/api.rb
|
132
148
|
- lib/chefspec/api/apt_package.rb
|
133
149
|
- lib/chefspec/api/batch.rb
|
134
150
|
- lib/chefspec/api/chef_gem.rb
|
@@ -177,7 +193,6 @@ files:
|
|
177
193
|
- lib/chefspec/api/template.rb
|
178
194
|
- lib/chefspec/api/user.rb
|
179
195
|
- lib/chefspec/api/yum_package.rb
|
180
|
-
- lib/chefspec/api.rb
|
181
196
|
- lib/chefspec/berkshelf.rb
|
182
197
|
- lib/chefspec/cacher.rb
|
183
198
|
- lib/chefspec/coverage.rb
|
@@ -193,13 +208,13 @@ files:
|
|
193
208
|
- lib/chefspec/formatter.rb
|
194
209
|
- lib/chefspec/librarian.rb
|
195
210
|
- lib/chefspec/macros.rb
|
211
|
+
- lib/chefspec/matchers.rb
|
196
212
|
- lib/chefspec/matchers/include_recipe_matcher.rb
|
197
213
|
- lib/chefspec/matchers/link_to_matcher.rb
|
198
214
|
- lib/chefspec/matchers/notifications_matcher.rb
|
199
215
|
- lib/chefspec/matchers/render_file_matcher.rb
|
200
216
|
- lib/chefspec/matchers/resource_matcher.rb
|
201
217
|
- lib/chefspec/matchers/state_attrs_matcher.rb
|
202
|
-
- lib/chefspec/matchers.rb
|
203
218
|
- lib/chefspec/mixins/normalize.rb
|
204
219
|
- lib/chefspec/renderer.rb
|
205
220
|
- lib/chefspec/rspec.rb
|
@@ -215,8 +230,8 @@ files:
|
|
215
230
|
- lib/chefspec/stubs/search_registry.rb
|
216
231
|
- lib/chefspec/stubs/search_stub.rb
|
217
232
|
- lib/chefspec/stubs/stub.rb
|
233
|
+
- lib/chefspec/util.rb
|
218
234
|
- lib/chefspec/version.rb
|
219
|
-
- lib/chefspec.rb
|
220
235
|
homepage: http://acrmp.github.com/chefspec
|
221
236
|
licenses:
|
222
237
|
- MIT
|
@@ -232,14 +247,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
232
247
|
version: '1.9'
|
233
248
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
234
249
|
requirements:
|
235
|
-
- - '
|
250
|
+
- - '>='
|
236
251
|
- !ruby/object:Gem::Version
|
237
|
-
version:
|
252
|
+
version: '0'
|
238
253
|
requirements: []
|
239
254
|
rubyforge_project:
|
240
|
-
rubygems_version: 2.
|
255
|
+
rubygems_version: 2.2.0
|
241
256
|
signing_key:
|
242
257
|
specification_version: 4
|
243
|
-
summary: chefspec-3.1.0
|
258
|
+
summary: chefspec-3.1.0
|
244
259
|
test_files: []
|
245
260
|
has_rdoc:
|