test-kitchen 0.7.0 → 1.0.0.alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/.gitignore +20 -0
  2. data/.travis.yml +11 -0
  3. data/.yardopts +3 -0
  4. data/Gemfile +13 -0
  5. data/Guardfile +11 -0
  6. data/LICENSE +15 -0
  7. data/README.md +131 -0
  8. data/Rakefile +69 -0
  9. data/bin/kitchen +9 -4
  10. data/features/cli.feature +17 -0
  11. data/features/cli_init.feature +156 -0
  12. data/features/support/env.rb +14 -0
  13. data/lib/kitchen/busser.rb +166 -0
  14. data/lib/kitchen/chef_data_uploader.rb +156 -0
  15. data/lib/kitchen/cli.rb +540 -0
  16. data/lib/kitchen/collection.rb +55 -0
  17. data/lib/kitchen/color.rb +46 -0
  18. data/lib/kitchen/config.rb +223 -0
  19. data/lib/kitchen/driver/base.rb +180 -0
  20. data/lib/kitchen/driver/dummy.rb +81 -0
  21. data/lib/kitchen/driver/ssh_base.rb +192 -0
  22. data/lib/kitchen/driver.rb +42 -0
  23. data/lib/kitchen/errors.rb +52 -0
  24. data/lib/kitchen/instance.rb +327 -0
  25. data/lib/kitchen/instance_actor.rb +42 -0
  26. data/lib/kitchen/loader/yaml.rb +105 -0
  27. data/lib/kitchen/logger.rb +145 -0
  28. data/{cookbooks/test-kitchen/libraries/helpers.rb → lib/kitchen/logging.rb} +13 -9
  29. data/lib/kitchen/manager.rb +45 -0
  30. data/lib/kitchen/metadata_chopper.rb +52 -0
  31. data/lib/kitchen/platform.rb +61 -0
  32. data/lib/kitchen/rake_tasks.rb +59 -0
  33. data/lib/kitchen/shell_out.rb +65 -0
  34. data/lib/kitchen/state_file.rb +88 -0
  35. data/lib/kitchen/suite.rb +76 -0
  36. data/lib/kitchen/thor_tasks.rb +62 -0
  37. data/lib/kitchen/util.rb +79 -0
  38. data/{cookbooks/test-kitchen/recipes/erlang.rb → lib/kitchen/version.rb} +9 -6
  39. data/lib/kitchen.rb +98 -0
  40. data/lib/vendor/hash_recursive_merge.rb +74 -0
  41. data/spec/kitchen/collection_spec.rb +80 -0
  42. data/spec/kitchen/color_spec.rb +54 -0
  43. data/spec/kitchen/config_spec.rb +201 -0
  44. data/spec/kitchen/driver/dummy_spec.rb +191 -0
  45. data/spec/kitchen/instance_spec.rb +162 -0
  46. data/spec/kitchen/loader/yaml_spec.rb +243 -0
  47. data/spec/kitchen/platform_spec.rb +48 -0
  48. data/spec/kitchen/state_file_spec.rb +122 -0
  49. data/spec/kitchen/suite_spec.rb +64 -0
  50. data/spec/spec_helper.rb +47 -0
  51. data/templates/plugin/driver.rb.erb +23 -0
  52. data/templates/plugin/license_apachev2.erb +15 -0
  53. data/templates/plugin/license_gplv2.erb +18 -0
  54. data/templates/plugin/license_gplv3.erb +16 -0
  55. data/templates/plugin/license_mit.erb +22 -0
  56. data/templates/plugin/license_reserved.erb +5 -0
  57. data/templates/plugin/version.rb.erb +12 -0
  58. data/test-kitchen.gemspec +44 -0
  59. metadata +290 -82
  60. data/config/Cheffile +0 -47
  61. data/config/Kitchenfile +0 -39
  62. data/config/Vagrantfile +0 -114
  63. data/cookbooks/test-kitchen/attributes/default.rb +0 -25
  64. data/cookbooks/test-kitchen/metadata.rb +0 -27
  65. data/cookbooks/test-kitchen/recipes/chef.rb +0 -19
  66. data/cookbooks/test-kitchen/recipes/compat.rb +0 -39
  67. data/cookbooks/test-kitchen/recipes/default.rb +0 -51
  68. data/cookbooks/test-kitchen/recipes/ruby.rb +0 -29
  69. data/lib/test-kitchen/cli/destroy.rb +0 -36
  70. data/lib/test-kitchen/cli/init.rb +0 -37
  71. data/lib/test-kitchen/cli/platform_list.rb +0 -37
  72. data/lib/test-kitchen/cli/project_info.rb +0 -44
  73. data/lib/test-kitchen/cli/ssh.rb +0 -36
  74. data/lib/test-kitchen/cli/status.rb +0 -36
  75. data/lib/test-kitchen/cli/test.rb +0 -68
  76. data/lib/test-kitchen/cli.rb +0 -282
  77. data/lib/test-kitchen/dsl.rb +0 -63
  78. data/lib/test-kitchen/environment.rb +0 -166
  79. data/lib/test-kitchen/platform.rb +0 -79
  80. data/lib/test-kitchen/project/base.rb +0 -159
  81. data/lib/test-kitchen/project/cookbook.rb +0 -97
  82. data/lib/test-kitchen/project/cookbook_copy.rb +0 -58
  83. data/lib/test-kitchen/project/ruby.rb +0 -37
  84. data/lib/test-kitchen/project/supported_platforms.rb +0 -75
  85. data/lib/test-kitchen/project.rb +0 -23
  86. data/lib/test-kitchen/runner/base.rb +0 -154
  87. data/lib/test-kitchen/runner/openstack/dsl.rb +0 -39
  88. data/lib/test-kitchen/runner/openstack/environment.rb +0 -141
  89. data/lib/test-kitchen/runner/openstack.rb +0 -147
  90. data/lib/test-kitchen/runner/vagrant.rb +0 -95
  91. data/lib/test-kitchen/runner.rb +0 -21
  92. data/lib/test-kitchen/scaffold.rb +0 -88
  93. data/lib/test-kitchen/ui.rb +0 -73
  94. data/lib/test-kitchen/version.rb +0 -21
  95. data/lib/test-kitchen.rb +0 -34
@@ -0,0 +1,76 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2012, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ module Kitchen
20
+
21
+ # A Chef run_list and attribute hash that will be used in a convergence
22
+ # integration.
23
+ #
24
+ # @author Fletcher Nichol <fnichol@nichol.ca>
25
+ class Suite
26
+
27
+ # @return [String] logical name of this suite
28
+ attr_reader :name
29
+
30
+ # @return [Array] Array of Chef run_list items
31
+ attr_reader :run_list
32
+
33
+ # @return [Hash] Hash of Chef node attributes
34
+ attr_reader :attributes
35
+
36
+ # @return [Array] Array of names of excluded platforms
37
+ attr_reader :excludes
38
+
39
+ # @return [String] local path to the suite's data bags, or nil if one does
40
+ # not exist
41
+ attr_reader :data_bags_path
42
+
43
+ # @return [String] local path to the suite's roles, or nil if one does
44
+ # not exist
45
+ attr_reader :roles_path
46
+
47
+ # Constructs a new suite.
48
+ #
49
+ # @param [Hash] options configuration for a new suite
50
+ # @option options [String] :name logical name of this suit (**Required**)
51
+ # @option options [String] :run_list Array of Chef run_list items
52
+ # (**Required**)
53
+ # @option options [Hash] :attributes Hash of Chef node attributes
54
+ # @option options [String] :excludes Array of names of excluded platforms
55
+ # @option options [String] :data_bags_path path to data bags
56
+ # @option options [String] :roles_path path to roles
57
+ def initialize(options = {})
58
+ validate_options(options)
59
+
60
+ @name = options[:name]
61
+ @run_list = options[:run_list]
62
+ @attributes = options[:attributes] || Hash.new
63
+ @excludes = options[:excludes] || Array.new
64
+ @data_bags_path = options[:data_bags_path]
65
+ @roles_path = options[:roles_path]
66
+ end
67
+
68
+ private
69
+
70
+ def validate_options(opts)
71
+ [:name, :run_list].each do |k|
72
+ raise ClientError, "Suite#new requires option :#{k}" if opts[k].nil?
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,62 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2012, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'thor'
20
+
21
+ require 'kitchen'
22
+
23
+ module Kitchen
24
+
25
+ # Kitchen Thor task generator.
26
+ #
27
+ # @author Fletcher Nichol <fnichol@nichol.ca>
28
+ class ThorTasks < Thor
29
+
30
+ namespace :kitchen
31
+
32
+ # Creates Kitchen Thor tasks and allows the callee to configure it.
33
+ #
34
+ # @yield [self] gives itself to the block
35
+ def initialize(*args)
36
+ super
37
+ @config = Kitchen::Config.new
38
+ @config.supervised = false
39
+ Kitchen.logger = Kitchen.default_file_logger
40
+ yield self if block_given?
41
+ define
42
+ end
43
+
44
+ private
45
+
46
+ attr_reader :config
47
+
48
+ def define
49
+ config.instances.each do |instance|
50
+ self.class.desc instance.name, "Run #{instance.name} test instance"
51
+ self.class.send(:define_method, instance.name.gsub(/-/, '_')) do
52
+ instance.test(:always)
53
+ end
54
+ end
55
+
56
+ self.class.desc "all", "Run all test instances"
57
+ self.class.send(:define_method, :all) do
58
+ config.instances.each { |i| invoke i.name.gsub(/-/, '_') }
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,79 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2012, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ module Kitchen
20
+
21
+ # Stateless utility methods used in different contexts. Essentially a mini
22
+ # PassiveSupport library.
23
+ module Util
24
+
25
+ def self.to_camel_case(str)
26
+ str.split('_').map { |w| w.capitalize }.join
27
+ end
28
+
29
+ def self.to_snake_case(str)
30
+ str.split('::').
31
+ last.
32
+ gsub(/([A-Z+])([A-Z][a-z])/, '\1_\2').
33
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
34
+ downcase
35
+ end
36
+
37
+ def self.to_logger_level(symbol)
38
+ return nil unless [:debug, :info, :warn, :error, :fatal].include?(symbol)
39
+
40
+ Logger.const_get(symbol.to_s.upcase)
41
+ end
42
+
43
+ def self.from_logger_level(const)
44
+ case const
45
+ when Logger::DEBUG then :debug
46
+ when Logger::INFO then :info
47
+ when Logger::WARN then :warn
48
+ when Logger::ERROR then :error
49
+ else :fatal
50
+ end
51
+ end
52
+
53
+ def self.symbolized_hash(obj)
54
+ if obj.is_a?(Hash)
55
+ obj.inject({}) { |h, (k, v)| h[k.to_sym] = symbolized_hash(v) ; h }
56
+ elsif obj.is_a?(Array)
57
+ obj.inject([]) { |a, v| a << symbolized_hash(v) ; a }
58
+ else
59
+ obj
60
+ end
61
+ end
62
+
63
+ def self.stringified_hash(obj)
64
+ if obj.is_a?(Hash)
65
+ obj.inject({}) { |h, (k, v)| h[k.to_s] = symbolized_hash(v) ; h }
66
+ elsif obj.is_a?(Array)
67
+ obj.inject([]) { |a, v| a << symbolized_hash(v) ; a }
68
+ else
69
+ obj
70
+ end
71
+ end
72
+
73
+ def self.duration(total)
74
+ minutes = (total / 60).to_i
75
+ seconds = (total - (minutes * 60))
76
+ "(%dm%.2fs)" % [minutes, seconds]
77
+ end
78
+ end
79
+ end
@@ -1,19 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  #
2
- # Author:: Seth Chisamore (<schisamo@opscode.com>)
3
- # Copyright:: Copyright (c) 2012 Opscode, Inc.
4
- # License:: Apache License, Version 2.0
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2012, Fletcher Nichol
5
6
  #
6
7
  # Licensed under the Apache License, Version 2.0 (the "License");
7
8
  # you may not use this file except in compliance with the License.
8
9
  # You may obtain a copy of the License at
9
10
  #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
+ # http://www.apache.org/licenses/LICENSE-2.0
11
12
  #
12
13
  # Unless required by applicable law or agreed to in writing, software
13
14
  # distributed under the License is distributed on an "AS IS" BASIS,
14
15
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
16
  # See the License for the specific language governing permissions and
16
17
  # limitations under the License.
17
- #
18
18
 
19
- # TODO - write this!
19
+ module Kitchen
20
+
21
+ VERSION = "1.0.0.alpha.0"
22
+ end
data/lib/kitchen.rb ADDED
@@ -0,0 +1,98 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2012, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'celluloid'
20
+ require 'pathname'
21
+ require 'thread'
22
+
23
+ require 'kitchen/errors'
24
+ require 'kitchen/logger'
25
+ require 'kitchen/logging'
26
+ require 'kitchen/shell_out'
27
+ require 'kitchen/util'
28
+
29
+ require 'kitchen/busser'
30
+ require 'kitchen/chef_data_uploader'
31
+ require 'kitchen/color'
32
+ require 'kitchen/collection'
33
+ require 'kitchen/config'
34
+ require 'kitchen/driver'
35
+ require 'kitchen/driver/base'
36
+ require 'kitchen/driver/ssh_base'
37
+ require 'kitchen/instance'
38
+ require 'kitchen/instance_actor'
39
+ require 'kitchen/loader/yaml'
40
+ require 'kitchen/manager'
41
+ require 'kitchen/metadata_chopper'
42
+ require 'kitchen/platform'
43
+ require 'kitchen/state_file'
44
+ require 'kitchen/suite'
45
+ require 'kitchen/version'
46
+
47
+ module Kitchen
48
+
49
+ class << self
50
+
51
+ attr_accessor :logger
52
+ attr_accessor :crashes
53
+ attr_accessor :mutex
54
+
55
+ # Returns the root path of the Kitchen gem source code.
56
+ #
57
+ # @return [Pathname] root path of gem
58
+ def source_root
59
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
60
+ end
61
+
62
+ def crashes?
63
+ ! crashes.empty?
64
+ end
65
+
66
+ def default_logger
67
+ Logger.new(:stdout => STDOUT, :level => env_log)
68
+ end
69
+
70
+ def default_file_logger
71
+ logfile = File.expand_path(File.join(".kitchen", "logs", "kitchen.log"))
72
+ Logger.new(:stdout => STDOUT, :logdev => logfile, :level => env_log)
73
+ end
74
+
75
+ private
76
+
77
+ def env_log
78
+ level = ENV['KITCHEN_LOG'] && ENV['KITCHEN_LOG'].downcase.to_sym
79
+ level = Util.to_logger_level(level) unless level.nil?
80
+ end
81
+ end
82
+
83
+ # Default log level verbosity
84
+ DEFAULT_LOG_LEVEL = :info
85
+ end
86
+
87
+ # Initialize the base logger and use that for Celluloid's logger
88
+ Kitchen.logger = Kitchen.default_logger
89
+ Celluloid.logger = Kitchen.logger
90
+
91
+ # Setup a collection of instance crash exceptions for error reporting
92
+ Kitchen.crashes = []
93
+ Celluloid.exception_handler do |exception|
94
+ Kitchen.logger.debug("An instance crashed because of #{exception.inspect}")
95
+ Kitchen.mutex.synchronize { Kitchen.crashes << exception }
96
+ end
97
+
98
+ Kitchen.mutex = Mutex.new
@@ -0,0 +1,74 @@
1
+ #
2
+ # = Hash Recursive Merge
3
+ #
4
+ # Merges a Ruby Hash recursively, Also known as deep merge.
5
+ # Recursive version of Hash#merge and Hash#merge!.
6
+ #
7
+ # Category:: Ruby
8
+ # Package:: Hash
9
+ # Author:: Simone Carletti <weppos@weppos.net>
10
+ # Copyright:: 2007-2008 The Authors
11
+ # License:: MIT License
12
+ # Link:: http://www.simonecarletti.com/
13
+ # Source:: http://gist.github.com/gists/6391/
14
+ #
15
+ module HashRecursiveMerge
16
+
17
+ #
18
+ # Recursive version of Hash#merge!
19
+ #
20
+ # Adds the contents of +other_hash+ to +hsh+,
21
+ # merging entries in +hsh+ with duplicate keys with those from +other_hash+.
22
+ #
23
+ # Compared with Hash#merge!, this method supports nested hashes.
24
+ # When both +hsh+ and +other_hash+ contains an entry with the same key,
25
+ # it merges and returns the values from both arrays.
26
+ #
27
+ # h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
28
+ # h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}}
29
+ # h1.rmerge!(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
30
+ #
31
+ # Simply using Hash#merge! would return
32
+ #
33
+ # h1.merge!(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
34
+ #
35
+ def rmerge!(other_hash)
36
+ merge!(other_hash) do |key, oldval, newval|
37
+ oldval.class == self.class ? oldval.rmerge!(newval) : newval
38
+ end
39
+ end
40
+
41
+ #
42
+ # Recursive version of Hash#merge
43
+ #
44
+ # Compared with Hash#merge!, this method supports nested hashes.
45
+ # When both +hsh+ and +other_hash+ contains an entry with the same key,
46
+ # it merges and returns the values from both arrays.
47
+ #
48
+ # Compared with Hash#merge, this method provides a different approch
49
+ # for merging nasted hashes.
50
+ # If the value of a given key is an Hash and both +other_hash+ abd +hsh
51
+ # includes the same key, the value is merged instead replaced with
52
+ # +other_hash+ value.
53
+ #
54
+ # h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
55
+ # h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}}
56
+ # h1.rmerge(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
57
+ #
58
+ # Simply using Hash#merge would return
59
+ #
60
+ # h1.merge(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
61
+ #
62
+ def rmerge(other_hash)
63
+ r = {}
64
+ merge(other_hash) do |key, oldval, newval|
65
+ r[key] = oldval.class == self.class ? oldval.rmerge(newval) : newval
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+
72
+ class Hash
73
+ include HashRecursiveMerge
74
+ end
@@ -0,0 +1,80 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2012, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative '../spec_helper'
20
+ require 'ostruct'
21
+
22
+ require 'kitchen/collection'
23
+
24
+ describe Kitchen::Collection do
25
+
26
+ let(:collection) do
27
+ Kitchen::Collection.new([
28
+ obj('one'), obj('two', 'a'), obj('two', 'b'), obj('three')
29
+ ])
30
+ end
31
+
32
+ it "transparently wraps an Array" do
33
+ collection.must_be_instance_of Array
34
+ end
35
+
36
+ describe "#get" do
37
+
38
+ it "returns a single object by its name" do
39
+ collection.get('three').must_equal obj('three')
40
+ end
41
+
42
+ it "returns the first occurance of an object by its name" do
43
+ collection.get('two').must_equal obj('two', 'a')
44
+ end
45
+
46
+ it "returns nil if an object cannot be found by its name" do
47
+ collection.get('nope').must_be_nil
48
+ end
49
+ end
50
+
51
+ describe "#get_all" do
52
+
53
+ it "returns a Collection of objects whose name matches the regex" do
54
+ result = collection.get_all(/(one|three)/)
55
+ result.size.must_equal 2
56
+ result[0].must_equal obj('one')
57
+ result[1].must_equal obj('three')
58
+ result.get_all(/one/).size.must_equal 1
59
+ end
60
+
61
+ it "returns an empty Collection if on matches are found" do
62
+ result = collection.get_all(/noppa/)
63
+ result.must_equal []
64
+ result.get("nahuh").must_be_nil
65
+ end
66
+ end
67
+
68
+ describe "#as_name" do
69
+
70
+ it "returns an Array of names as strings" do
71
+ collection.as_names.must_equal %w{one two two three}
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def obj(name, extra = nil)
78
+ OpenStruct.new(:name => name, :extra => extra)
79
+ end
80
+ end
@@ -0,0 +1,54 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2013, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative '../spec_helper'
20
+
21
+ require 'kitchen/color'
22
+
23
+ describe Kitchen::Color do
24
+
25
+ describe ".escape" do
26
+
27
+ it "returns an empty string if name is nil" do
28
+ Kitchen::Color.escape(nil).must_equal ""
29
+ end
30
+
31
+ it "returns an empty string if name is not in the ANSI hash" do
32
+ Kitchen::Color.escape(:puce).must_equal ""
33
+ end
34
+
35
+ it "returns an ansi escape sequence string for cyan" do
36
+ Kitchen::Color.escape(:cyan).must_equal "\e[36m"
37
+ end
38
+
39
+ it "returns an ansi escape sequence string for reset" do
40
+ Kitchen::Color.escape(:reset).must_equal "\e[0m"
41
+ end
42
+ end
43
+
44
+ describe ".colorize" do
45
+
46
+ it "returns an ansi escaped string colored yellow" do
47
+ Kitchen::Color.colorize("hello", :yellow).must_equal "\e[33mhello\e[0m"
48
+ end
49
+
50
+ it "returns an unescaped string if color is not in the ANSI hash" do
51
+ Kitchen::Color.colorize("double", :rainbow).must_equal "double"
52
+ end
53
+ end
54
+ end