fabiokung-rfactor 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ == 0.0.1 2009-02-04
2
+
3
+ * basic extract method support:
4
+ * for code inside methods
5
+ * without identifying method parameters
6
+ * without getting method return
data/Manifest.txt ADDED
@@ -0,0 +1,24 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ features/development.feature
7
+ features/extract_method.feature
8
+ features/steps/code_steps.rb
9
+ features/steps/common.rb
10
+ features/steps/env.rb
11
+ lib/rfactor.rb
12
+ lib/rfactor/code.rb
13
+ lib/rfactor/line_finder.rb
14
+ lib/rfactor/string_ext.rb
15
+ script/console
16
+ script/destroy
17
+ script/generate
18
+ spec/code_spec.rb
19
+ spec/line_finder_spec.rb
20
+ spec/rfactor_spec.rb
21
+ spec/spec.opts
22
+ spec/spec_helper.rb
23
+ spec/string_ext_spec.rb
24
+ tasks/rspec.rake
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on rfactor, see http://rfactor.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.rdoc ADDED
@@ -0,0 +1,68 @@
1
+ = rfactor
2
+
3
+ http://wiki.github.com/fabiokung/rfactor
4
+
5
+ == DESCRIPTION:
6
+
7
+ Common refactorings for Ruby code, written in Ruby. This project aims
8
+ to be integrated with several editors (mainly TextMate), to provide
9
+ simple refactorings, such as:
10
+
11
+ * extract method
12
+ * extract Class
13
+ * extract Module
14
+ * rename using ack
15
+ * move using ack
16
+
17
+ == FEATURES/PROBLEMS:
18
+
19
+ * Uses {RubyParser}[http://parsetree.rubyforge.org] to extract ASTs
20
+
21
+ == SYNOPSIS:
22
+
23
+ code = Rfactor::Code.new(CODE)
24
+ new_code = code.extract_method :name => 'common_behavior',
25
+ :start => 10,
26
+ :end => 15
27
+ # new_code should contain the changed code. The content between
28
+ # lines 10 and 15 are extracted to the new method called common_behavior
29
+
30
+ See the features (Cucumber) directory for more examples.
31
+
32
+ == REQUIREMENTS:
33
+
34
+ * ParseTree
35
+ * modified ruby_parser, from [fabiokung's github repository](http://github.com/fabiokung/ruby_parser/tree/master)
36
+ * modified sexp_processor, from [fabiokung's github repository](http://github.com/fabiokung/sexp_processor/tree/master)
37
+
38
+ == INSTALL:
39
+
40
+ gem install ParseTree
41
+ gem install fabiokung-sexp_processor -s http://gems.github.com
42
+ gem install fabiokung-ruby_parser -s http://gems.github.com
43
+ gem install fabiokung-rfactor -s http://gems.github.com
44
+
45
+ == LICENSE:
46
+
47
+ (The MIT License)
48
+
49
+ Copyright (c) 2008 Fabio Kung <fabio.kung@gmail.com>
50
+
51
+ Permission is hereby granted, free of charge, to any person obtaining
52
+ a copy of this software and associated documentation files (the
53
+ 'Software'), to deal in the Software without restriction, including
54
+ without limitation the rights to use, copy, modify, merge, publish,
55
+ distribute, sublicense, and/or sell copies of the Software, and to
56
+ permit persons to whom the Software is furnished to do so, subject to
57
+ the following conditions:
58
+
59
+ The above copyright notice and this permission notice shall be
60
+ included in all copies or substantial portions of the Software.
61
+
62
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
63
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
64
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
65
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
66
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
67
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
68
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/rfactor'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('rfactor', Rfactor::VERSION) do |p|
7
+ p.developer('Fabio Kung', 'fabio.kung@gmail.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
10
+ p.rubyforge_name = p.name # TODO this is default value
11
+ p.extra_deps = [
12
+ ['ruby_parser','>= 2.0.1']
13
+ ]
14
+ p.extra_dev_deps = [
15
+ ['newgem', ">= #{::Newgem::VERSION}"]
16
+ ]
17
+
18
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
19
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
20
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
21
+ p.rsync_args = '-av --delete --ignore-errors'
22
+ end
23
+
24
+ require 'newgem/tasks' # load /tasks/*.rake
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
26
+
27
+ # TODO - want other tests/tasks run by default? Add them to the list
28
+ task :default => [:spec, :features]
@@ -0,0 +1,13 @@
1
+ Feature: Development processes of newgem itself (rake tasks)
2
+
3
+ As a Newgem maintainer or contributor
4
+ I want rake tasks to maintain and release the gem
5
+ So that I can spend time on the tests and code, and not excessive time on maintenance processes
6
+
7
+ Scenario: Generate RubyGem
8
+ Given this project is active project folder
9
+ And 'pkg' folder is deleted
10
+ When task 'rake gem' is invoked
11
+ Then folder 'pkg' is created
12
+ And file with name matching 'pkg/*.gem' is created else you should run "rake manifest" to fix this
13
+ And gem spec key 'rdoc_options' contains /--mainREADME.rdoc/
@@ -0,0 +1,69 @@
1
+ Feature: Extract Method
2
+ In order to improve my code's quality
3
+ As a developer
4
+ I want to extract methods
5
+
6
+ Scenario: Simple code, no variables, one method
7
+ Given I have the following code:
8
+ """
9
+ def the_method(firstArg, secondArg)
10
+ puts "some"
11
+ puts :code
12
+ puts /to be/
13
+ puts 'refactored'
14
+ end
15
+ """
16
+ And lines from 3 to 5 are selected
17
+ And I want them to be in the method called 'other_method'
18
+ When I call 'extract method'
19
+ Then the code should be:
20
+ """
21
+ def the_method(firstArg, secondArg)
22
+ puts "some"
23
+ other_method()
24
+ end
25
+
26
+ def other_method()
27
+ puts :code
28
+ puts /to be/
29
+ puts 'refactored'
30
+ end
31
+
32
+ """
33
+
34
+ Scenario: Simple code, no variables, many methods
35
+ Given I have the following code:
36
+ """
37
+ def the_method(firstArg, secondArg)
38
+ puts :code
39
+ puts /to be/
40
+ puts 'refactored'
41
+ end
42
+
43
+ def more()
44
+ n = 3+2/7
45
+ puts "other #{n}"
46
+ n
47
+ end
48
+ """
49
+ And lines from 3 to 4 are selected
50
+ And I want them to be in the method called 'new_method'
51
+ When I call 'extract method'
52
+ Then the code should be:
53
+ """
54
+ def the_method(firstArg, secondArg)
55
+ puts :code
56
+ new_method()
57
+ end
58
+
59
+ def new_method()
60
+ puts /to be/
61
+ puts 'refactored'
62
+ end
63
+
64
+ def more()
65
+ n = 3+2/7
66
+ puts "other #{n}"
67
+ n
68
+ end
69
+ """
@@ -0,0 +1,22 @@
1
+ Given /^I have the following code:$/ do |code|
2
+ @code = code
3
+ end
4
+
5
+ Given /^lines from (\d+) to (\d+) are selected$/ do |start_line, end_line|
6
+ @selected_lines = [start_line.to_i, end_line.to_i]
7
+ end
8
+
9
+ Given /^I want them to be in the method called '(.+)'$/ do |name|
10
+ @method_name = name
11
+ end
12
+
13
+ When /^I call 'extract method'$/ do
14
+ @code = Rfactor::Code.new(@code)
15
+ @new_code = @code.extract_method :name => @method_name,
16
+ :start => @selected_lines[0],
17
+ :end => @selected_lines[1]
18
+ end
19
+
20
+ Then /^the code should be:$/ do |expected|
21
+ @new_code.should == expected
22
+ end
@@ -0,0 +1,174 @@
1
+ def in_project_folder(&block)
2
+ project_folder = @active_project_folder || @tmp_root
3
+ FileUtils.chdir(project_folder, &block)
4
+ end
5
+
6
+ def in_home_folder(&block)
7
+ FileUtils.chdir(@home_path, &block)
8
+ end
9
+
10
+ Given %r{^a safe folder} do
11
+ FileUtils.rm_rf @tmp_root = File.dirname(__FILE__) + "/../../tmp"
12
+ FileUtils.mkdir_p @tmp_root
13
+ FileUtils.mkdir_p @home_path = File.expand_path(File.join(@tmp_root, "home"))
14
+ @lib_path = File.expand_path(File.dirname(__FILE__) + '/../../lib')
15
+ Given "env variable $HOME set to '#{@home_path}'"
16
+ end
17
+
18
+ Given %r{^this project is active project folder} do
19
+ Given "a safe folder"
20
+ @active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
21
+ end
22
+
23
+ Given %r{^env variable \$([\w_]+) set to '(.*)'} do |env_var, value|
24
+ ENV[env_var] = value
25
+ end
26
+
27
+ def force_local_lib_override(project_name = @project_name)
28
+ rakefile = File.read(File.join(project_name, 'Rakefile'))
29
+ File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
30
+ f << "$:.unshift('#{@lib_path}')\n"
31
+ f << rakefile
32
+ end
33
+ end
34
+
35
+ def setup_active_project_folder project_name
36
+ @active_project_folder = File.join(@tmp_root, project_name)
37
+ @project_name = project_name
38
+ end
39
+
40
+ Given %r{'(.*)' folder is deleted} do |folder|
41
+ in_project_folder do
42
+ FileUtils.rm_rf folder
43
+ end
44
+ end
45
+
46
+ When %r{^'(.*)' generator is invoked with arguments '(.*)'$} do |generator, arguments|
47
+ FileUtils.chdir(@active_project_folder) do
48
+ if Object.const_defined?("APP_ROOT")
49
+ APP_ROOT.replace(FileUtils.pwd)
50
+ else
51
+ APP_ROOT = FileUtils.pwd
52
+ end
53
+ run_generator(generator, arguments.split(' '), SOURCES)
54
+ end
55
+ end
56
+
57
+ When %r{run executable '(.*)' with arguments '(.*)'} do |executable, arguments|
58
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
59
+ FileUtils.chdir(@active_project_folder) do
60
+ system "ruby #{executable} #{arguments} > #{@stdout}"
61
+ end
62
+ end
63
+
64
+ When %r{^task 'rake (.*)' is invoked$} do |task|
65
+ @stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
66
+ FileUtils.chdir(@active_project_folder) do
67
+ system "rake #{task} --trace > #{@stdout} 2> #{@stdout}"
68
+ end
69
+ end
70
+
71
+ Then %r{^folder '(.*)' is created} do |folder|
72
+ in_project_folder do
73
+ File.exists?(folder).should be_true
74
+ end
75
+ end
76
+
77
+ Then %r{^file '(.*)' (is|is not) created} do |file, is|
78
+ in_project_folder do
79
+ File.exists?(file).should(is == 'is' ? be_true : be_false)
80
+ end
81
+ end
82
+
83
+ Then %r{^file with name matching '(.*)' is created} do |pattern|
84
+ in_project_folder do
85
+ Dir[pattern].should_not be_empty
86
+ end
87
+ end
88
+
89
+ Then %r{gem file '(.*)' and generated file '(.*)' should be the same} do |gem_file, project_file|
90
+ File.exists?(gem_file).should be_true
91
+ File.exists?(project_file).should be_true
92
+ gem_file_contents = File.read(File.dirname(__FILE__) + "/../../#{gem_file}")
93
+ project_file_contents = File.read(File.join(@active_project_folder, project_file))
94
+ project_file_contents.should == gem_file_contents
95
+ end
96
+
97
+ Then %r{^output same as contents of '(.*)'$} do |file|
98
+ expected_output = File.read(File.join(File.dirname(__FILE__) + "/../expected_outputs", file))
99
+ actual_output = File.read(File.dirname(__FILE__) + "/../../tmp/#{@stdout}")
100
+ actual_output.should == expected_output
101
+ end
102
+
103
+ Then %r{^(does|does not) invoke generator '(.*)'$} do |does_invoke, generator|
104
+ actual_output = File.read(File.dirname(__FILE__) + "/../../tmp/#{@stdout}")
105
+ does_invoke == "does" ?
106
+ actual_output.should(match(/dependency\s+#{generator}/)) :
107
+ actual_output.should_not(match(/dependency\s+#{generator}/))
108
+ end
109
+
110
+ Then %r{help options '(.*)' and '(.*)' are displayed} do |opt1, opt2|
111
+ actual_output = File.read(@stdout)
112
+ actual_output.should match(/#{opt1}/)
113
+ actual_output.should match(/#{opt2}/)
114
+ end
115
+
116
+ Then %r{^output (does|does not) match \/(.*)\/} do |does, regex|
117
+ actual_output = File.read(@stdout)
118
+ (does == 'does') ?
119
+ actual_output.should(match(/#{regex}/)) :
120
+ actual_output.should_not(match(/#{regex}/))
121
+ end
122
+
123
+ Then %r{^contents of file '(.*)' (does|does not) match \/(.*)\/} do |file, does, regex|
124
+ in_project_folder do
125
+ actual_output = File.read(file)
126
+ (does == 'does') ?
127
+ actual_output.should(match(/#{regex}/)) :
128
+ actual_output.should_not(match(/#{regex}/))
129
+ end
130
+ end
131
+
132
+ Then %r{^all (\d+) tests pass} do |expected_test_count|
133
+ expected = %r{^#{expected_test_count} tests, \d+ assertions, 0 failures, 0 errors}
134
+ actual_output = File.read(@stdout)
135
+ actual_output.should match(expected)
136
+ end
137
+
138
+ Then %r{^all (\d+) examples pass} do |expected_test_count|
139
+ expected = %r{^#{expected_test_count} examples?, 0 failures}
140
+ actual_output = File.read(@stdout)
141
+ actual_output.should match(expected)
142
+ end
143
+
144
+ Then %r{^yaml file '(.*)' contains (\{.*\})} do |file, yaml|
145
+ in_project_folder do
146
+ yaml = eval yaml
147
+ YAML.load(File.read(file)).should == yaml
148
+ end
149
+ end
150
+
151
+ Then %r{^Rakefile can display tasks successfully} do
152
+ @stdout = File.expand_path(File.join(@tmp_root, "rakefile.out"))
153
+ FileUtils.chdir(@active_project_folder) do
154
+ system "rake -T > #{@stdout} 2> #{@stdout}"
155
+ end
156
+ actual_output = File.read(@stdout)
157
+ actual_output.should match(/^rake\s+\w+\s+#\s.*/)
158
+ end
159
+
160
+ Then %r{^task 'rake (.*)' is executed successfully} do |task|
161
+ @stdout.should_not be_nil
162
+ actual_output = File.read(@stdout)
163
+ actual_output.should_not match(/^Don't know how to build task '#{task}'/)
164
+ actual_output.should_not match(/Error/i)
165
+ end
166
+
167
+ Then %r{^gem spec key '(.*)' contains \/(.*)\/} do |key, regex|
168
+ in_project_folder do
169
+ gem_file = Dir["pkg/*.gem"].first
170
+ gem_spec = Gem::Specification.from_yaml(`gem spec #{gem_file}`)
171
+ spec_value = gem_spec.send(key.to_sym)
172
+ spec_value.to_s.should match(/#{regex}/)
173
+ end
174
+ end
@@ -0,0 +1,6 @@
1
+ require File.dirname(__FILE__) + "/../../lib/rfactor"
2
+
3
+ gem 'cucumber'
4
+ require 'cucumber'
5
+ gem 'rspec'
6
+ require 'spec'
@@ -0,0 +1,51 @@
1
+ module Rfactor
2
+
3
+ class Code
4
+
5
+ def initialize(code)
6
+ @code = code
7
+ @ast = RubyParser.new.parse(code)
8
+ @line_finder = LineFinder.new(@ast)
9
+ end
10
+
11
+ def extract_method(args)
12
+ raise ":name is required" unless args.has_key?(:name)
13
+
14
+ method_lines = @line_finder.method_lines(args[:start])
15
+ selected_lines = Range.new(args[:start], args[:end])
16
+
17
+ new_code = ""
18
+ extracted_method = ""
19
+ added = false
20
+ identation = 0
21
+
22
+ @code.each_with_index do |line, n|
23
+ line_number = n + 1 # not 0-based
24
+ if line_number == method_lines.first
25
+ identation = extract_identation_level_from line
26
+ extracted_method << "\n#{identation}"
27
+ extracted_method << "def #{args[:name]}()\n"
28
+ end
29
+ if selected_lines.include? line_number
30
+ new_code << "#{identation} #{args[:name]}()\n" if line_number == selected_lines.first
31
+ extracted_method << line
32
+ elsif line_number > method_lines.last && !added
33
+ added = true
34
+ new_code << extracted_method << "#{identation}end\n"
35
+ new_code << line
36
+ else
37
+ new_code << line
38
+ end
39
+ end
40
+ new_code << "\n#{extracted_method}#{identation}end\n" unless added
41
+ new_code
42
+ end
43
+
44
+ private
45
+ def extract_identation_level_from(line)
46
+ spaces = line.match /^(\s*)def/
47
+ spaces.captures[0]
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,39 @@
1
+ module Rfactor
2
+
3
+ class LineFinder
4
+
5
+ def initialize(ast)
6
+ @ast = ast
7
+ end
8
+
9
+ def method_lines(line_in_code)
10
+ processor = MethodLineFinderProcessor.new(line_in_code)
11
+ processor.process(@ast)
12
+ Range.new(processor.method_line, processor.last_method_line)
13
+ end
14
+ end
15
+
16
+ class MethodLineFinderProcessor < ::SexpProcessor
17
+ attr_reader :method_line
18
+ attr_reader :last_method_line
19
+
20
+ def initialize(line)
21
+ super()
22
+ self.strict = false
23
+ self.require_empty = false
24
+ @line = line
25
+ @method_line = 0
26
+ @last_method_line = 0
27
+ end
28
+
29
+ def process_defn(exp)
30
+ current = exp.line
31
+ if current > @method_line && current < @line
32
+ @method_line = current
33
+ @last_method_line = exp.endline
34
+ end
35
+ exp
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,14 @@
1
+ class String
2
+
3
+ def last_line
4
+ number = 0
5
+ self.each_with_index do |line, i|
6
+ number = i
7
+ end
8
+ number + 1
9
+ end
10
+
11
+ def strip_blank_lines_at_end
12
+ self.gsub /((\s*)\n)+$/, ''
13
+ end
14
+ end
data/lib/rfactor.rb ADDED
@@ -0,0 +1,14 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Rfactor
5
+ VERSION = '0.0.1'
6
+ end
7
+
8
+ require 'rubygems'
9
+ require 'ruby_parser'
10
+ require 'sexp_processor'
11
+
12
+ require 'rfactor/string_ext'
13
+ require 'rfactor/line_finder'
14
+ require 'rfactor/code'
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/rfactor.rb'}"
9
+ puts "Loading rfactor gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
data/spec/code_spec.rb ADDED
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Rfactor::Code do
4
+ it "should require new method name on refactor" do
5
+ rfactor = Rfactor::Code.new("def a; end")
6
+ lambda { rfactor.extract_method({}) }.should raise_error(":name is required")
7
+ end
8
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ CODE = <<-END
4
+ class Bla
5
+ def my_method
6
+ puts "something"
7
+ puts "more"
8
+ 3+2
9
+ end
10
+
11
+ def my_other_method
12
+ puts "anything"
13
+ end
14
+ end
15
+ END
16
+
17
+ describe Rfactor::LineFinder do
18
+
19
+ before(:each) do
20
+ @ast = RubyParser.new.parse(CODE)
21
+ @finder = Rfactor::LineFinder.new(@ast)
22
+ end
23
+
24
+ it "should find method start line" do
25
+ @finder.method_lines(3).first.should == 2
26
+ end
27
+
28
+ it "should find method end line" do
29
+ @finder.method_lines(3).last.should == 6
30
+ end
31
+
32
+ it "it should find method end line even if the method is the last" do
33
+ @finder.method_lines(9).last.should == 10
34
+ end
35
+
36
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Rfactor do
4
+ it "should have VERSION" do
5
+ Rfactor::VERSION.should_not be_empty
6
+ end
7
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format specdoc
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'rfactor'
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe String do
4
+
5
+ it "should strip all blank lines in the end" do
6
+ text = <<-TEXT
7
+ some text
8
+ and more more more
9
+ some other
10
+
11
+ with blank lines in the middle
12
+ and in the end
13
+
14
+
15
+
16
+
17
+ TEXT
18
+
19
+ expected = " some text
20
+ and more more more
21
+ some other
22
+
23
+ with blank lines in the middle
24
+ and in the end"
25
+
26
+ text.strip_blank_lines_at_end.should == expected
27
+ end
28
+
29
+ end
data/tasks/rspec.rake ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fabiokung-rfactor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Fabio Kung
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-04 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ruby_parser
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.1
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: newgem
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 1.1.0
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: hoe
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.0
41
+ version:
42
+ description: "Common refactorings for Ruby code, written in Ruby. This project aims to be integrated with several editors (mainly TextMate), to provide simple refactorings, such as: * extract method * extract Class * extract Module * rename using ack * move using ack"
43
+ email:
44
+ - fabio.kung@gmail.com
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ extra_rdoc_files:
50
+ - History.txt
51
+ - Manifest.txt
52
+ - PostInstall.txt
53
+ - README.rdoc
54
+ files:
55
+ - History.txt
56
+ - Manifest.txt
57
+ - PostInstall.txt
58
+ - README.rdoc
59
+ - Rakefile
60
+ - features/development.feature
61
+ - features/extract_method.feature
62
+ - features/steps/code_steps.rb
63
+ - features/steps/common.rb
64
+ - features/steps/env.rb
65
+ - lib/rfactor.rb
66
+ - lib/rfactor/code.rb
67
+ - lib/rfactor/line_finder.rb
68
+ - lib/rfactor/string_ext.rb
69
+ - script/console
70
+ - script/destroy
71
+ - script/generate
72
+ - spec/code_spec.rb
73
+ - spec/line_finder_spec.rb
74
+ - spec/rfactor_spec.rb
75
+ - spec/spec.opts
76
+ - spec/spec_helper.rb
77
+ - spec/string_ext_spec.rb
78
+ - tasks/rspec.rake
79
+ has_rdoc: true
80
+ homepage: http://github.com/fabiokung/rfactor/tree/master
81
+ post_install_message: PostInstall.txt
82
+ rdoc_options:
83
+ - --main
84
+ - README.rdoc
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ version:
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ version:
99
+ requirements: []
100
+
101
+ rubyforge_project: rfactor
102
+ rubygems_version: 1.2.0
103
+ signing_key:
104
+ specification_version: 2
105
+ summary: Common refactorings for Ruby code, written in Ruby
106
+ test_files: []
107
+