test-kitchen 1.4.2 → 1.5.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.travis.yml +27 -2
- data/CHANGELOG.md +40 -1
- data/Gemfile.proxy_tests +6 -0
- data/features/kitchen_driver_discover_command.feature +6 -0
- data/features/kitchen_init_command.feature +5 -3
- data/features/step_definitions/gem_steps.rb +12 -4
- data/features/step_definitions/git_steps.rb +1 -1
- data/features/step_definitions/output_steps.rb +1 -1
- data/features/support/env.rb +13 -9
- data/lib/kitchen/cli.rb +3 -0
- data/lib/kitchen/command/driver_discover.rb +8 -0
- data/lib/kitchen/configurable.rb +32 -0
- data/lib/kitchen/driver/ssh_base.rb +18 -4
- data/lib/kitchen/generator/driver_create.rb +2 -2
- data/lib/kitchen/lazy_hash.rb +20 -0
- data/lib/kitchen/provisioner/base.rb +16 -1
- data/lib/kitchen/provisioner/chef_base.rb +42 -98
- data/lib/kitchen/provisioner/chef_solo.rb +6 -4
- data/lib/kitchen/provisioner/chef_zero.rb +7 -5
- data/lib/kitchen/transport/winrm.rb +36 -2
- data/lib/kitchen/verifier/base.rb +18 -1
- data/lib/kitchen/verifier/busser.rb +12 -5
- data/lib/kitchen/verifier/shell.rb +101 -0
- data/lib/kitchen/version.rb +1 -1
- data/spec/kitchen/configurable_spec.rb +211 -2
- data/spec/kitchen/driver/ssh_base_spec.rb +131 -8
- data/spec/kitchen/lazy_hash_spec.rb +27 -0
- data/spec/kitchen/provisioner/base_spec.rb +25 -0
- data/spec/kitchen/provisioner/chef_base_spec.rb +133 -252
- data/spec/kitchen/provisioner/chef_solo_spec.rb +17 -0
- data/spec/kitchen/provisioner/chef_zero_spec.rb +14 -2
- data/spec/kitchen/provisioner/shell_spec.rb +60 -12
- data/spec/kitchen/transport/winrm_spec.rb +50 -0
- data/spec/kitchen/verifier/base_spec.rb +26 -0
- data/spec/kitchen/verifier/busser_spec.rb +69 -3
- data/spec/kitchen/verifier/shell_spec.rb +157 -0
- data/support/busser_install_command.sh +1 -2
- data/test-kitchen.gemspec +10 -2
- metadata +86 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adede1e7727afe32740d4f4b60452b704f4326ee
|
4
|
+
data.tar.gz: cfd3c1e7ea3517a9d9bbdc8b3b1e135dd546f26b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d3dfad8e69eb236fd38ca05e233245342140823b94cf9d7cea0b56f5ec6bbae1aba59494c728fe768dc29e51fd3ee817e764836751e1187f996f6566385b758
|
7
|
+
data.tar.gz: 4cb4852bb1977639bbb5068420ba26c170f5594d1e21b12be1dec4c6cd6a464ab7426640324066e7545b768c8865d401d1a5d6969f97fc2cdb200fd064ad6020
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
3
|
rvm:
|
4
|
-
- 2.2
|
4
|
+
- 2.2.3
|
5
5
|
- 2.1
|
6
6
|
- 2.0.0
|
7
|
-
- 1.9.3
|
8
7
|
- ruby-head
|
9
8
|
|
10
9
|
env:
|
@@ -24,6 +23,32 @@ bundler_args: --without guard
|
|
24
23
|
sudo: false
|
25
24
|
|
26
25
|
matrix:
|
26
|
+
include:
|
27
|
+
- rvm: 2.2
|
28
|
+
sudo: required
|
29
|
+
dist: trusty
|
30
|
+
# To run the proxy tests we need additional gems than what Test Kitchen normally uses
|
31
|
+
# for testing
|
32
|
+
gemfile: Gemfile.proxy_tests
|
33
|
+
before_install:
|
34
|
+
- sudo apt-get update
|
35
|
+
- sudo apt-get -y install squid3 git curl
|
36
|
+
env:
|
37
|
+
# ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']
|
38
|
+
- secure: "E7h427Y8z6Nx5sdrA4Ye9gO9pDGpe4jxfhJdM4HPJIM/FSkEJM0ZDPdvhQ6QAQ1S1AHja/JhQUFaNP5NzKhRkVqGCzunBBC6RVb7pp1Qo16EMhJkg7LEsExiSsjQykAzt2w6K/71V+mIlMKxCPYdpu6PT/8w/jZFgBqLEHXuogU="
|
39
|
+
- global:
|
40
|
+
- PROXY_TESTS_DIR=proxy_tests/files/default/scripts
|
41
|
+
- PROXY_TESTS_REPO=$PROXY_TESTS_DIR/repo
|
42
|
+
|
43
|
+
script:
|
44
|
+
- bundle exec kitchen --version
|
45
|
+
# TODO switch to master when https://github.com/chef/proxy_tests/pull/12 is merged
|
46
|
+
- git clone https://github.com/chef/proxy_tests.git
|
47
|
+
- rvmsudo -E bundle exec bash $PROXY_TESTS_DIR/run_tests.sh kitchen \* \* /tmp/out.txt
|
48
|
+
after_script:
|
49
|
+
- cat /tmp/out.txt
|
50
|
+
- sudo cat /var/log/squid3/cache.log
|
51
|
+
- sudo cat /var/log/squid3/access.log
|
27
52
|
allow_failures:
|
28
53
|
- rvm: ruby-head
|
29
54
|
exclude:
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,29 @@
|
|
1
|
-
## 1.
|
1
|
+
## 1.5.0
|
2
|
+
|
3
|
+
### Potentially breaking changes
|
4
|
+
|
5
|
+
### Bug fixes
|
6
|
+
|
7
|
+
* PR [#816][]: Fix SuSe OS Busser install ([@Peuserik][])
|
8
|
+
* PR [#833][]: Updates the gem path to install everything in /tmp/verifier ([@scotthain][])
|
9
|
+
* PR [#878][]: write install_command to file and invoke on the instance to avoid command too long on windows ([@mwrock][])
|
10
|
+
|
11
|
+
### New features
|
12
|
+
|
13
|
+
* PR [#741][]: Add shell verifier ([@sawanoboly][])
|
14
|
+
* PR [#752][]: Make lazyhash enumerable ([@caboteria][])
|
15
|
+
* PR [#892][]: Adding proxy tests to the Travis.yml ([@tyler-ball][])
|
16
|
+
* PR [#895][]: Adding in ChefConfig support to enable loading proxy config from chef config files ([@tyler-ball][])
|
17
|
+
|
18
|
+
### Improvements
|
19
|
+
|
20
|
+
* PR [#782][]: Use [`mixlib-install`](https://github.com/chef/mixlib-install) to generate chef install command. ([@thommay][])
|
21
|
+
* PR [#804][]: Drop Ruby 1.9 from TravisCI build matrix ([@thommay][])
|
22
|
+
* PR [#813][]: Honor proxy ENV variables ([@mcquin][])
|
23
|
+
* PR [#885][]: Running the chef_base provisioner install_command via sudo, and command_prefix support ([@adamleff][])
|
24
|
+
* PR [#896][]: Fixing garbled output for chef_zero provisioner ([@someara][])
|
25
|
+
|
26
|
+
## 1.4.2 / 2015-08-03
|
2
27
|
|
3
28
|
### Potentially breaking changes
|
4
29
|
|
@@ -769,12 +794,26 @@ The initial release.
|
|
769
794
|
[#734]: https://github.com/test-kitchen/test-kitchen/issues/734
|
770
795
|
[#736]: https://github.com/test-kitchen/test-kitchen/issues/736
|
771
796
|
[#737]: https://github.com/test-kitchen/test-kitchen/issues/737
|
797
|
+
[#741]: https://github.com/test-kitchen/test-kitchen/issues/741
|
798
|
+
[#752]: https://github.com/test-kitchen/test-kitchen/issues/752
|
799
|
+
[#782]: https://github.com/test-kitchen/test-kitchen/issues/782
|
772
800
|
[#801]: https://github.com/test-kitchen/test-kitchen/issues/801
|
773
801
|
[#802]: https://github.com/test-kitchen/test-kitchen/issues/802
|
802
|
+
[#804]: https://github.com/test-kitchen/test-kitchen/issues/804
|
803
|
+
[#813]: https://github.com/test-kitchen/test-kitchen/issues/813
|
804
|
+
[#816]: https://github.com/test-kitchen/test-kitchen/issues/816
|
805
|
+
[#833]: https://github.com/test-kitchen/test-kitchen/issues/833
|
806
|
+
[#878]: https://github.com/test-kitchen/test-kitchen/issues/878
|
807
|
+
[#885]: https://github.com/test-kitchen/test-kitchen/issues/885
|
808
|
+
[#892]: https://github.com/test-kitchen/test-kitchen/issues/892
|
809
|
+
[#895]: https://github.com/test-kitchen/test-kitchen/issues/895
|
810
|
+
[#896]: https://github.com/test-kitchen/test-kitchen/issues/896
|
774
811
|
[@Annih]: https://github.com/Annih
|
775
812
|
[@ChrisLundquist]: https://github.com/ChrisLundquist
|
776
813
|
[@MarkGibbons]: https://github.com/MarkGibbons
|
814
|
+
[@Peuserik]: https://github.com/Peuserik
|
777
815
|
[@adamhjk]: https://github.com/adamhjk
|
816
|
+
[@adamleff]: https://github.com/adamleff
|
778
817
|
[@afiune]: https://github.com/afiune
|
779
818
|
[@arangamani]: https://github.com/arangamani
|
780
819
|
[@arunthampi]: https://github.com/arunthampi
|
data/Gemfile.proxy_tests
ADDED
@@ -17,3 +17,9 @@ Feature: Search RubyGems to discover new Test Kitchen Driver gems
|
|
17
17
|
When I run `kitchen driver discover`
|
18
18
|
Then the exit status should be 0
|
19
19
|
And the output should contain "kitchen-bluebox"
|
20
|
+
|
21
|
+
Scenario: Running driver discover with the --chef-config-path parameter loads the chef config
|
22
|
+
Given an empty file named "kitchen_client.rb"
|
23
|
+
When I run `kitchen driver discover --chef-config-path=kitchen_client.rb`
|
24
|
+
Then the exit status should be 0
|
25
|
+
And the output should contain "kitchen-bluebox"
|
@@ -3,6 +3,9 @@ Feature: Add Test Kitchen support to an existing project
|
|
3
3
|
As an operator
|
4
4
|
I want to run a command to initialize my project
|
5
5
|
|
6
|
+
Background:
|
7
|
+
Given a sandboxed GEM_HOME directory named "kitchen-init"
|
8
|
+
|
6
9
|
@spawn
|
7
10
|
Scenario: Displaying help
|
8
11
|
When I run `kitchen help init`
|
@@ -15,8 +18,7 @@ Feature: Add Test Kitchen support to an existing project
|
|
15
18
|
|
16
19
|
@spawn
|
17
20
|
Scenario: Running init with default values
|
18
|
-
Given
|
19
|
-
And I have a git repository
|
21
|
+
Given I have a git repository
|
20
22
|
When I run `kitchen init`
|
21
23
|
Then the exit status should be 0
|
22
24
|
And a directory named "test/integration/default" should exist
|
@@ -173,7 +175,7 @@ Feature: Add Test Kitchen support to an existing project
|
|
173
175
|
"""
|
174
176
|
|
175
177
|
Scenario: Running without git doesn't make a .gitignore
|
176
|
-
When I successfully run `kitchen init`
|
178
|
+
When I successfully run `kitchen init --no-driver`
|
177
179
|
Then the exit status should be 0
|
178
180
|
And a file named ".gitignore" should not exist
|
179
181
|
|
@@ -10,19 +10,27 @@ Given(/^a sandboxed GEM_HOME directory named "(.*?)"$/) do |name|
|
|
10
10
|
@aruba_timeout_seconds = 30
|
11
11
|
|
12
12
|
gem_home = Pathname.new(Dir.mktmpdir(name))
|
13
|
-
|
14
|
-
|
13
|
+
aruba.environment["GEM_HOME"] = gem_home.to_s
|
14
|
+
aruba.environment["GEM_PATH"] = [gem_home.to_s, ENV["GEM_PATH"]].join(":")
|
15
15
|
@cleanup_dirs << gem_home
|
16
16
|
end
|
17
17
|
|
18
18
|
Then(/^a gem named "(.*?)" is installed with version "(.*?)"$/) do |name, version|
|
19
19
|
unbundlerize do
|
20
|
-
run_simple(
|
20
|
+
run_simple(
|
21
|
+
sanitize_text("gem list #{name} --version #{version} -i"),
|
22
|
+
:fail_on_error => true,
|
23
|
+
:exit_timeout => nil
|
24
|
+
)
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
24
28
|
Then(/^a gem named "(.*?)" is installed$/) do |name|
|
25
29
|
unbundlerize do
|
26
|
-
run_simple(
|
30
|
+
run_simple(
|
31
|
+
sanitize_text("gem list #{name} -i"),
|
32
|
+
:fail_on_error => true,
|
33
|
+
:exit_timeout => nil
|
34
|
+
)
|
27
35
|
end
|
28
36
|
end
|
data/features/support/env.rb
CHANGED
@@ -31,12 +31,12 @@ Before do
|
|
31
31
|
@aruba_timeout_seconds = 15
|
32
32
|
@cleanup_dirs = []
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
aruba.config.command_launcher = :in_process
|
35
|
+
aruba.config.main_class = ArubaHelper
|
36
36
|
end
|
37
37
|
|
38
38
|
Before("@spawn") do
|
39
|
-
|
39
|
+
aruba.config.command_launcher = :spawn
|
40
40
|
end
|
41
41
|
|
42
42
|
After do |s|
|
@@ -47,25 +47,29 @@ After do |s|
|
|
47
47
|
|
48
48
|
# Restore environment variables to their original settings, if they have
|
49
49
|
# been saved off
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
env = aruba.environment
|
51
|
+
env.to_h.keys.select { |key| key =~ /^_CUKE_/ }.
|
52
|
+
each do |backup_key|
|
53
|
+
env[backup_key.sub(/^_CUKE_/, "")] = env[backup_key]
|
54
|
+
env.delete(backup_key)
|
55
|
+
end
|
53
56
|
|
54
57
|
@cleanup_dirs.each { |dir| FileUtils.rm_rf(dir) }
|
55
58
|
end
|
56
59
|
|
57
60
|
def backup_envvar(key)
|
58
|
-
|
61
|
+
aruba.environment["_CUKE_#{key}"] = aruba.environment[key]
|
59
62
|
end
|
60
63
|
|
61
64
|
def restore_envvar(key)
|
62
|
-
|
65
|
+
aruba.environment[key] = aruba.environment["_CUKE_#{key}"]
|
66
|
+
aruba.environment.delete("_CUKE_#{key}")
|
63
67
|
end
|
64
68
|
|
65
69
|
def unbundlerize
|
66
70
|
keys = %w[BUNDLER_EDITOR BUNDLE_BIN_PATH BUNDLE_GEMFILE RUBYOPT]
|
67
71
|
|
68
|
-
keys.each { |key| backup_envvar(key);
|
72
|
+
keys.each { |key| backup_envvar(key); aruba.environment.delete(key) }
|
69
73
|
yield
|
70
74
|
keys.each { |key| restore_envvar(key) }
|
71
75
|
end
|
data/lib/kitchen/cli.rb
CHANGED
@@ -287,6 +287,9 @@ module Kitchen
|
|
287
287
|
guarenteed that every result is a driver, but chances are good most
|
288
288
|
relevant drivers will be returned.
|
289
289
|
D
|
290
|
+
method_option :chef_config_path,
|
291
|
+
:default => nil,
|
292
|
+
:desc => "Path to chef config file containing proxy configuration to use"
|
290
293
|
def discover
|
291
294
|
perform("discover", "driver_discover", args)
|
292
295
|
end
|
@@ -19,6 +19,8 @@
|
|
19
19
|
require "kitchen/command"
|
20
20
|
|
21
21
|
require "rubygems/spec_fetcher"
|
22
|
+
require "chef-config/config"
|
23
|
+
require "chef-config/workstation_config_loader"
|
22
24
|
|
23
25
|
module Kitchen
|
24
26
|
|
@@ -31,6 +33,12 @@ module Kitchen
|
|
31
33
|
|
32
34
|
# Invoke the command.
|
33
35
|
def call
|
36
|
+
# We are introducing the idea of using the Chef configuration as a
|
37
|
+
# unified config for all the ChefDK tools. The first practical
|
38
|
+
# implementation of this is 1 location to setup proxy configurations.
|
39
|
+
ChefConfig::WorkstationConfigLoader.new(options[:chef_config_path]).load
|
40
|
+
ChefConfig::Config.export_proxies
|
41
|
+
|
34
42
|
specs = fetch_gem_specs.sort { |x, y| x[0] <=> y[0] }
|
35
43
|
specs = specs[0, 49].push(["...", "..."]) if specs.size > 49
|
36
44
|
specs = specs.unshift(["Gem Name", "Latest Stable Release"])
|
data/lib/kitchen/configurable.rb
CHANGED
@@ -295,15 +295,36 @@ module Kitchen
|
|
295
295
|
# @param code [String] the shell code to be wrapped
|
296
296
|
# @return [String] wrapped shell code
|
297
297
|
# @api private
|
298
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
299
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
298
300
|
def wrap_shell_code(code)
|
299
301
|
env = []
|
300
302
|
if config[:http_proxy]
|
301
303
|
env << shell_env_var("http_proxy", config[:http_proxy])
|
302
304
|
env << shell_env_var("HTTP_PROXY", config[:http_proxy])
|
305
|
+
else
|
306
|
+
export_proxy(env, "http")
|
303
307
|
end
|
304
308
|
if config[:https_proxy]
|
305
309
|
env << shell_env_var("https_proxy", config[:https_proxy])
|
306
310
|
env << shell_env_var("HTTPS_PROXY", config[:https_proxy])
|
311
|
+
else
|
312
|
+
export_proxy(env, "https")
|
313
|
+
end
|
314
|
+
if config[:ftp_proxy]
|
315
|
+
env << shell_env_var("ftp_proxy", config[:ftp_proxy])
|
316
|
+
env << shell_env_var("FTP_PROXY", config[:ftp_proxy])
|
317
|
+
else
|
318
|
+
export_proxy(env, "ftp")
|
319
|
+
end
|
320
|
+
# if http_proxy was set from environment variable or https_proxy was set
|
321
|
+
# from environment variable, or ftp_proxy was set from environment
|
322
|
+
# variable, include no_proxy environment variable, if set.
|
323
|
+
if (!config[:http_proxy] && (ENV["http_proxy"] || ENV["HTTP_PROXY"])) ||
|
324
|
+
(!config[:https_proxy] && (ENV["https_proxy"] || ENV["HTTPS_PROXY"])) ||
|
325
|
+
(!config[:ftp_proxy] && (ENV["ftp_proxy"] || ENV["FTP_PROXY"]))
|
326
|
+
env << shell_env_var("no_proxy", ENV["no_proxy"]) if ENV["no_proxy"]
|
327
|
+
env << shell_env_var("NO_PROXY", ENV["NO_PROXY"]) if ENV["NO_PROXY"]
|
307
328
|
end
|
308
329
|
if powershell_shell?
|
309
330
|
env.join("\n").concat("\n").concat(code)
|
@@ -312,6 +333,17 @@ module Kitchen
|
|
312
333
|
end
|
313
334
|
end
|
314
335
|
|
336
|
+
# Helper method to export
|
337
|
+
#
|
338
|
+
# @param env [Array] the environment to modify
|
339
|
+
# @param code [String] the type of proxy to export, one of 'http', 'https' or 'ftp'
|
340
|
+
# @api private
|
341
|
+
def export_proxy(env, type)
|
342
|
+
env << shell_env_var("#{type}_proxy", ENV["#{type}_proxy"]) if ENV["#{type}_proxy"]
|
343
|
+
env << shell_env_var("#{type.upcase}_PROXY", ENV["#{type.upcase}_PROXY"]) if
|
344
|
+
ENV["#{type.upcase}_PROXY"]
|
345
|
+
end
|
346
|
+
|
315
347
|
# Class methods which will be mixed in on inclusion of Configurable module.
|
316
348
|
module ClassMethods
|
317
349
|
|
@@ -233,17 +233,31 @@ module Kitchen
|
|
233
233
|
[combined[:hostname], combined[:username], opts]
|
234
234
|
end
|
235
235
|
|
236
|
-
# Adds http and
|
237
|
-
# in configuration data.
|
236
|
+
# Adds http, https and ftp proxy environment variables to a command, if
|
237
|
+
# set in configuration data or on local workstation.
|
238
238
|
#
|
239
239
|
# @param cmd [String] command string
|
240
240
|
# @return [String] command string
|
241
241
|
# @api private
|
242
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize
|
242
243
|
def env_cmd(cmd)
|
243
244
|
return if cmd.nil?
|
244
245
|
env = "env"
|
245
|
-
|
246
|
-
|
246
|
+
http_proxy = config[:http_proxy] || ENV["http_proxy"] ||
|
247
|
+
ENV["HTTP_PROXY"]
|
248
|
+
https_proxy = config[:https_proxy] || ENV["https_proxy"] ||
|
249
|
+
ENV["HTTPS_PROXY"]
|
250
|
+
ftp_proxy = config[:ftp_proxy] || ENV["ftp_proxy"] ||
|
251
|
+
ENV["FTP_PROXY"]
|
252
|
+
no_proxy = if (!config[:http_proxy] && http_proxy) ||
|
253
|
+
(!config[:https_proxy] && https_proxy) ||
|
254
|
+
(!config[:ftp_proxy] && ftp_proxy)
|
255
|
+
ENV["no_proxy"] || ENV["NO_PROXY"]
|
256
|
+
end
|
257
|
+
env << " http_proxy=#{http_proxy}" if http_proxy
|
258
|
+
env << " https_proxy=#{https_proxy}" if https_proxy
|
259
|
+
env << " ftp_proxy=#{ftp_proxy}" if ftp_proxy
|
260
|
+
env << " no_proxy=#{no_proxy}" if no_proxy
|
247
261
|
|
248
262
|
env == "env" ? cmd : "#{env} #{cmd}"
|
249
263
|
end
|
data/lib/kitchen/lazy_hash.rb
CHANGED
@@ -53,6 +53,7 @@ module Kitchen
|
|
53
53
|
#
|
54
54
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
55
55
|
class LazyHash < SimpleDelegator
|
56
|
+
include Enumerable
|
56
57
|
|
57
58
|
# Creates a new LazyHash using a Hash-like object to populate itself and
|
58
59
|
# an object that can be used as context in value-callable blocks. The
|
@@ -105,6 +106,25 @@ module Kitchen
|
|
105
106
|
hash
|
106
107
|
end
|
107
108
|
|
109
|
+
# Yields each key/value pair to the provided block. Returns a new
|
110
|
+
# Hash with only the keys and rendered values for which the block
|
111
|
+
# returns true.
|
112
|
+
#
|
113
|
+
# @return [Hash] a new hash
|
114
|
+
def select(&block)
|
115
|
+
to_hash.select(&block)
|
116
|
+
end
|
117
|
+
|
118
|
+
# If no block provided, returns an enumerator over the keys and
|
119
|
+
# rendered values in the underlying object. If a block is
|
120
|
+
# provided, calls the block once for each [key, rendered_value]
|
121
|
+
# pair in the underlying object.
|
122
|
+
#
|
123
|
+
# @return [Enumerator, Array]
|
124
|
+
def each(&block)
|
125
|
+
to_hash.each(&block)
|
126
|
+
end
|
127
|
+
|
108
128
|
private
|
109
129
|
|
110
130
|
# Returns an object or invokes call with context if object is callable.
|