Class: RSpecKickstarter::Generator
- Inherits:
-
Object
- Object
- RSpecKickstarter::Generator
- Defined in:
- lib/rspec_kickstarter/generator.rb
Instance Attribute Summary collapse
-
#spec_dir ⇒ Object
Returns the value of attribute spec_dir.
Instance Method Summary collapse
-
#extract_target_class_or_module(top_level) ⇒ Object
Extracts RDoc::NormalClass/RDoc::NormalModule from RDoc::TopLevel.
-
#get_block_code(method) ⇒ Object
e.g.
-
#get_complete_class_name(c, name = c.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_ruby_parser(file_path) ⇒ Object
Creates new RDoc::Parser::Ruby instance.
-
#get_spec_path(file_path) ⇒ Object
Returns spec file path.
-
#initialize(spec_dir = './spec') ⇒ 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_string_value_to_require(file_path) ⇒ Object
Returns string value to require.
- #write_spec(file_path, force_write = false, dry_run = false) ⇒ Object
Constructor Details
#initialize(spec_dir = './spec') ⇒ Generator
13 14 15 |
# File 'lib/rspec_kickstarter/generator.rb', line 13 def initialize(spec_dir = './spec') @spec_dir = spec_dir.gsub(/\/$/, '') end |
Instance Attribute Details
#spec_dir ⇒ Object
Returns the value of attribute spec_dir.
11 12 13 |
# File 'lib/rspec_kickstarter/generator.rb', line 11 def spec_dir @spec_dir end |
Instance Method Details
#extract_target_class_or_module(top_level) ⇒ Object
Extracts RDoc::NormalClass/RDoc::NormalModule from RDoc::TopLevel.
145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/rspec_kickstarter/generator.rb', line 145 def extract_target_class_or_module(top_level) c = top_level.classes.first if c.nil? m = top_level.modules.first if m.nil? top_level.is_a?(RDoc::NormalModule) ? top_level : nil else extract_target_class_or_module(m) end else c end end |
#get_block_code(method) ⇒ Object
e.g. { |a, b| }
256 257 258 259 260 261 262 |
# File 'lib/rspec_kickstarter/generator.rb', line 256 def get_block_code(method) if method.block_params.nil? || method.block_params.empty? "" else " { |#{method.block_params}| }" end end |
#get_complete_class_name(c, name = c.name) ⇒ Object
Gets the complete class name from RDoc::NormalClass/RDoc::NormalModule instance.
162 163 164 165 166 167 168 |
# File 'lib/rspec_kickstarter/generator.rb', line 162 def get_complete_class_name(c, name = c.name) if !c.parent.name.nil? && c.parent.is_a?(RDoc::NormalModule) get_complete_class_name(c.parent, "#{c.parent.name}::#{name}") else name end end |
#get_instantiation_code(c, method) ⇒ Object
e.g.
a = stub('a')
b = stub('b')
= BarBaz.new(a, b)
218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/rspec_kickstarter/generator.rb', line 218 def get_instantiation_code(c, method) if method.singleton "" else constructor = c.method_list.find { |m| m.name == 'new' } if constructor.nil? "\n #{instance_name(c)} = #{get_complete_class_name(c)}.new" else get_params_initialization_code(constructor) + "\n #{instance_name(c)} = #{get_complete_class_name(c)}.new(#{to_param_names_array(constructor.params).join(', ')})" end end end |
#get_method_invocation_code(c, method) ⇒ Object
e.g. BarBaz.do_something(a, b) { |c| }
245 246 247 248 249 250 251 |
# File 'lib/rspec_kickstarter/generator.rb', line 245 def get_method_invocation_code(c, method) if method.singleton "#{get_complete_class_name(c)}.#{method.name}(#{to_param_names_array(method.params).join(', ')})#{get_block_code(method)}" else "#{instance_name(c)}.#{method.name}(#{to_param_names_array(method.params).join(', ')})#{get_block_code(method)}" end end |
#get_params_initialization_code(method) ⇒ Object
e.g.
a = stub('a')
b = stub('b')
237 238 239 240 |
# File 'lib/rspec_kickstarter/generator.rb', line 237 def get_params_initialization_code(method) code = to_param_names_array(method.params).map { |p| " #{p} = stub('#{p}')" }.join("\n") code.empty? ? "" : "\n#{code}" end |
#get_ruby_parser(file_path) ⇒ Object
Creates new RDoc::Parser::Ruby instance.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/rspec_kickstarter/generator.rb', line 116 def get_ruby_parser(file_path) top_level = RDoc::TopLevel.new(file_path) if RUBY_VERSION.to_f < 2.0 # reset is removed since 2.0 RDoc::TopLevel.reset() end # RDoc::Stats initialization if RUBY_VERSION.to_f >= 2.0 # Ruby 2.0 requires RDoc::Store internally. store = RDoc::Store.new top_level.store = store stats = RDoc::Stats.new(store, 1) else stats = RDoc::Stats.new(1) end RDoc::Parser::Ruby.new( top_level, file_path, File.read(file_path), RDoc::Options.new, stats ) end |
#get_spec_path(file_path) ⇒ Object
Returns spec file path. e.g. “lib/foo/bar_baz.rb” -> “spec/foo/bar_baz_spec.rb”
174 175 176 |
# File 'lib/rspec_kickstarter/generator.rb', line 174 def get_spec_path(file_path) spec_dir + '/' + file_path.gsub(/^\.\//, '').gsub(/^(lib\/)|(app\/)/, '').gsub(/\.rb$/, '_spec.rb') end |
#instance_name(c) ⇒ Object
Returns snake_case name. e.g. FooBar -> “foo_bar”
190 191 192 193 194 195 196 197 |
# File 'lib/rspec_kickstarter/generator.rb', line 190 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”]
204 205 206 |
# File 'lib/rspec_kickstarter/generator.rb', line 204 def to_param_names_array(params) params.split(',').map { |p| p.gsub(/[\(\)\s]/, '').gsub(/=.+$/, '') }.reject { |p| p.nil? || p.empty? } end |
#to_string_value_to_require(file_path) ⇒ Object
Returns string value to require. e.g. “lib/foo/bar_baz.rb” -> “foo/bar_baz”
182 183 184 |
# File 'lib/rspec_kickstarter/generator.rb', line 182 def to_string_value_to_require(file_path) file_path.gsub(/^(lib\/)|(app\/)/, '').gsub(/\.rb$/, '') end |
#write_spec(file_path, force_write = false, dry_run = false) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/rspec_kickstarter/generator.rb', line 17 def write_spec(file_path, force_write = false, dry_run = false) top_level = get_ruby_parser(file_path).scan c = extract_target_class_or_module(top_level) if c.nil? puts "#{file_path} skipped (Class/Module not found)." else spec_path = get_spec_path(file_path) if force_write && File.exist?(spec_path) # Append to the existing spec or skip existing_spec = File.read(spec_path) racking_methods = c.method_list .select { |m| m.visibility == :public } .reject { |m| existing_spec.match(m.name) } if racking_methods.empty? puts "#{spec_path} skipped." else additional_spec = "\#{racking_methods.map { |method|\n<<EACH_SPEC\n# TODO auto-generated\ndescribe '\#{method.name}' do\n it 'works' do\#{get_instantiation_code(c, method)}\#{get_params_initialization_code(method)}\n result = \#{get_method_invocation_code(c, method)}\n expect(result).not_to be_nil\n end\nend\nEACH_SPEC\n}.join(\"\\n\")}\n" last_end_not_found = true code = existing_spec.split("\n").reverse.reject { |line| if last_end_not_found last_end_not_found = line.gsub(/#.+$/, '').strip != "end" true else false end }.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 else # Create a new spec self_path = to_string_value_to_require(file_path) code = "# -*- encoding: utf-8 -*-\nrequire 'spec_helper'\nrequire '\#{self_path}'\n\ndescribe \#{get_complete_class_name(c)} do\n\n\#{c.method_list\n.select { |m| m.visibility == :public }\n.map { |method| \n<<EACH_SPEC\n# TODO auto-generated\ndescribe '\#{method.name}' do\n it 'works' do\#{get_instantiation_code(c, method)}\#{get_params_initialization_code(method)}\n result = \#{get_method_invocation_code(c, method)}\n expect(result).not_to be_nil\n end\nend\nEACH_SPEC\n}.join(\"\\n\")}\nend\n" 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 end end |