Class: RSpecKickstarter::Generator
- Inherits:
-
Object
- Object
- RSpecKickstarter::Generator
- Includes:
- ERBTemplates
- Defined in:
- lib/rspec_kickstarter/generator.rb
Overview
RSpec Code Generator
Constant Summary collapse
- RAILS_RESOURCE_METHOD_AND_HTTPMETHOD =
{ 'index' => 'get', 'new' => 'get', 'create' => 'post', 'show' => 'get', 'edit' => 'get', 'update' => 'put', 'destroy' => 'delete' }
Constants included from ERBTemplates
ERBTemplates::BASIC_METHODS_PART_TEMPLATE, ERBTemplates::BASIC_NEW_SPEC_TEMPLATE, ERBTemplates::RAILS_CONTROLLER_METHODS_PART_TEMPLATE, ERBTemplates::RAILS_CONTROLLER_NEW_SPEC_TEMPLATE, ERBTemplates::RAILS_HELPER_METHODS_PART_TEMPLATE, ERBTemplates::RAILS_HELPER_NEW_SPEC_TEMPLATE
Instance Attribute Summary collapse
-
#delta_template ⇒ Object
Returns the value of attribute delta_template.
-
#full_template ⇒ Object
Returns the value of attribute full_template.
-
#spec_dir ⇒ Object
Returns the value of attribute spec_dir.
Instance Method Summary collapse
-
#append_to_existing_spec(class_or_module, dry_run, rails_mode, spec_path) ⇒ Object
Appends new tests to the existing spec.
-
#create_new_spec(class_or_module, dry_run, rails_mode, file_path, spec_path) ⇒ Object
Creates new spec.
-
#get_block_code(method) ⇒ Object
e.g.
-
#get_complete_class_name(class_or_module, name = class_or_module.name) ⇒ Object
Gets the complete class name from RDoc::NormalClass/RDoc::NormalModule instance.
-
#get_instantiation_code(c, method) ⇒ Object
e.g.
-
#get_method_invocation_code(c, method) ⇒ Object
e.g.
-
#get_params_initialization_code(method) ⇒ Object
e.g.
-
#get_rails_helper_method_invocation_code(method) ⇒ Object
e.g.
- #get_rails_http_method(method_name) ⇒ Object
-
#get_spec_path(file_path) ⇒ Object
Returns spec file path.
-
#initialize(spec_dir = './spec', delta_template = nil, full_template = nil) ⇒ Generator
constructor
A new instance of Generator.
-
#instance_name(c) ⇒ Object
Returns snake_case name.
-
#to_param_names_array(params) ⇒ Object
Extracts parameter names as an Array.
-
#to_params_part(params) ⇒ Object
Returns params part e.g.
-
#to_string_value_to_require(file_path) ⇒ Object
Returns string value to require.
-
#write_spec(file_path, force_write = false, dry_run = false, rails_mode = false) ⇒ Object
Writes new spec or appends to the existing spec.
Constructor Details
#initialize(spec_dir = './spec', delta_template = nil, full_template = nil) ⇒ Generator
Returns a new instance of Generator.
17 18 19 20 21 |
# File 'lib/rspec_kickstarter/generator.rb', line 17 def initialize(spec_dir = './spec', delta_template = nil, full_template = nil) @spec_dir = spec_dir.gsub(/\/$/, '') @delta_template = delta_template @full_template = full_template end |
Instance Attribute Details
#delta_template ⇒ Object
Returns the value of attribute delta_template.
15 16 17 |
# File 'lib/rspec_kickstarter/generator.rb', line 15 def delta_template @delta_template end |
#full_template ⇒ Object
Returns the value of attribute full_template.
15 16 17 |
# File 'lib/rspec_kickstarter/generator.rb', line 15 def full_template @full_template end |
#spec_dir ⇒ Object
Returns the value of attribute spec_dir.
15 16 17 |
# File 'lib/rspec_kickstarter/generator.rb', line 15 def spec_dir @spec_dir end |
Instance Method Details
#append_to_existing_spec(class_or_module, dry_run, rails_mode, spec_path) ⇒ Object
Appends new tests to the existing spec.
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 154 155 156 157 158 159 160 |
# File 'lib/rspec_kickstarter/generator.rb', line 129 def append_to_existing_spec(class_or_module, dry_run, rails_mode, spec_path) existing_spec = File.read(spec_path) lacking_methods = class_or_module.method_list .select { |m| m.visibility == :public } .reject { |m| existing_spec.match(m.name) } if lacking_methods.empty? puts "#{spec_path} skipped." else # These names are used in ERB template, don't delete. methods_to_generate = lacking_methods c = class_or_module erb = RSpecKickstarter::ERBFactory.new(@delta_template).get_instance_for_appending(rails_mode, spec_path) additional_spec = erb.result(binding) last_end_not_found = true code = existing_spec.split("\n").reverse.reject { |line| before_modified = last_end_not_found last_end_not_found = line.gsub(/#.+$/, '').strip != 'end' if before_modified before_modified }.reverse.join("\n") + "\n" + additional_spec + "\nend\n" if dry_run puts "----- #{spec_path} -----" puts code else File.open(spec_path, 'w') { |f| f.write(code) } end puts "#{spec_path} modified." end end |
#create_new_spec(class_or_module, dry_run, rails_mode, file_path, spec_path) ⇒ Object
Creates new spec.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/rspec_kickstarter/generator.rb', line 102 def create_new_spec(class_or_module, dry_run, rails_mode, file_path, spec_path) # These names are used in ERB template, don't delete. methods_to_generate = class_or_module.method_list.select { |m| m.visibility == :public } c = class_or_module self_path = to_string_value_to_require(file_path) erb = RSpecKickstarter::ERBFactory.new(@full_template).get_instance_for_new_spec(rails_mode, file_path) code = erb.result(binding) if dry_run puts "----- #{spec_path} -----" puts code else if File.exist?(spec_path) puts "#{spec_path} already exists." else FileUtils.mkdir_p(File.dirname(spec_path)) File.open(spec_path, 'w') { |f| f.write(code) } puts "#{spec_path} created." end end end |
#get_block_code(method) ⇒ Object
e.g. { |a, b| }
214 215 216 217 218 219 220 |
# File 'lib/rspec_kickstarter/generator.rb', line 214 def get_block_code(method) if method.block_params.nil? || method.block_params.empty? '' else " { |#{method.block_params}| }" end end |
#get_complete_class_name(class_or_module, name = class_or_module.name) ⇒ Object
Gets the complete class name from RDoc::NormalClass/RDoc::NormalModule instance.
43 44 45 46 47 48 49 |
# File 'lib/rspec_kickstarter/generator.rb', line 43 def get_complete_class_name(class_or_module, name = class_or_module.name) if !class_or_module.parent.name.nil? && class_or_module.parent.is_a?(RDoc::NormalModule) get_complete_class_name(class_or_module.parent, "#{class_or_module.parent.name}::#{name}") else name end end |
#get_instantiation_code(c, method) ⇒ Object
e.g.
a = double('a')
b = double('b')
= BarBaz.new(a, b)
172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/rspec_kickstarter/generator.rb', line 172 def get_instantiation_code(c, method) if method.singleton '' else constructor = c.method_list.find { |m| m.name == 'new' } if constructor.nil? " #{instance_name(c)} = #{get_complete_class_name(c)}.new\n" else get_params_initialization_code(constructor) + " #{instance_name(c)} = #{get_complete_class_name(c)}.new#{to_params_part(constructor.params)}\n" end end end |
#get_method_invocation_code(c, method) ⇒ Object
e.g. BarBaz.do_something(a, b) { |c| }
199 200 201 202 |
# File 'lib/rspec_kickstarter/generator.rb', line 199 def get_method_invocation_code(c, method) target = method.singleton ? get_complete_class_name(c) : instance_name(c) "#{target}.#{method.name}#{to_params_part(method.params)}#{get_block_code(method)}" end |
#get_params_initialization_code(method) ⇒ Object
e.g.
a = double('a')
b = double('b')
191 192 193 194 |
# File 'lib/rspec_kickstarter/generator.rb', line 191 def get_params_initialization_code(method) code = to_param_names_array(method.params).map { |p| " #{p} = double('#{p}')" }.join("\n") code.empty? ? '' : "#{code}\n" end |
#get_rails_helper_method_invocation_code(method) ⇒ Object
e.g. do_something(a, b) { |c| }
207 208 209 |
# File 'lib/rspec_kickstarter/generator.rb', line 207 def get_rails_helper_method_invocation_code(method) "#{method.name}#{to_params_part(method.params)}#{get_block_code(method)}" end |
#get_rails_http_method(method_name) ⇒ Object
222 223 224 225 |
# File 'lib/rspec_kickstarter/generator.rb', line 222 def get_rails_http_method(method_name) http_method = RAILS_RESOURCE_METHOD_AND_HTTPMETHOD[method_name] http_method.nil? ? 'get' : http_method end |
#get_spec_path(file_path) ⇒ Object
Returns spec file path. e.g. “lib/foo/bar_baz.rb” -> “spec/foo/bar_baz_spec.rb”
55 56 57 |
# File 'lib/rspec_kickstarter/generator.rb', line 55 def get_spec_path(file_path) spec_dir + '/' + file_path.gsub(/^\.\//, '').gsub(%r{^(lib/)|(app/)}, '').gsub(/\.rb$/, '_spec.rb') end |
#instance_name(c) ⇒ Object
Returns snake_case name. e.g. FooBar -> “foo_bar”
71 72 73 74 75 76 77 78 |
# File 'lib/rspec_kickstarter/generator.rb', line 71 def instance_name(c) c.name .gsub(/::/, '/') .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') .gsub(/([a-z\d])([A-Z])/, '\1_\2') .tr('-', '_') .downcase end |
#to_param_names_array(params) ⇒ Object
Extracts parameter names as an Array. e.g. “()” -> [] e.g. “(a, b = ‘foo’)” -> [“a”, “b”]
85 86 87 |
# File 'lib/rspec_kickstarter/generator.rb', line 85 def to_param_names_array(params) params.split(',').map { |p| p.gsub(/[\(\)\s]/, '').gsub(/=.+$/, '') }.reject { |p| p.nil? || p.empty? } end |
#to_params_part(params) ⇒ Object
Returns params part e.g. [“a”,“b”] -> “(a, b)” e.g. [] -> “”
94 95 96 97 |
# File 'lib/rspec_kickstarter/generator.rb', line 94 def to_params_part(params) param_csv = to_param_names_array(params).join(', ') param_csv.empty? ? '' : "(#{param_csv})" end |
#to_string_value_to_require(file_path) ⇒ Object
Returns string value to require. e.g. “lib/foo/bar_baz.rb” -> “foo/bar_baz”
63 64 65 |
# File 'lib/rspec_kickstarter/generator.rb', line 63 def to_string_value_to_require(file_path) file_path.gsub(%r{^(lib/)|(app/)}, '').gsub(/\.rb$/, '') end |
#write_spec(file_path, force_write = false, dry_run = false, rails_mode = false) ⇒ Object
Writes new spec or appends to the existing spec.
26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/rspec_kickstarter/generator.rb', line 26 def write_spec(file_path, force_write = false, dry_run = false, rails_mode = false) class_or_module = RSpecKickstarter::RDocFactory.get_rdoc_class_or_module(file_path) if class_or_module spec_path = get_spec_path(file_path) if force_write && File.exist?(spec_path) append_to_existing_spec(class_or_module, dry_run, rails_mode, spec_path) else create_new_spec(class_or_module, dry_run, rails_mode, file_path, spec_path) end else puts "#{file_path} skipped (Class/Module not found)." end end |