rcodetools 0.5.0.0 → 0.7.0.0

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.
Files changed (61) hide show
  1. data/CHANGES +14 -0
  2. data/README +63 -0
  3. data/README.TDC +158 -0
  4. data/README.ja +84 -0
  5. data/README.vim +11 -0
  6. data/Rakefile +15 -2
  7. data/THANKS +5 -0
  8. data/bin/rct-complete +4 -2
  9. data/bin/rct-doc +4 -2
  10. data/bin/rct-meth-args +1 -1
  11. data/bin/xmpfilter +7 -1
  12. data/icicles-rcodetools.el +2 -1
  13. data/lib/rcodetools/completion.rb +36 -18
  14. data/lib/rcodetools/doc.rb +3 -0
  15. data/lib/rcodetools/fork.rb +222 -0
  16. data/lib/rcodetools/fork_config.rb +26 -0
  17. data/lib/rcodetools/options.rb +34 -1
  18. data/lib/rcodetools/xmpfilter.rb +106 -18
  19. data/lib/rcodetools/xmptestunitfilter.rb +116 -55
  20. data/lib/ruby_toggle_file.rb +99 -0
  21. data/rcodetools.el +64 -9
  22. data/rcodetools.vim +41 -6
  23. data/test/data/completion_class_info-input.rb +1 -0
  24. data/test/data/completion_class_info-output.rb +10 -0
  25. data/test/data/completion_class_info_no_candidates-input.rb +1 -0
  26. data/test/data/completion_class_info_no_candidates-output.rb +1 -0
  27. data/test/data/completion_detect_rbtest-input.rb +7 -0
  28. data/test/data/completion_detect_rbtest-output.rb +2 -0
  29. data/test/data/completion_detect_rbtest2-input.rb +1 -0
  30. data/test/data/completion_detect_rbtest2-output.rb +2 -0
  31. data/test/data/completion_in_method-input.rb +3 -0
  32. data/test/data/completion_in_method-output.rb +1 -0
  33. data/test/data/completion_in_method-test.rb +6 -0
  34. data/test/data/completion_rbtest-input.rb +7 -0
  35. data/test/data/completion_rbtest-output.rb +2 -0
  36. data/test/data/doc_detect_rbtest-input.rb +1 -0
  37. data/test/data/doc_detect_rbtest-output.rb +1 -0
  38. data/test/data/doc_detect_rbtest2-input.rb +7 -0
  39. data/test/data/doc_detect_rbtest2-output.rb +1 -0
  40. data/test/data/doc_rbtest-input.rb +7 -0
  41. data/test/data/doc_rbtest-output.rb +1 -0
  42. data/test/data/rspec-input.rb +9 -9
  43. data/test/data/rspec-output.rb +21 -21
  44. data/test/data/rspec_poetry-input.rb +9 -9
  45. data/test/data/rspec_poetry-output.rb +21 -21
  46. data/test/data/sample_test_script.rb +9 -0
  47. data/test/data/unit_test_detect_rbtest-input.rb +50 -0
  48. data/test/data/unit_test_detect_rbtest-output.rb +52 -0
  49. data/test/data/unit_test_detect_rbtest2-input.rb +6 -0
  50. data/test/data/unit_test_detect_rbtest2-output.rb +6 -0
  51. data/test/data/unit_test_rbtest-input.rb +6 -0
  52. data/test/data/unit_test_rbtest-output.rb +6 -0
  53. data/test/test_completion.rb +37 -3
  54. data/test/test_doc.rb +2 -0
  55. data/test/test_functional.rb +75 -14
  56. data/test/test_options.rb +1 -0
  57. data/test/test_ruby_toggle_file.rb +125 -0
  58. data/test/test_run.rb +7 -3
  59. data/test/test_xmpfilter.rb +132 -5
  60. data/test/test_xmptestunitfilter.rb +1 -0
  61. metadata +76 -43
@@ -3,8 +3,12 @@
3
3
  # rubikitch <rubikitch@ruby-lang.org>
4
4
  # Use and distribution subject to the terms of the Ruby license.
5
5
 
6
+ require 'rcodetools/fork_config'
7
+
8
+ module Rcodetools
9
+
6
10
  class XMPFilter
7
- VERSION = "0.5.0"
11
+ VERSION = "0.7.0"
8
12
 
9
13
  MARKER = "!XMP#{Time.new.to_i}_#{Process.pid}_#{rand(1000000)}!"
10
14
  XMP_RE = Regexp.new("^" + Regexp.escape(MARKER) + '\[([0-9]+)\] (=>|~>|==>) (.*)')
@@ -17,6 +21,22 @@ class XMPFilter
17
21
  :include_paths => [], :warnings => true,
18
22
  :use_parentheses => true}
19
23
 
24
+ def self.windows?
25
+ /win|mingw/ =~ RUBY_PLATFORM && /darwin/ !~ RUBY_PLATFORM
26
+ end
27
+
28
+ Interpreter = Struct.new(:options, :execute_method, :accept_debug, :chdir_proc)
29
+ INTERPRETER_RUBY = Interpreter.new(["-w"],
30
+ windows? ? :execute_tmpfile : :execute_popen,
31
+ true, nil)
32
+ INTERPRETER_RBTEST = Interpreter.new(["-S", "rbtest"], :execute_script, false, nil)
33
+ INTERPRETER_FORK = Interpreter.new(["-S", "rct-fork-client"], :execute_tmpfile, false,
34
+ lambda { Fork::chdir_fork_directory })
35
+
36
+ def self.detect_rbtest(code, opts)
37
+ opts[:use_rbtest] ||= (opts[:detect_rbtest] and code =~ /^=begin test./) ? true : false
38
+ end
39
+
20
40
  # The processor (overridable)
21
41
  def self.run(code, opts)
22
42
  new(opts).annotate(code)
@@ -24,6 +44,7 @@ class XMPFilter
24
44
 
25
45
  def initialize(opts = {})
26
46
  options = INITIALIZE_OPTS.merge opts
47
+ @interpreter_info = INTERPRETER_RUBY
27
48
  @interpreter = options[:interpreter]
28
49
  @options = options[:options]
29
50
  @libs = options[:libs]
@@ -34,8 +55,52 @@ class XMPFilter
34
55
  @warnings = options[:warnings]
35
56
  @parentheses = options[:use_parentheses]
36
57
  @ignore_NoMethodError = options[:ignore_NoMethodError]
37
-
58
+ test_script = options[:test_script]
59
+ test_method = options[:test_method]
60
+ filename = options[:filename]
38
61
  @postfix = ""
62
+
63
+ initialize_rct_fork if options[:detect_rct_fork]
64
+ initialize_rbtest if options[:use_rbtest]
65
+ initialize_for_test_script test_script, test_method, filename if test_script and !options[:use_rbtest]
66
+ end
67
+
68
+ def initialize_rct_fork
69
+ if Fork::run?
70
+ @interpreter_info = INTERPRETER_FORK
71
+ end
72
+ end
73
+
74
+ def initialize_rbtest
75
+ @interpreter_info = INTERPRETER_RBTEST
76
+ end
77
+
78
+ def initialize_for_test_script(test_script, test_method, filename)
79
+ test_script.replace File.expand_path(test_script)
80
+ filename.replace File.expand_path(filename)
81
+ unless test_script == filename
82
+ basedir = common_path(test_script, filename)
83
+ relative_filename = filename[basedir.length+1 .. -1].sub(%r!^lib/!, '')
84
+ @evals << %Q!$LOADED_FEATURES << #{relative_filename.dump}!
85
+ @evals << %Q!require 'test/unit'!
86
+ @evals << %Q!load #{test_script.dump}!
87
+ end
88
+ test_method = get_test_method_from_lineno(test_script, test_method.to_i) if test_method =~ /^\d/
89
+ @evals << %Q!Test::Unit::AutoRunner.run(false, nil, ["-n", #{test_method.dump}])! if test_method
90
+ end
91
+
92
+ def get_test_method_from_lineno(filename, lineno)
93
+ lines = File.readlines(filename)
94
+ (lineno-1).downto(0) do |i|
95
+ if lines[i] =~ /^ *def *(test_[A-Za-z0-9?!_]+)$/
96
+ return $1
97
+ end
98
+ end
99
+ nil
100
+ end
101
+
102
+ def common_path(a, b)
103
+ (a.split(File::Separator) & b.split(File::Separator)).join(File::Separator)
39
104
  end
40
105
 
41
106
  def add_markers(code, min_codeline_size = 50)
@@ -82,10 +147,6 @@ class XMPFilter
82
147
  v = "#{VAR}"
83
148
  blocal = "__#{VAR}"
84
149
  blocal2 = "___#{VAR}"
85
- # rubikitch: oneline-ized
86
- # <<EOF.chomp
87
- # ((#{v} = (#{expr}); $stderr.puts("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " " + #{v}.inspect) || begin; $stderr.puts local_variables; local_variables.each{|#{blocal}| #{blocal2} = eval(#{blocal}); if #{v} == #{blocal2} && #{blocal} != %#{expr}.strip; $stderr.puts("#{MARKER}[#{idx}] ==> " + #{blocal}); elsif [#{blocal2}] == #{v}; $stderr.puts("#{MARKER}[#{idx}] ==> [" + #{blocal} + "]") end }; nil rescue Exception; nil end || #{v}))
88
- # EOF
89
150
  oneline_ize(<<-EOF).chomp
90
151
  #{v} = (#{expr})
91
152
  $stderr.puts("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " " + #{v}.inspect) || begin
@@ -108,23 +169,33 @@ end || #{v}
108
169
  alias_method :prepare_line, :prepare_line_annotation
109
170
 
110
171
  def execute_tmpfile(code)
172
+ ios = %w[_ stdin stdout stderr]
111
173
  stdin, stdout, stderr = (1..3).map do |i|
112
- fname = "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb"
174
+ fname = if $DEBUG
175
+ "xmpfilter.tmpfile_#{ios[i]}.rb"
176
+ else
177
+ "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb"
178
+ end
113
179
  f = File.open(fname, "w+")
114
- at_exit { f.close unless f.closed?; File.unlink fname }
180
+ at_exit { f.close unless f.closed?; File.unlink fname unless $DEBUG}
115
181
  f
116
182
  end
117
183
  stdin.puts code
118
184
  stdin.close
119
185
  exe_line = <<-EOF.map{|l| l.strip}.join(";")
120
- $stdout.reopen('#{stdout.path}', 'w')
121
- $stderr.reopen('#{stderr.path}', 'w')
122
- $0.replace '#{stdin.path}'
186
+ $stdout.reopen('#{File.expand_path(stdout.path)}', 'w')
187
+ $stderr.reopen('#{File.expand_path(stderr.path)}', 'w')
188
+ $0.replace '#{File.expand_path(stdin.path)}'
123
189
  ARGV.replace(#{@options.inspect})
124
- load #{stdin.path.inspect}
190
+ load #{File.expand_path(stdin.path).inspect}
125
191
  #{@evals.join(";")}
126
192
  EOF
193
+ debugprint "execute command = #{(interpreter_command << "-e" << exe_line).join ' '}"
194
+
195
+ oldpwd = Dir.pwd
196
+ @interpreter_info.chdir_proc and @interpreter_info.chdir_proc.call
127
197
  system(*(interpreter_command << "-e" << exe_line))
198
+ Dir.chdir oldpwd
128
199
  [stdout, stderr]
129
200
  end
130
201
 
@@ -137,15 +208,30 @@ end || #{v}
137
208
  [stdout, stderr]
138
209
  end
139
210
 
140
- if /win|mingw/ =~ RUBY_PLATFORM && /darwin/ !~ RUBY_PLATFORM
141
- alias_method :execute, :execute_tmpfile
142
- else
143
- alias_method :execute, :execute_popen
211
+ def execute_script(code)
212
+ codefile = "xmpfilter.tmpfile_#{Process.pid}.rb"
213
+ File.open(codefile, "w"){|f| f.puts code}
214
+ path = File.expand_path(codefile)
215
+ at_exit { File.unlink path if File.exist? path}
216
+ stdout, stderr = (1..2).map do |i|
217
+ fname = "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb"
218
+ fullname = File.expand_path(fname)
219
+ at_exit { File.unlink fullname if File.exist? fullname}
220
+ File.open(fname, "w+")
221
+ end
222
+ args = *(interpreter_command << %["#{codefile}"] << "2>" <<
223
+ %["#{stderr.path}"] << ">" << %["#{stdout.path}"])
224
+ system(args.join(" "))
225
+ [stdout, stderr]
226
+ end
227
+
228
+ def execute(code)
229
+ __send__ @interpreter_info.execute_method, code
144
230
  end
145
231
 
146
232
  def interpreter_command
147
- r = [@interpreter, "-w"]
148
- r << "-d" if $DEBUG
233
+ r = [ @interpreter ] + @interpreter_info.options
234
+ r << "-d" if $DEBUG and @interpreter_info.accept_debug
149
235
  r << "-I#{@include_paths.join(":")}" unless @include_paths.empty?
150
236
  @libs.each{|x| r << "-r#{x}" } unless @libs.empty?
151
237
  (r << "-").concat @options unless @options.empty?
@@ -207,3 +293,5 @@ class XMPAddMarkers < XMPFilter
207
293
  new(opts).add_markers(code, opts[:min_codeline_size])
208
294
  end
209
295
  end
296
+
297
+ end
@@ -1,4 +1,7 @@
1
1
  require 'rcodetools/xmpfilter'
2
+
3
+ module Rcodetools
4
+
2
5
  class XMPTestUnitFilter < XMPFilter
3
6
  def initialize(opts = {})
4
7
  super
@@ -117,81 +120,139 @@ end
117
120
 
118
121
  class XMPRSpecFilter < XMPTestUnitFilter
119
122
  private
120
- def execute(code)
121
- codefile = "xmpfilter.rspec_tmpfile_#{Process.pid}.rb"
122
- File.open(codefile, "w"){|f| f.puts code}
123
- path = File.expand_path(codefile)
124
- at_exit { File.unlink path if File.exist? path}
125
- stdout, stderr = (1..2).map do |i|
126
- fname = "xmpfilter.rspec_tmpfile_#{Process.pid}-#{i}.rb"
127
- fullname = File.expand_path(fname)
128
- at_exit { File.unlink fullname if File.exist? fullname}
129
- File.open(fname, "w+")
130
- end
131
- args = *(interpreter_command << %["#{codefile}"] << "2>" <<
132
- %["#{stderr.path}"] << ">" << %["#{stdout.path}"])
133
- system(args.join(" "))
134
- [stdout, stderr]
135
- end
123
+ alias :execute :execute_script
136
124
 
137
125
  def interpreter_command
138
126
  [@interpreter] + @libs.map{|x| "-r#{x}"}
139
127
  end
140
128
 
141
- def raise_assertion(expression, exceptions, index)
142
- ["lambda{#{expression}}.should_raise #{exceptions[index][0]}"]
129
+ begin
130
+ require 'spec/version'
131
+ rescue LoadError
132
+ require 'rubygems'
133
+ begin
134
+ require 'spec/version'
135
+ rescue LoadError # if rspec isn't available, use most recent conventions
136
+ module Spec::VERSION; STRING = "1.0.0" end
137
+ end
143
138
  end
144
139
 
145
- module WithParentheses
146
- def nil_assertion(expression)
147
- ["(#{expression}).should_be_nil"]
140
+ if Spec::VERSION::STRING >= "0.8.0"
141
+
142
+ def raise_assertion(expression, exceptions, index)
143
+ ["lambda{#{expression}}.should raise_error(#{exceptions[index][0]})"]
148
144
  end
149
-
150
- def value_assertions(klass_txt, value_txt, value, expression)
151
- case value
152
- when Float
153
- ["(#{expression}).should_be_close #{value.inspect}, 0.0001"]
154
- when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass
155
- ["(#{expression}).should_equal #{value_txt}"]
156
- else
157
- object_assertions klass_txt, value_txt, expression
145
+
146
+ module WithParentheses
147
+ def nil_assertion(expression)
148
+ ["(#{expression}).should be_nil"]
158
149
  end
159
- end
160
150
 
161
- def object_assertions(klass_txt, value_txt, expression)
162
- [ "(#{expression}).should_be_a_kind_of #{klass_txt}",
163
- "(#{expression}.inspect).should_equal #{value_txt.inspect}" ]
164
- end
151
+ def value_assertions(klass_txt, value_txt, value, expression)
152
+ case value
153
+ when Float
154
+ ["(#{expression}).should be_close(#{value.inspect}, 0.0001)"]
155
+ when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass
156
+ ["(#{expression}).should == (#{value_txt})"]
157
+ else
158
+ object_assertions klass_txt, value_txt, expression
159
+ end
160
+ end
165
161
 
166
- def equal_assertion(expected, actual)
167
- "(#{actual}).should_equal #{expected}"
168
- end
169
- end
162
+ def object_assertions(klass_txt, value_txt, expression)
163
+ [ "(#{expression}).should be_a_kind_of(#{klass_txt})",
164
+ "(#{expression}.inspect).should == (#{value_txt.inspect})" ]
165
+ end
170
166
 
171
- module Poetry
172
- def nil_assertion(expression)
173
- ["#{expression}.should_be_nil"]
167
+ def equal_assertion(expected, actual)
168
+ "(#{actual}).should == (#{expected})"
169
+ end
174
170
  end
175
171
 
176
- def value_assertions(klass_txt, value_txt, value, expression)
177
- case value
178
- when Float
179
- ["#{expression}.should_be_close #{value.inspect}, 0.0001"]
180
- when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass
181
- ["#{expression}.should_equal #{value_txt}"]
182
- else
183
- object_assertions klass_txt, value_txt, expression
172
+ module Poetry
173
+ def nil_assertion(expression)
174
+ ["#{expression}.should be_nil"]
175
+ end
176
+
177
+ def value_assertions(klass_txt, value_txt, value, expression)
178
+ case value
179
+ when Float
180
+ ["#{expression}.should be_close(#{value.inspect}, 0.0001)"]
181
+ when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass
182
+ ["#{expression}.should == #{value_txt}"]
183
+ else
184
+ object_assertions klass_txt, value_txt, expression
185
+ end
186
+ end
187
+
188
+ def object_assertions(klass_txt, value_txt, expression)
189
+ [ "#{expression}.should be_a_kind_of(#{klass_txt})",
190
+ "#{expression}.inspect.should == #{value_txt.inspect}" ]
191
+ end
192
+
193
+ def equal_assertion(expected, actual)
194
+ "#{actual}.should == #{expected}"
184
195
  end
185
196
  end
197
+ else
198
+ # old rspec, use deprecated syntax
199
+ def raise_assertion(expression, exceptions, index)
200
+ ["lambda{#{expression}}.should_raise_error(#{exceptions[index][0]})"]
201
+ end
186
202
 
187
- def object_assertions(klass_txt, value_txt, expression)
188
- [ "#{expression}.should_be_a_kind_of #{klass_txt}",
189
- "#{expression}.inspect.should_equal #{value_txt.inspect}" ]
203
+ module WithParentheses
204
+ def nil_assertion(expression)
205
+ ["(#{expression}).should_be_nil"]
206
+ end
207
+
208
+ def value_assertions(klass_txt, value_txt, value, expression)
209
+ case value
210
+ when Float
211
+ ["(#{expression}).should_be_close(#{value.inspect}, 0.0001)"]
212
+ when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass
213
+ ["(#{expression}).should_equal(#{value_txt})"]
214
+ else
215
+ object_assertions klass_txt, value_txt, expression
216
+ end
217
+ end
218
+
219
+ def object_assertions(klass_txt, value_txt, expression)
220
+ [ "(#{expression}).should_be_a_kind_of(#{klass_txt})",
221
+ "(#{expression}.inspect).should_equal(#{value_txt.inspect})" ]
222
+ end
223
+
224
+ def equal_assertion(expected, actual)
225
+ "(#{actual}).should_equal(#{expected})"
226
+ end
190
227
  end
191
228
 
192
- def equal_assertion(expected, actual)
193
- "#{actual}.should_equal #{expected}"
229
+ module Poetry
230
+ def nil_assertion(expression)
231
+ ["#{expression}.should_be_nil"]
232
+ end
233
+
234
+ def value_assertions(klass_txt, value_txt, value, expression)
235
+ case value
236
+ when Float
237
+ ["#{expression}.should_be_close #{value.inspect}, 0.0001"]
238
+ when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass
239
+ ["#{expression}.should_equal #{value_txt}"]
240
+ else
241
+ object_assertions klass_txt, value_txt, expression
242
+ end
243
+ end
244
+
245
+ def object_assertions(klass_txt, value_txt, expression)
246
+ [ "#{expression}.should_be_a_kind_of #{klass_txt}",
247
+ "#{expression}.inspect.should_equal #{value_txt.inspect}" ]
248
+ end
249
+
250
+ def equal_assertion(expected, actual)
251
+ "#{actual}.should_equal #{expected}"
252
+ end
194
253
  end
195
254
  end
255
+
196
256
  end
197
257
 
258
+ end
@@ -0,0 +1,99 @@
1
+
2
+ # The name is taken from EmacsLisp
3
+ def run_hooks_with_args_until_success(regexp, *args)
4
+ private_methods(true).concat(methods(true)).grep(regexp).sort.each do |m|
5
+ _ = __send__(m, *args)
6
+ return _ if _
7
+ end
8
+ nil
9
+ end
10
+
11
+ class RubyToggleFile
12
+ def ruby_toggle_file(file)
13
+ if File.basename(file) =~ /(?:^test_|_test\.rb$)/
14
+ implementation_file(file)
15
+ else
16
+ test_file(file)
17
+ end
18
+ end
19
+
20
+ LIB_RE = %r!/lib/(.+)\.rb$!
21
+ TEST_RE = %r!/test/(.+/)?test_(.+)\.rb$!
22
+
23
+ def test_file(implementation)
24
+ if m = LIB_RE.match(implementation)
25
+ dir, node = File.split m[1]
26
+ dir = (dir == '.') ? nil : dir+"/"
27
+ else
28
+ dir = node = nil
29
+ end
30
+ run_hooks_with_args_until_success %r/^test_file_/, implementation, m&&(m.pre_match+"/"), dir, node
31
+ end
32
+
33
+ def implementation_file(test)
34
+ m = TEST_RE.match(test)
35
+ run_hooks_with_args_until_success %r/^implementation_file_/, test, m&&(m.pre_match+"/"), m&&m[1], m&&m[2]
36
+ end
37
+
38
+ private
39
+ def exist(file)
40
+ file if File.exist? file
41
+ end
42
+
43
+ RAILS_MVC2TESTNAME = { 'models' => 'unit', 'controllers' => 'functional' }
44
+ RAILS_TESTNAME2MVC = RAILS_MVC2TESTNAME.invert
45
+ def test_file_00_rails(implementation, basedir, dir, node) # rails
46
+ if m = %r!app/(models|controllers)/(.+)\.rb$!.match(implementation)
47
+ "%stest/%s/%s_test.rb" % [ m.pre_match, RAILS_MVC2TESTNAME[m[1]], m[2] ]
48
+ end
49
+ end
50
+
51
+ def test_file_05_rails_lib(implementation, basedir, dir, node)
52
+ if basedir and File.directory?( File.join(basedir, "app") )
53
+ "#{basedir}test/unit/test_#{node}.rb"
54
+ end
55
+ end
56
+
57
+ def test_file_10_no_match(implementation, basedir, dir, node)
58
+ if [basedir, dir, node].all?{|x| x.nil?}
59
+ "#{File.dirname(implementation)}/test_#{File.basename(implementation)}"
60
+ end
61
+ end
62
+
63
+ def test_file_20_simple(implementation, basedir, dir, node) # test/test_NODE.rb
64
+ exist "#{basedir}test/test_#{node}.rb"
65
+ end
66
+
67
+ def test_file_30_flat(implementation, basedir, dir, node) # lib/XXX/NODE.rb -> test/test_NODE.rb
68
+ exist "#{basedir}test/test_#{node}.rb" if dir
69
+ end
70
+
71
+ def test_file_99_autotest_default(implementation, basedir, dir, node) # lib/XXX/NODE.rb -> test/XXX/test_NODE.rb
72
+ "#{basedir}test/#{dir}test_#{node}.rb"
73
+ end
74
+
75
+ def implementation_file_00_rails(test, basedir, dir, node)
76
+ if m = %r!test/(unit|functional)/(.+)_test.rb$!.match(test)
77
+ "%sapp/%s/%s.rb" % [ m.pre_match, RAILS_TESTNAME2MVC[m[1]], m[2] ]
78
+ end
79
+ end
80
+
81
+ def implementation_file_10_no_match(test, basename, dir, node)
82
+ if dir == nil and node == nil and test =~ %r!/test_(.+)\.rb$!
83
+ test.sub("/test_", "/")
84
+ end
85
+ end
86
+
87
+ def implementation_file_20(test, basedir, dir, node)
88
+ exist("#{basedir}lib/#{dir}#{node}.rb")
89
+ end
90
+
91
+ def implementation_file_30_flat(test, basedir, dir, node)
92
+ Dir[ "#{basedir}lib/**/#{node}.rb" ].first
93
+ end
94
+
95
+ def implementation_file_99_default(test, basedir, dir, node)
96
+ "#{basedir}lib/#{dir}#{node}.rb"
97
+ end
98
+
99
+ end