Class: Retrospec

Inherits:
Object
  • Object
show all
Defined in:
lib/retrospec.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(supplied_module_path = nil, opts = {}) ⇒ Retrospec

module path is the relative or absolute path to the module that should retro fitted opts hash contains additional flags and options that can be user to control the creation of the tests opts opts opts



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/retrospec.rb', line 25

def initialize(supplied_module_path=nil,opts={})
  Utilities::PuppetModule.instance.future_parser = opts[:enable_future_parser]
  # user supplied a template path or user wants to use local templates
  if opts[:template_dir] or opts[:enable_user_templates]
    @template_dir = Helpers.setup_user_template_dir(opts[:template_dir])
  else
    # if user doesn't supply template directory we assume we should use the templates in this gem
    @template_dir = Helpers.gem_template_dir
  end
  begin
    Utilities::PuppetModule.instance.module_path = supplied_module_path
    Utilities::PuppetModule.create_tmp_module_path # this is required to finish initialization
    @module_path = Utilities::PuppetModule.module_path
    @spec_object = Utilities::SpecObject.new(Utilities::PuppetModule.instance)
    spec_object.enable_beaker_tests = opts[:enable_beaker_tests]
  end
end

Instance Attribute Details

#module_pathObject (readonly)

Returns the value of attribute module_path.



17
18
19
# File 'lib/retrospec.rb', line 17

def module_path
  @module_path
end

#spec_objectObject (readonly)

Returns the value of attribute spec_object.



18
19
20
# File 'lib/retrospec.rb', line 18

def spec_object
  @spec_object
end

#template_dirObject (readonly)

Returns the value of attribute template_dir.



16
17
18
# File 'lib/retrospec.rb', line 16

def template_dir
  @template_dir
end

Instance Method Details

#create_filesObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/retrospec.rb', line 43

def create_files
  safe_create_module_files
  # a Type is nothing more than a defined type or puppet class
  # we could have named this manifest but there could be multiple types
  # in a manifest.
  spec_object.types.each do |type|
     safe_create_resource_spec_files(type)
     if spec_object.enable_beaker_tests?
       safe_create_acceptance_tests(type)
     end
  end
  Utilities::PuppetModule.clean_tmp_modules_dir
  true
end

#generate_file_name(type_name) ⇒ Object

returns the filename of the type



156
157
158
159
160
# File 'lib/retrospec.rb', line 156

def generate_file_name(type_name)
  tokens = type_name.split('::')
  file_name = tokens.pop
  "#{file_name}_spec.rb"
end

#generate_file_path(type, is_acceptance_test) ⇒ Object

generates a file path for spec tests based on the resource name. An added option is to generate directory names for each parent resource as a default option at this time acceptance tests follow this same test directory layout until best practices are formed.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/retrospec.rb', line 118

def generate_file_path(type, is_acceptance_test)
  classes_dir = 'classes'
  defines_dir = 'defines'
  hosts_dir   = 'hosts'
  acceptance_dir = 'acceptance'
  case type.type
    when :hostclass
      type_dir_name = classes_dir
    when :definition
      type_dir_name = defines_dir
    else
      raise "#{type.type} retrospec does not support this resource type yet"
  end
  if is_acceptance_test
    type_dir_name = File.join('spec',acceptance_dir, type_dir_name)
  else
    type_dir_name = File.join('spec', type_dir_name)
  end
  file_name = generate_file_name(type.name)
  tokens = type.name.split('::')
  # if there are only two tokens ie. tomcat::params we dont need to create a subdirectory
  if tokens.count > 2
    # this is a deep level resource ie. tomcat::config::server::connector
    # however we don't need the tomcat directory so we can just remove it
    # this should leave us with config/server/connector_spec.rb
    tokens.delete_at(0)
    # remove the last token since its the class name
    tokens.pop
    # so lets make a directory structure out of it
    dir_name = File.join(tokens)  # config/server
    dir_name = File.join(type_dir_name,dir_name, file_name) # spec/classes/tomcat/config/server
  else
    dir_name = File.join(type_dir_name,file_name)
  end
  dir_name
end

#safe_create_acceptance_tests(type, template = File.join(template_dir,'acceptance_spec_test.erb')) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/retrospec.rb', line 106

def safe_create_acceptance_tests(type,template=File.join(template_dir,'acceptance_spec_test.erb'))
  @parameters = type.arguments
  @type = type
  file_path = File.join(module_path,generate_file_path(type, true))
  safe_create_template_file(file_path, template)
  file_path
end

#safe_create_module_filesObject

creates any file that is contained in the templates/modules_files directory structure loops through the directory looking for erb files, all other files are ignored. strips the erb extension and renders the template to the current module path filenames must named how they would appear in the normal module path. The directory structure where the file is contained



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/retrospec.rb', line 63

def safe_create_module_files
  templates = Dir.glob(File.join(template_dir,'module_files', '**', '{*,.*}')).find_all {|t| File.file?(t)}
  templates.each do |template|
    # need to remove the erb extension and rework the destination path
    if template =~ /nodesets|spec_helper_acceptance/ and !spec_object.enable_beaker_tests?
      next
    else
      dest = template.gsub(File.join(template_dir,'module_files'), module_path).gsub('.erb', '')
      safe_create_template_file(dest, template)
    end
  end
end

#safe_create_resource_spec_files(type, template = File.join(template_dir,'resource_spec_file.erb')) ⇒ Object

Creates an associated spec file for each type and even creates the subfolders for nested classes one::two::three



93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/retrospec.rb', line 93

def safe_create_resource_spec_files(type,template=File.join(template_dir,'resource_spec_file.erb'))
  spec_object.parameters = type.arguments
  spec_object.type = type
  VariableStore.populate(type)
  spec_object.resources = Resource.all(type)
  # pass the type to the variable store and it will discover all the variables and try to resolve them.
  # this does not get deep nested conditional blocks
  spec_object.resources += Conditional.all(type)
  file_path = File.join(module_path,generate_file_path(type, false))
  safe_create_template_file(file_path, template)
  file_path
end

#safe_create_template_file(path, template) ⇒ Object

path is the full path of the file to create template is the full path to the template file



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/retrospec.rb', line 78

def safe_create_template_file(path, template)
  # check to ensure parent directory exists
  file_dir_path = File.expand_path(File.dirname(path))
  if ! File.exists?(file_dir_path)
    Helpers.safe_mkdir(file_dir_path)
  end
  File.open(template) do |file|
    renderer = ERB.new(file.read, 0, '-')
    content = renderer.result spec_object.get_binding
    dest_path = File.expand_path(path)
    Helpers.safe_create_file(dest_path, content)
  end
end