chefspec 3.1.0.beta.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|